Date: Thu, 23 Apr 2026 23:08:50 -0300
Subject: [PATCH 08/23] refactor: update repository references from
Fission-AI/OpenSpec to fkmatsuda/BR-OpenSpec
---
.changeset/config.json | 2 +-
.devcontainer/README.md | 2 +-
.devcontainer/devcontainer.json | 2 +-
.github/workflows/release-prepare.yml | 2 +-
LICENSE | 2 +-
README.md | 19 +++++++++----------
README.pt-BR.md | 19 +++++++++----------
README_OLD.md | 21 ++++++++++-----------
docs/installation.md | 14 +++++++-------
docs/migration-guide.md | 3 +--
docs/opsx.md | 4 +---
docs/pt-BR/installation.md | 14 +++++++-------
docs/pt-BR/migration-guide.md | 3 +--
docs/pt-BR/opsx.md | 4 +---
flake.nix | 10 +++++-----
package.json | 8 ++++----
src/commands/feedback.ts | 4 ++--
src/core/init.ts | 4 ++--
src/core/update.ts | 2 +-
test/commands/feedback.test.ts | 22 +++++++++++-----------
20 files changed, 76 insertions(+), 85 deletions(-)
diff --git a/.changeset/config.json b/.changeset/config.json
index 50cbb51321..30fa697402 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -2,7 +2,7 @@
"$schema": "https://unpkg.com/@changesets/config/schema.json",
"changelog": [
"@changesets/changelog-github",
- { "repo": "Fission-AI/OpenSpec" }
+ { "repo": "fkmatsuda/BR-OpenSpec" }
],
"commit": false,
"fixed": [],
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
index 989fa527f1..4dc7691ad1 100644
--- a/.devcontainer/README.md
+++ b/.devcontainer/README.md
@@ -1,6 +1,6 @@
# Dev Container Setup
-This directory contains the VS Code dev container configuration for OpenSpec development.
+This directory contains the VS Code dev container configuration for BR-OpenSpec development.
## What's Included
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index c381b61fa0..cd92b9c55d 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,5 +1,5 @@
{
- "name": "OpenSpec Development",
+ "name": "BR-OpenSpec Development",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm",
// Additional tools and features
diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml
index 0a58d8e87c..38949dcdb1 100644
--- a/.github/workflows/release-prepare.yml
+++ b/.github/workflows/release-prepare.yml
@@ -15,7 +15,7 @@ concurrency:
jobs:
prepare:
- if: github.repository == 'Fission-AI/OpenSpec'
+ if: github.repository == 'fkmatsuda/BR-OpenSpec'
runs-on: ubuntu-latest
steps:
# Generate GitHub App token first - used for checkout and changesets
diff --git a/LICENSE b/LICENSE
index 84c125ae7b..743476f365 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2024 OpenSpec Contributors
+Copyright (c) 2024 BR-OpenSpec Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index e70d3459fa..015c46f722 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
@@ -8,18 +8,17 @@
-
-
+
+
-
The most loved spec framework.
-[](https://github.com/Fission-AI/OpenSpec/stargazers)
-[](https://www.npmjs.com/package/@fission-ai/openspec)
-[](https://github.com/Fission-AI/OpenSpec/graphs/contributors)
+[](https://github.com/fkmatsuda/BR-OpenSpec/stargazers)
+[](https://www.npmjs.com/package/@fkmatsuda/br-openspec)
+[](https://github.com/fkmatsuda/BR-OpenSpec/graphs/contributors)
@@ -39,7 +38,7 @@ Our philosophy:
> Run `/opsx:propose "your idea"` to get started. → [Learn more here](docs/opsx.md)
- Follow @0xTab on X for updates · Join the OpenSpec Discord for help and questions.
+ Follow @0xTab on X for updates.
@@ -84,7 +83,7 @@ AI: Archived to openspec/changes/archive/2025-01-23-add-dark-mode/
Install OpenSpec globally:
```bash
-npm install -g @fission-ai/openspec@latest
+npm install -g @fkmatsuda/br-openspec@latest
```
Then navigate to your project directory and initialize:
@@ -137,7 +136,7 @@ AI coding assistants are powerful but unpredictable when requirements live only
**Upgrade the package**
```bash
-npm install -g @fission-ai/openspec@latest
+npm install -g @fkmatsuda/br-openspec@latest
```
**Refresh agent instructions**
diff --git a/README.pt-BR.md b/README.pt-BR.md
index e94678a41c..699660f1d2 100644
--- a/README.pt-BR.md
+++ b/README.pt-BR.md
@@ -1,5 +1,5 @@
-
+
@@ -8,18 +8,17 @@
-
-
+
+
-
O framework de spec mais querido.
-[](https://github.com/Fission-AI/OpenSpec/stargazers)
-[](https://www.npmjs.com/package/@fission-ai/openspec)
-[](https://github.com/Fission-AI/OpenSpec/graphs/contributors)
+[](https://github.com/fkmatsuda/BR-OpenSpec/stargazers)
+[](https://www.npmjs.com/package/@fkmatsuda/br-openspec)
+[](https://github.com/fkmatsuda/BR-OpenSpec/graphs/contributors)
@@ -39,7 +38,7 @@ Nossa filosofia:
> Execute `/opsx:propose "sua ideia"` para começar. → [Saiba mais aqui](docs/pt-BR/opsx.md)
- Siga @0xTab no X para atualizações · Entre no Discord do OpenSpec para ajuda e dúvidas.
+ Siga @0xTab no X para atualizações.
@@ -84,7 +83,7 @@ IA: Arquivado em openspec/changes/archive/2025-01-23-add-dark-mode/
Instale o OpenSpec globalmente:
```bash
-npm install -g @fission-ai/openspec@latest
+npm install -g @fkmatsuda/br-openspec@latest
```
Em seguida, navegue até o diretório do seu projeto e inicialize:
@@ -137,7 +136,7 @@ Assistentes de codificação com IA são poderosos, mas imprevisíveis quando os
**Atualize o pacote**
```bash
-npm install -g @fission-ai/openspec@latest
+npm install -g @fkmatsuda/br-openspec@latest
```
**Atualize as instruções do agente**
diff --git a/README_OLD.md b/README_OLD.md
index e0f7f39a82..17ad184936 100644
--- a/README_OLD.md
+++ b/README_OLD.md
@@ -1,5 +1,5 @@
-
+
@@ -10,12 +10,11 @@
Spec-driven development for AI coding assistants.
-
-
-
+
+
+
-
@@ -23,7 +22,7 @@
- Follow @0xTab on X for updates · Join the OpenSpec Discord for help and questions.
+ Follow @0xTab on X for updates.
@@ -143,7 +142,7 @@ These tools automatically read workflow instructions from `openspec/AGENTS.md`.
**Option A: Using npm**
```bash
-npm install -g @fission-ai/openspec@latest
+npm install -g @fkmatsuda/br-openspec@latest
```
Verify installation:
@@ -155,12 +154,12 @@ openspec --version
Run OpenSpec directly without installation:
```bash
-nix run github:Fission-AI/OpenSpec -- init
+nix run github:fkmatsuda/BR-OpenSpec -- init
```
Or install to your profile:
```bash
-nix profile install github:Fission-AI/OpenSpec
+nix profile install github:fkmatsuda/BR-OpenSpec
```
Or add to your development environment in `flake.nix`:
@@ -168,7 +167,7 @@ Or add to your development environment in `flake.nix`:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
- openspec.url = "github:Fission-AI/OpenSpec";
+ openspec.url = "github:fkmatsuda/BR-OpenSpec";
};
outputs = { nixpkgs, openspec, ... }: {
@@ -403,7 +402,7 @@ Run `openspec update` whenever someone switches tools so your agents pick up the
1. **Upgrade the package**
```bash
- npm install -g @fission-ai/openspec@latest
+ npm install -g @fkmatsuda/br-openspec@latest
```
2. **Refresh agent instructions**
- Run `openspec update` inside each project to regenerate AI guidance and ensure the latest slash commands are active.
diff --git a/docs/installation.md b/docs/installation.md
index 78910513c9..e15820305c 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -9,25 +9,25 @@
### npm
```bash
-npm install -g @fission-ai/openspec@latest
+npm install -g @fkmatsuda/br-openspec@latest
```
### pnpm
```bash
-pnpm add -g @fission-ai/openspec@latest
+pnpm add -g @fkmatsuda/br-openspec@latest
```
### yarn
```bash
-yarn global add @fission-ai/openspec@latest
+yarn global add @fkmatsuda/br-openspec@latest
```
### bun
```bash
-bun add -g @fission-ai/openspec@latest
+bun add -g @fkmatsuda/br-openspec@latest
```
## Nix
@@ -35,13 +35,13 @@ bun add -g @fission-ai/openspec@latest
Run OpenSpec directly without installation:
```bash
-nix run github:Fission-AI/OpenSpec -- init
+nix run github:fkmatsuda/BR-OpenSpec -- init
```
Or install to your profile:
```bash
-nix profile install github:Fission-AI/OpenSpec
+nix profile install github:fkmatsuda/BR-OpenSpec
```
Or add to your development environment in `flake.nix`:
@@ -50,7 +50,7 @@ Or add to your development environment in `flake.nix`:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
- openspec.url = "github:Fission-AI/OpenSpec";
+ openspec.url = "github:fkmatsuda/BR-OpenSpec";
};
outputs = { nixpkgs, openspec, ... }: {
diff --git a/docs/migration-guide.md b/docs/migration-guide.md
index 5091ce4380..e29ae2f44f 100644
--- a/docs/migration-guide.md
+++ b/docs/migration-guide.md
@@ -590,6 +590,5 @@ project/
## Getting Help
-- **Discord**: [discord.gg/YctCnvvshC](https://discord.gg/YctCnvvshC)
-- **GitHub Issues**: [github.com/Fission-AI/OpenSpec/issues](https://github.com/Fission-AI/OpenSpec/issues)
+- **GitHub Issues**: [github.com/fkmatsuda/BR-OpenSpec/issues](https://github.com/fkmatsuda/BR-OpenSpec/issues)
- **Documentation**: [docs/opsx.md](opsx.md) for the full OPSX reference
diff --git a/docs/opsx.md b/docs/opsx.md
index 9607b7d06d..5456e3bfa5 100644
--- a/docs/opsx.md
+++ b/docs/opsx.md
@@ -1,7 +1,5 @@
# OPSX Workflow
-> Feedback welcome on [Discord](https://discord.gg/YctCnvvshC).
-
## What Is It?
OPSX is now the standard workflow for OpenSpec.
@@ -656,4 +654,4 @@ openspec schema validate my-workflow
This is rough. That's intentional — we're learning what works.
-Found a bug? Have ideas? Join us on [Discord](https://discord.gg/YctCnvvshC) or open an issue on [GitHub](https://github.com/Fission-AI/openspec/issues).
+Found a bug? Have ideas? Open an issue on [GitHub](https://github.com/fkmatsuda/BR-OpenSpec/issues).
diff --git a/docs/pt-BR/installation.md b/docs/pt-BR/installation.md
index 17860f3013..1a0c71f2cf 100644
--- a/docs/pt-BR/installation.md
+++ b/docs/pt-BR/installation.md
@@ -9,25 +9,25 @@
### npm
```bash
-npm install -g @fission-ai/openspec@latest
+npm install -g @fkmatsuda/br-openspec@latest
```
### pnpm
```bash
-pnpm add -g @fission-ai/openspec@latest
+pnpm add -g @fkmatsuda/br-openspec@latest
```
### yarn
```bash
-yarn global add @fission-ai/openspec@latest
+yarn global add @fkmatsuda/br-openspec@latest
```
### bun
```bash
-bun add -g @fission-ai/openspec@latest
+bun add -g @fkmatsuda/br-openspec@latest
```
## Nix
@@ -35,13 +35,13 @@ bun add -g @fission-ai/openspec@latest
Execute o OpenSpec diretamente sem instalação:
```bash
-nix run github:Fission-AI/OpenSpec -- init
+nix run github:fkmatsuda/BR-OpenSpec -- init
```
Ou instale no seu perfil:
```bash
-nix profile install github:Fission-AI/OpenSpec
+nix profile install github:fkmatsuda/BR-OpenSpec
```
Ou adicione ao seu ambiente de desenvolvimento em `flake.nix`:
@@ -50,7 +50,7 @@ Ou adicione ao seu ambiente de desenvolvimento em `flake.nix`:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
- openspec.url = "github:Fission-AI/OpenSpec";
+ openspec.url = "github:fkmatsuda/BR-OpenSpec";
};
outputs = { nixpkgs, openspec, ... }: {
diff --git a/docs/pt-BR/migration-guide.md b/docs/pt-BR/migration-guide.md
index 8f836893be..73bba749d7 100644
--- a/docs/pt-BR/migration-guide.md
+++ b/docs/pt-BR/migration-guide.md
@@ -590,6 +590,5 @@ project/
## Obtendo Ajuda
-- **Discord**: [discord.gg/YctCnvvshC](https://discord.gg/YctCnvvshC)
-- **GitHub Issues**: [github.com/Fission-AI/OpenSpec/issues](https://github.com/Fission-AI/OpenSpec/issues)
+- **GitHub Issues**: [github.com/fkmatsuda/BR-OpenSpec/issues](https://github.com/fkmatsuda/BR-OpenSpec/issues)
- **Documentação**: [docs/opsx.md](opsx.md) para a referência completa do OPSX
diff --git a/docs/pt-BR/opsx.md b/docs/pt-BR/opsx.md
index 661a95c08b..6b41905255 100644
--- a/docs/pt-BR/opsx.md
+++ b/docs/pt-BR/opsx.md
@@ -1,7 +1,5 @@
# Fluxo de Trabalho OPSX
-> Feedback é bem-vindo no [Discord](https://discord.gg/YctCnvvshC).
-
## O Que É?
O OPSX é agora o fluxo de trabalho padrão do OpenSpec.
@@ -656,4 +654,4 @@ openspec schema validate my-workflow
Isso ainda está em desenvolvimento. Isso é intencional — estamos aprendendo o que funciona.
-Encontrou um bug? Tem ideias? Junte-se a nós no [Discord](https://discord.gg/YctCnvvshC) ou abra uma issue no [GitHub](https://github.com/Fission-AI/openspec/issues).
+Encontrou um bug? Tem ideias? Abra uma issue no [GitHub](https://github.com/fkmatsuda/BR-OpenSpec/issues).
diff --git a/flake.nix b/flake.nix
index 90ba68aef9..95f10d779b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,5 +1,5 @@
{
- description = "OpenSpec - AI-native system for spec-driven development";
+ description = "BR-OpenSpec - AI-native system for spec-driven development";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
@@ -51,7 +51,7 @@
inherit (finalAttrs) pname version src;
pnpm = pkgs.pnpm_9;
fetcherVersion = 3;
- hash = "sha256-9s2kdvd7svK4hofnD66HkDc86WTQeayfF5y7L2dmjNg=";
+ hash = "sha256-JMQMQBriv89MLw+SE5qfO/oNjJEI44g/Y9dpyRz1hro=";
};
nativeBuildInputs = with pkgs; [
@@ -72,8 +72,8 @@
dontNpmPrune = true;
meta = with pkgs.lib; {
- description = "AI-native system for spec-driven development";
- homepage = "https://github.com/Fission-AI/OpenSpec";
+ description = "BR-OpenSpec - AI-native system for spec-driven development";
+ homepage = "https://github.com/fkmatsuda/BR-OpenSpec";
license = licenses.mit;
maintainers = [ ];
mainProgram = "openspec";
@@ -102,7 +102,7 @@
];
shellHook = ''
- echo "OpenSpec development environment"
+ echo "BR-OpenSpec development environment"
echo "Node version: $(node --version)"
echo "pnpm version: $(pnpm --version)"
echo "Run 'pnpm install' to install dependencies"
diff --git a/package.json b/package.json
index 886099f8e2..bd40fe9c98 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "@fission-ai/openspec",
+ "name": "@fkmatsuda/br-openspec",
"version": "1.3.1",
"description": "AI-native system for spec-driven development",
"keywords": [
@@ -9,13 +9,13 @@
"ai",
"development"
],
- "homepage": "https://github.com/Fission-AI/OpenSpec",
+ "homepage": "https://github.com/fkmatsuda/BR-OpenSpec",
"repository": {
"type": "git",
- "url": "https://github.com/Fission-AI/OpenSpec"
+ "url": "https://github.com/fkmatsuda/BR-OpenSpec"
},
"license": "MIT",
- "author": "OpenSpec Contributors",
+ "author": "BR-OpenSpec Contributors",
"type": "module",
"publishConfig": {
"access": "public"
diff --git a/src/commands/feedback.ts b/src/commands/feedback.ts
index e157d11e18..2dd5a00db7 100644
--- a/src/commands/feedback.ts
+++ b/src/commands/feedback.ts
@@ -98,7 +98,7 @@ function formatBody(bodyText?: string): string {
* Generate a pre-filled GitHub issue URL for manual submission
*/
function generateManualSubmissionUrl(title: string, body: string): string {
- const repo = 'Fission-AI/OpenSpec';
+ const repo = 'fkmatsuda/BR-OpenSpec';
const encodedTitle = encodeURIComponent(title);
const encodedBody = encodeURIComponent(body);
const encodedLabels = encodeURIComponent('feedback');
@@ -130,7 +130,7 @@ function submitViaGhCli(title: string, body: string): void {
'issue',
'create',
'--repo',
- 'Fission-AI/OpenSpec',
+ 'fkmatsuda/BR-OpenSpec',
'--title',
title,
'--body',
diff --git a/src/core/init.ts b/src/core/init.ts
index d9bd0753a1..1e177c2b6b 100644
--- a/src/core/init.ts
+++ b/src/core/init.ts
@@ -704,8 +704,8 @@ export class InitCommand {
// Links
console.log();
- console.log(`Learn more: ${chalk.cyan('https://github.com/Fission-AI/OpenSpec')}`);
- console.log(`Feedback: ${chalk.cyan('https://github.com/Fission-AI/OpenSpec/issues')}`);
+ console.log(`Learn more: ${chalk.cyan('https://github.com/fkmatsuda/BR-OpenSpec')}`);
+ console.log(`Feedback: ${chalk.cyan('https://github.com/fkmatsuda/BR-OpenSpec/issues')}`);
// Restart instruction if any tools were configured
if (results.createdTools.length > 0 || results.refreshedTools.length > 0) {
diff --git a/src/core/update.ts b/src/core/update.ts
index de922a5ffe..a24f6cb113 100644
--- a/src/core/update.ts
+++ b/src/core/update.ts
@@ -272,7 +272,7 @@ export class UpdateCommand {
console.log(' /opsx:continue Create the next artifact');
console.log(' /opsx:apply Implement tasks');
console.log();
- console.log(`Learn more: ${chalk.cyan('https://github.com/Fission-AI/OpenSpec')}`);
+ console.log(`Learn more: ${chalk.cyan('https://github.com/fkmatsuda/BR-OpenSpec')}`);
}
const configuredAndNewTools = [...new Set([...configuredTools, ...newlyConfiguredTools])];
diff --git a/test/commands/feedback.test.ts b/test/commands/feedback.test.ts
index 7a2125f16f..16949f9699 100644
--- a/test/commands/feedback.test.ts
+++ b/test/commands/feedback.test.ts
@@ -46,7 +46,7 @@ describe('FeedbackCommand', () => {
return '';
});
- mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/123\n');
+ mockExecFileSync.mockReturnValue('https://github.com/fkmatsuda/BR-OpenSpec/issues/123\n');
await feedbackCommand.execute('Test');
@@ -72,7 +72,7 @@ describe('FeedbackCommand', () => {
return '';
});
- mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/123\n');
+ mockExecFileSync.mockReturnValue('https://github.com/fkmatsuda/BR-OpenSpec/issues/123\n');
await feedbackCommand.execute('Test');
@@ -110,7 +110,7 @@ describe('FeedbackCommand', () => {
// Should show manual submission URL
expect(consoleLogSpy).toHaveBeenCalledWith(
- expect.stringContaining('https://github.com/Fission-AI/OpenSpec/issues/new')
+ expect.stringContaining('https://github.com/fkmatsuda/BR-OpenSpec/issues/new')
);
});
@@ -151,7 +151,7 @@ describe('FeedbackCommand', () => {
describe('successful feedback submission', () => {
it('should submit feedback via gh CLI when authenticated', async () => {
- const issueUrl = 'https://github.com/Fission-AI/OpenSpec/issues/123';
+ const issueUrl = 'https://github.com/fkmatsuda/BR-OpenSpec/issues/123';
// Simulate gh installed and authenticated
mockExecSync.mockImplementation((cmd: string, options?: any) => {
@@ -175,7 +175,7 @@ describe('FeedbackCommand', () => {
'issue',
'create',
'--repo',
- 'Fission-AI/OpenSpec',
+ 'fkmatsuda/BR-OpenSpec',
'--title',
'Feedback: Great tool!',
'--body',
@@ -201,7 +201,7 @@ describe('FeedbackCommand', () => {
});
it('should include --body flag when body is provided', async () => {
- const issueUrl = 'https://github.com/Fission-AI/OpenSpec/issues/124';
+ const issueUrl = 'https://github.com/fkmatsuda/BR-OpenSpec/issues/124';
mockExecSync.mockImplementation((cmd: string, options?: any) => {
if (cmd === 'which gh' || cmd === 'where gh') {
@@ -239,7 +239,7 @@ describe('FeedbackCommand', () => {
return '';
});
- mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/125\n');
+ mockExecFileSync.mockReturnValue('https://github.com/fkmatsuda/BR-OpenSpec/issues/125\n');
await feedbackCommand.execute('Test message');
@@ -265,7 +265,7 @@ describe('FeedbackCommand', () => {
return '';
});
- mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/126\n');
+ mockExecFileSync.mockReturnValue('https://github.com/fkmatsuda/BR-OpenSpec/issues/126\n');
await feedbackCommand.execute('Test', { body: 'Body text' });
@@ -291,7 +291,7 @@ describe('FeedbackCommand', () => {
return '';
});
- mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/127\n');
+ mockExecFileSync.mockReturnValue('https://github.com/fkmatsuda/BR-OpenSpec/issues/127\n');
await feedbackCommand.execute('Test');
@@ -351,7 +351,7 @@ describe('FeedbackCommand', () => {
return '';
});
- mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/128\n');
+ mockExecFileSync.mockReturnValue('https://github.com/fkmatsuda/BR-OpenSpec/issues/128\n');
await feedbackCommand.execute('Test with "quotes"', {
body: 'Body with "quotes"',
@@ -415,7 +415,7 @@ describe('FeedbackCommand', () => {
// Verify URL is shown
const urlCall = consoleLogSpy.mock.calls.find((call: any[]) =>
- call[0]?.includes('https://github.com/Fission-AI/OpenSpec/issues/new')
+ call[0]?.includes('https://github.com/fkmatsuda/BR-OpenSpec/issues/new')
);
expect(urlCall).toBeDefined();
From 4afb929c35e328003ef11b431431aedfff3090ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A1bio=20Kenji=20Matsuda?=
Date: Thu, 23 Apr 2026 23:09:42 -0300
Subject: [PATCH 09/23] fix: update package name in version check script
---
.github/CODEOWNERS | 2 +-
MAINTAINERS.md | 12 +-
docs/cli.md | 4 +-
docs/pt-BR/cli.md | 4 +-
package-lock.json | 5601 --------------------------------
scripts/pack-version-check.mjs | 2 +-
6 files changed, 8 insertions(+), 5617 deletions(-)
delete mode 100644 package-lock.json
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index e066888eaf..ce2ceea4d4 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,2 +1,2 @@
# Default code ownership
-* @TabishB
+* @fkmatsuda
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index d27e1ef466..deeac5fbe4 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -1,17 +1,9 @@
# Maintainers
-People who maintain and guide OpenSpec.
+People who maintain and guide BR-OpenSpec.
## Core Maintainers
| Name | GitHub | Role |
|------|--------|------|
-| Tabish Bidiwale | [@TabishB](https://github.com/TabishB) | Lead maintainer |
-
-## Advisors
-
-Advisors help shape technical direction and provide guidance to the project.
-
-| Name | GitHub | Focus |
-|------|--------|-------|
-| Hari Krishnan | [@harikrishnan83](https://github.com/harikrishnan83) | Technical direction |
+| fkmatsuda | [@fkmatsuda](https://github.com/fkmatsuda) | Lead maintainer |
diff --git a/docs/cli.md b/docs/cli.md
index 5bbe6e0184..fd098014cf 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -153,7 +153,7 @@ openspec update [path] [options]
```bash
# Update instruction files after npm upgrade
-npm update @fission-ai/openspec
+npm update @fkmatsuda/br-openspec
openspec update
```
@@ -743,7 +743,7 @@ openspec schema which spec-driven
```
spec-driven resolves from: package
- Source: /usr/local/lib/node_modules/@fission-ai/openspec/schemas/spec-driven
+ Source: /usr/local/lib/node_modules/@fkmatsuda/br-openspec/schemas/spec-driven
```
**Schema precedence:**
diff --git a/docs/pt-BR/cli.md b/docs/pt-BR/cli.md
index 8ce64d6b14..9aabefdee8 100644
--- a/docs/pt-BR/cli.md
+++ b/docs/pt-BR/cli.md
@@ -153,7 +153,7 @@ openspec update [path] [options]
```bash
# Atualizar arquivos de instrução após atualização via npm
-npm update @fission-ai/openspec
+npm update @fkmatsuda/br-openspec
openspec update
```
@@ -743,7 +743,7 @@ openspec schema which spec-driven
```
spec-driven resolves from: package
- Source: /usr/local/lib/node_modules/@fission-ai/openspec/schemas/spec-driven
+ Source: /usr/local/lib/node_modules/@fkmatsuda/br-openspec/schemas/spec-driven
```
**Precedência de schemas:**
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index bd3cee9003..0000000000
--- a/package-lock.json
+++ /dev/null
@@ -1,5601 +0,0 @@
-{
- "name": "@fission-ai/openspec",
- "version": "1.3.1",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "@fission-ai/openspec",
- "version": "1.3.1",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.2.2",
- "@inquirer/prompts": "^7.8.0",
- "chalk": "^5.5.0",
- "commander": "^14.0.0",
- "fast-glob": "^3.3.3",
- "ora": "^8.2.0",
- "posthog-node": "^5.20.0",
- "yaml": "^2.8.2",
- "zod": "^4.0.17"
- },
- "bin": {
- "openspec": "bin/openspec.js"
- },
- "devDependencies": {
- "@changesets/changelog-github": "^0.5.2",
- "@changesets/cli": "^2.27.7",
- "@types/node": "^24.2.0",
- "@vitest/coverage-v8": "3.2.4",
- "@vitest/ui": "^3.2.4",
- "eslint": "^9.39.2",
- "typescript": "^5.9.3",
- "typescript-eslint": "^8.50.1",
- "vitest": "^3.2.4"
- },
- "engines": {
- "node": ">=20.19.0"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.2",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz",
- "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
- "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@bcoe/v8-coverage": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
- "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@changesets/apply-release-plan": {
- "version": "7.0.14",
- "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.14.tgz",
- "integrity": "sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/config": "^3.1.2",
- "@changesets/get-version-range-type": "^0.4.0",
- "@changesets/git": "^3.0.4",
- "@changesets/should-skip-package": "^0.1.2",
- "@changesets/types": "^6.1.0",
- "@manypkg/get-packages": "^1.1.3",
- "detect-indent": "^6.0.0",
- "fs-extra": "^7.0.1",
- "lodash.startcase": "^4.4.0",
- "outdent": "^0.5.0",
- "prettier": "^2.7.1",
- "resolve-from": "^5.0.0",
- "semver": "^7.5.3"
- }
- },
- "node_modules/@changesets/assemble-release-plan": {
- "version": "6.0.9",
- "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.9.tgz",
- "integrity": "sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/errors": "^0.2.0",
- "@changesets/get-dependents-graph": "^2.1.3",
- "@changesets/should-skip-package": "^0.1.2",
- "@changesets/types": "^6.1.0",
- "@manypkg/get-packages": "^1.1.3",
- "semver": "^7.5.3"
- }
- },
- "node_modules/@changesets/changelog-git": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz",
- "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/types": "^6.1.0"
- }
- },
- "node_modules/@changesets/changelog-github": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.2.tgz",
- "integrity": "sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/get-github-info": "^0.7.0",
- "@changesets/types": "^6.1.0",
- "dotenv": "^8.1.0"
- }
- },
- "node_modules/@changesets/cli": {
- "version": "2.29.8",
- "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.29.8.tgz",
- "integrity": "sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/apply-release-plan": "^7.0.14",
- "@changesets/assemble-release-plan": "^6.0.9",
- "@changesets/changelog-git": "^0.2.1",
- "@changesets/config": "^3.1.2",
- "@changesets/errors": "^0.2.0",
- "@changesets/get-dependents-graph": "^2.1.3",
- "@changesets/get-release-plan": "^4.0.14",
- "@changesets/git": "^3.0.4",
- "@changesets/logger": "^0.1.1",
- "@changesets/pre": "^2.0.2",
- "@changesets/read": "^0.6.6",
- "@changesets/should-skip-package": "^0.1.2",
- "@changesets/types": "^6.1.0",
- "@changesets/write": "^0.4.0",
- "@inquirer/external-editor": "^1.0.2",
- "@manypkg/get-packages": "^1.1.3",
- "ansi-colors": "^4.1.3",
- "ci-info": "^3.7.0",
- "enquirer": "^2.4.1",
- "fs-extra": "^7.0.1",
- "mri": "^1.2.0",
- "p-limit": "^2.2.0",
- "package-manager-detector": "^0.2.0",
- "picocolors": "^1.1.0",
- "resolve-from": "^5.0.0",
- "semver": "^7.5.3",
- "spawndamnit": "^3.0.1",
- "term-size": "^2.1.0"
- },
- "bin": {
- "changeset": "bin.js"
- }
- },
- "node_modules/@changesets/config": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.2.tgz",
- "integrity": "sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/errors": "^0.2.0",
- "@changesets/get-dependents-graph": "^2.1.3",
- "@changesets/logger": "^0.1.1",
- "@changesets/types": "^6.1.0",
- "@manypkg/get-packages": "^1.1.3",
- "fs-extra": "^7.0.1",
- "micromatch": "^4.0.8"
- }
- },
- "node_modules/@changesets/errors": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz",
- "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "extendable-error": "^0.1.5"
- }
- },
- "node_modules/@changesets/get-dependents-graph": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.3.tgz",
- "integrity": "sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/types": "^6.1.0",
- "@manypkg/get-packages": "^1.1.3",
- "picocolors": "^1.1.0",
- "semver": "^7.5.3"
- }
- },
- "node_modules/@changesets/get-github-info": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.7.0.tgz",
- "integrity": "sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "dataloader": "^1.4.0",
- "node-fetch": "^2.5.0"
- }
- },
- "node_modules/@changesets/get-release-plan": {
- "version": "4.0.14",
- "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.14.tgz",
- "integrity": "sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/assemble-release-plan": "^6.0.9",
- "@changesets/config": "^3.1.2",
- "@changesets/pre": "^2.0.2",
- "@changesets/read": "^0.6.6",
- "@changesets/types": "^6.1.0",
- "@manypkg/get-packages": "^1.1.3"
- }
- },
- "node_modules/@changesets/get-version-range-type": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz",
- "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@changesets/git": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz",
- "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/errors": "^0.2.0",
- "@manypkg/get-packages": "^1.1.3",
- "is-subdir": "^1.1.1",
- "micromatch": "^4.0.8",
- "spawndamnit": "^3.0.1"
- }
- },
- "node_modules/@changesets/logger": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz",
- "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picocolors": "^1.1.0"
- }
- },
- "node_modules/@changesets/parse": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.2.tgz",
- "integrity": "sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/types": "^6.1.0",
- "js-yaml": "^4.1.1"
- }
- },
- "node_modules/@changesets/pre": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz",
- "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/errors": "^0.2.0",
- "@changesets/types": "^6.1.0",
- "@manypkg/get-packages": "^1.1.3",
- "fs-extra": "^7.0.1"
- }
- },
- "node_modules/@changesets/read": {
- "version": "0.6.6",
- "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.6.tgz",
- "integrity": "sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/git": "^3.0.4",
- "@changesets/logger": "^0.1.1",
- "@changesets/parse": "^0.4.2",
- "@changesets/types": "^6.1.0",
- "fs-extra": "^7.0.1",
- "p-filter": "^2.1.0",
- "picocolors": "^1.1.0"
- }
- },
- "node_modules/@changesets/should-skip-package": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz",
- "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/types": "^6.1.0",
- "@manypkg/get-packages": "^1.1.3"
- }
- },
- "node_modules/@changesets/types": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz",
- "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@changesets/write": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz",
- "integrity": "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@changesets/types": "^6.1.0",
- "fs-extra": "^7.0.1",
- "human-id": "^4.1.1",
- "prettier": "^2.7.1"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
- "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
- "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
- "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
- "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
- "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
- "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
- "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
- "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
- "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
- "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
- "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
- "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
- "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
- "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
- "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
- "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
- "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
- "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
- "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
- "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
- "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
- "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
- "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
- "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
- "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
- "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
- "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/config-array": {
- "version": "0.21.1",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
- "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/object-schema": "^2.1.7",
- "debug": "^4.3.1",
- "minimatch": "^3.1.2"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/config-helpers": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
- "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/core": {
- "version": "0.17.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
- "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
- "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.1",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/js": {
- "version": "9.39.3",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz",
- "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- }
- },
- "node_modules/@eslint/object-schema": {
- "version": "2.1.7",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
- "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/plugin-kit": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
- "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0",
- "levn": "^0.4.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@humanfs/core": {
- "version": "0.19.1",
- "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
- "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanfs/node": {
- "version": "0.16.7",
- "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
- "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanfs/core": "^0.19.1",
- "@humanwhocodes/retry": "^0.4.0"
- },
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/retry": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
- "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@inquirer/ansi": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz",
- "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@inquirer/checkbox": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz",
- "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/ansi": "^1.0.2",
- "@inquirer/core": "^10.3.2",
- "@inquirer/figures": "^1.0.15",
- "@inquirer/type": "^3.0.10",
- "yoctocolors-cjs": "^2.1.3"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/confirm": {
- "version": "5.1.21",
- "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz",
- "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.3.2",
- "@inquirer/type": "^3.0.10"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/core": {
- "version": "10.3.2",
- "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz",
- "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/ansi": "^1.0.2",
- "@inquirer/figures": "^1.0.15",
- "@inquirer/type": "^3.0.10",
- "cli-width": "^4.1.0",
- "mute-stream": "^2.0.0",
- "signal-exit": "^4.1.0",
- "wrap-ansi": "^6.2.0",
- "yoctocolors-cjs": "^2.1.3"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/editor": {
- "version": "4.2.23",
- "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz",
- "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.3.2",
- "@inquirer/external-editor": "^1.0.3",
- "@inquirer/type": "^3.0.10"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/expand": {
- "version": "4.0.23",
- "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz",
- "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.3.2",
- "@inquirer/type": "^3.0.10",
- "yoctocolors-cjs": "^2.1.3"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/external-editor": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz",
- "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==",
- "license": "MIT",
- "dependencies": {
- "chardet": "^2.1.1",
- "iconv-lite": "^0.7.0"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/figures": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz",
- "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@inquirer/input": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz",
- "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.3.2",
- "@inquirer/type": "^3.0.10"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/number": {
- "version": "3.0.23",
- "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz",
- "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.3.2",
- "@inquirer/type": "^3.0.10"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/password": {
- "version": "4.0.23",
- "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz",
- "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/ansi": "^1.0.2",
- "@inquirer/core": "^10.3.2",
- "@inquirer/type": "^3.0.10"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/prompts": {
- "version": "7.10.1",
- "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz",
- "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/checkbox": "^4.3.2",
- "@inquirer/confirm": "^5.1.21",
- "@inquirer/editor": "^4.2.23",
- "@inquirer/expand": "^4.0.23",
- "@inquirer/input": "^4.3.1",
- "@inquirer/number": "^3.0.23",
- "@inquirer/password": "^4.0.23",
- "@inquirer/rawlist": "^4.1.11",
- "@inquirer/search": "^3.2.2",
- "@inquirer/select": "^4.4.2"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/rawlist": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz",
- "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.3.2",
- "@inquirer/type": "^3.0.10",
- "yoctocolors-cjs": "^2.1.3"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/search": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz",
- "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.3.2",
- "@inquirer/figures": "^1.0.15",
- "@inquirer/type": "^3.0.10",
- "yoctocolors-cjs": "^2.1.3"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/select": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz",
- "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==",
- "license": "MIT",
- "dependencies": {
- "@inquirer/ansi": "^1.0.2",
- "@inquirer/core": "^10.3.2",
- "@inquirer/figures": "^1.0.15",
- "@inquirer/type": "^3.0.10",
- "yoctocolors-cjs": "^2.1.3"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@inquirer/type": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz",
- "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/@isaacs/cliui": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
- "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^5.1.2",
- "string-width-cjs": "npm:string-width@^4.2.0",
- "strip-ansi": "^7.0.1",
- "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
- "wrap-ansi": "^8.1.0",
- "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
- "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
- "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@isaacs/cliui/node_modules/string-width": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
- "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
- "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.2.2"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
- "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.1.0",
- "string-width": "^5.0.1",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/@istanbuljs/schema": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz",
- "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@manypkg/find-root": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz",
- "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.5.5",
- "@types/node": "^12.7.1",
- "find-up": "^4.1.0",
- "fs-extra": "^8.1.0"
- }
- },
- "node_modules/@manypkg/find-root/node_modules/@types/node": {
- "version": "12.20.55",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
- "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@manypkg/find-root/node_modules/fs-extra": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
- "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
- "node_modules/@manypkg/get-packages": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz",
- "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.5.5",
- "@changesets/types": "^4.0.1",
- "@manypkg/find-root": "^1.1.0",
- "fs-extra": "^8.1.0",
- "globby": "^11.0.0",
- "read-yaml-file": "^1.1.0"
- }
- },
- "node_modules/@manypkg/get-packages/node_modules/@changesets/types": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz",
- "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@manypkg/get-packages/node_modules/fs-extra": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
- "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
- "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@polka/url": {
- "version": "1.0.0-next.29",
- "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
- "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@posthog/core": {
- "version": "1.23.1",
- "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.1.tgz",
- "integrity": "sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ==",
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.6"
- }
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.58.0.tgz",
- "integrity": "sha512-mr0tmS/4FoVk1cnaeN244A/wjvGDNItZKR8hRhnmCzygyRXYtKF5jVDSIILR1U97CTzAYmbgIj/Dukg62ggG5w==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.58.0.tgz",
- "integrity": "sha512-+s++dbp+/RTte62mQD9wLSbiMTV+xr/PeRJEc/sFZFSBRlHPNPVaf5FXlzAL77Mr8FtSfQqCN+I598M8U41ccQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.58.0.tgz",
- "integrity": "sha512-MFWBwTcYs0jZbINQBXHfSrpSQJq3IUOakcKPzfeSznONop14Pxuqa0Kg19GD0rNBMPQI2tFtu3UzapZpH0Uc1Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.58.0.tgz",
- "integrity": "sha512-yiKJY7pj9c9JwzuKYLFaDZw5gma3fI9bkPEIyofvVfsPqjCWPglSHdpdwXpKGvDeYDms3Qal8qGMEHZ1M/4Udg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.58.0.tgz",
- "integrity": "sha512-x97kCoBh5MOevpn/CNK9W1x8BEzO238541BGWBc315uOlN0AD/ifZ1msg+ZQB05Ux+VF6EcYqpiagfLJ8U3LvQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.58.0.tgz",
- "integrity": "sha512-Aa8jPoZ6IQAG2eIrcXPpjRcMjROMFxCt1UYPZZtCxRV68WkuSigYtQ/7Zwrcr2IvtNJo7T2JfDXyMLxq5L4Jlg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.58.0.tgz",
- "integrity": "sha512-Ob8YgT5kD/lSIYW2Rcngs5kNB/44Q2RzBSPz9brf2WEtcGR7/f/E9HeHn1wYaAwKBni+bdXEwgHvUd0x12lQSA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.58.0.tgz",
- "integrity": "sha512-K+RI5oP1ceqoadvNt1FecL17Qtw/n9BgRSzxif3rTL2QlIu88ccvY+Y9nnHe/cmT5zbH9+bpiJuG1mGHRVwF4Q==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.58.0.tgz",
- "integrity": "sha512-T+17JAsCKUjmbopcKepJjHWHXSjeW7O5PL7lEFaeQmiVyw4kkc5/lyYKzrv6ElWRX/MrEWfPiJWqbTvfIvjM1Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.58.0.tgz",
- "integrity": "sha512-cCePktb9+6R9itIJdeCFF9txPU7pQeEHB5AbHu/MKsfH/k70ZtOeq1k4YAtBv9Z7mmKI5/wOLYjQ+B9QdxR6LA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.58.0.tgz",
- "integrity": "sha512-iekUaLkfliAsDl4/xSdoCJ1gnnIXvoNz85C8U8+ZxknM5pBStfZjeXgB8lXobDQvvPRCN8FPmmuTtH+z95HTmg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.58.0.tgz",
- "integrity": "sha512-68ofRgJNl/jYJbxFjCKE7IwhbfxOl1muPN4KbIqAIe32lm22KmU7E8OPvyy68HTNkI2iV/c8y2kSPSm2mW/Q9Q==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.58.0.tgz",
- "integrity": "sha512-dpz8vT0i+JqUKuSNPCP5SYyIV2Lh0sNL1+FhM7eLC457d5B9/BC3kDPp5BBftMmTNsBarcPcoz5UGSsnCiw4XQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.58.0.tgz",
- "integrity": "sha512-4gdkkf9UJ7tafnweBCR/mk4jf3Jfl0cKX9Np80t5i78kjIH0ZdezUv/JDI2VtruE5lunfACqftJ8dIMGN4oHew==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.58.0.tgz",
- "integrity": "sha512-YFS4vPnOkDTD/JriUeeZurFYoJhPf9GQQEF/v4lltp3mVcBmnsAdjEWhr2cjUCZzZNzxCG0HZOvJU44UGHSdzw==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.58.0.tgz",
- "integrity": "sha512-x2xgZlFne+QVNKV8b4wwaCS8pwq3y14zedZ5DqLzjdRITvreBk//4Knbcvm7+lWmms9V9qFp60MtUd0/t/PXPw==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.58.0.tgz",
- "integrity": "sha512-jIhrujyn4UnWF8S+DHSkAkDEO3hLX0cjzxJZPLF80xFyzyUIYgSMRcYQ3+uqEoyDD2beGq7Dj7edi8OnJcS/hg==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.58.0.tgz",
- "integrity": "sha512-+410Srdoh78MKSJxTQ+hZ/Mx+ajd6RjjPwBPNd0R3J9FtL6ZA0GqiiyNjCO9In0IzZkCNrpGymSfn+kgyPQocg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.58.0.tgz",
- "integrity": "sha512-ZjMyby5SICi227y1MTR3VYBpFTdZs823Rs/hpakufleBoufoOIB6jtm9FEoxn/cgO7l6PM2rCEl5Kre5vX0QrQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.58.0.tgz",
- "integrity": "sha512-ds4iwfYkSQ0k1nb8LTcyXw//ToHOnNTJtceySpL3fa7tc/AsE+UpUFphW126A6fKBGJD5dhRvg8zw1rvoGFxmw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.58.0.tgz",
- "integrity": "sha512-fd/zpJniln4ICdPkjWFhZYeY/bpnaN9pGa6ko+5WD38I0tTqk9lXMgXZg09MNdhpARngmxiCg0B0XUamNw/5BQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.58.0.tgz",
- "integrity": "sha512-YpG8dUOip7DCz3nr/JUfPbIUo+2d/dy++5bFzgi4ugOGBIox+qMbbqt/JoORwvI/C9Kn2tz6+Bieoqd5+B1CjA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.58.0.tgz",
- "integrity": "sha512-b9DI8jpFQVh4hIXFr0/+N/TzLdpBIoPzjt0Rt4xJbW3mzguV3mduR9cNgiuFcuL/TeORejJhCWiAXe3E/6PxWA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.58.0.tgz",
- "integrity": "sha512-CSrVpmoRJFN06LL9xhkitkwUcTZtIotYAF5p6XOR2zW0Zz5mzb3IPpcoPhB02frzMHFNo1reQ9xSF5fFm3hUsQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.58.0.tgz",
- "integrity": "sha512-QFsBgQNTnh5K0t/sBsjJLq24YVqEIVkGpfN2VHsnN90soZyhaiA9UUHufcctVNL4ypJY0wrwad0wslx2KJQ1/w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@types/chai": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
- "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/deep-eql": "*",
- "assertion-error": "^2.0.1"
- }
- },
- "node_modules/@types/deep-eql": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
- "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/estree": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "24.10.13",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.13.tgz",
- "integrity": "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==",
- "devOptional": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~7.16.0"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz",
- "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/regexpp": "^4.12.2",
- "@typescript-eslint/scope-manager": "8.56.0",
- "@typescript-eslint/type-utils": "8.56.0",
- "@typescript-eslint/utils": "8.56.0",
- "@typescript-eslint/visitor-keys": "8.56.0",
- "ignore": "^7.0.5",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^2.4.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^8.56.0",
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
- "version": "7.0.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
- "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz",
- "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/scope-manager": "8.56.0",
- "@typescript-eslint/types": "8.56.0",
- "@typescript-eslint/typescript-estree": "8.56.0",
- "@typescript-eslint/visitor-keys": "8.56.0",
- "debug": "^4.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/project-service": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz",
- "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.56.0",
- "@typescript-eslint/types": "^8.56.0",
- "debug": "^4.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz",
- "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.56.0",
- "@typescript-eslint/visitor-keys": "8.56.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz",
- "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz",
- "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.56.0",
- "@typescript-eslint/typescript-estree": "8.56.0",
- "@typescript-eslint/utils": "8.56.0",
- "debug": "^4.4.3",
- "ts-api-utils": "^2.4.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz",
- "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz",
- "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/project-service": "8.56.0",
- "@typescript-eslint/tsconfig-utils": "8.56.0",
- "@typescript-eslint/types": "8.56.0",
- "@typescript-eslint/visitor-keys": "8.56.0",
- "debug": "^4.4.3",
- "minimatch": "^9.0.5",
- "semver": "^7.7.3",
- "tinyglobby": "^0.2.15",
- "ts-api-utils": "^2.4.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz",
- "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.9.1",
- "@typescript-eslint/scope-manager": "8.56.0",
- "@typescript-eslint/types": "8.56.0",
- "@typescript-eslint/typescript-estree": "8.56.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz",
- "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.56.0",
- "eslint-visitor-keys": "^5.0.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
- "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^20.19.0 || ^22.13.0 || >=24"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@vitest/coverage-v8": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz",
- "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.3.0",
- "@bcoe/v8-coverage": "^1.0.2",
- "ast-v8-to-istanbul": "^0.3.3",
- "debug": "^4.4.1",
- "istanbul-lib-coverage": "^3.2.2",
- "istanbul-lib-report": "^3.0.1",
- "istanbul-lib-source-maps": "^5.0.6",
- "istanbul-reports": "^3.1.7",
- "magic-string": "^0.30.17",
- "magicast": "^0.3.5",
- "std-env": "^3.9.0",
- "test-exclude": "^7.0.1",
- "tinyrainbow": "^2.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@vitest/browser": "3.2.4",
- "vitest": "3.2.4"
- },
- "peerDependenciesMeta": {
- "@vitest/browser": {
- "optional": true
- }
- }
- },
- "node_modules/@vitest/expect": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
- "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/chai": "^5.2.2",
- "@vitest/spy": "3.2.4",
- "@vitest/utils": "3.2.4",
- "chai": "^5.2.0",
- "tinyrainbow": "^2.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/mocker": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
- "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/spy": "3.2.4",
- "estree-walker": "^3.0.3",
- "magic-string": "^0.30.17"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "msw": "^2.4.9",
- "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
- },
- "peerDependenciesMeta": {
- "msw": {
- "optional": true
- },
- "vite": {
- "optional": true
- }
- }
- },
- "node_modules/@vitest/pretty-format": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
- "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tinyrainbow": "^2.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/runner": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
- "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/utils": "3.2.4",
- "pathe": "^2.0.3",
- "strip-literal": "^3.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/snapshot": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
- "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/pretty-format": "3.2.4",
- "magic-string": "^0.30.17",
- "pathe": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/spy": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
- "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tinyspy": "^4.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/ui": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.2.4.tgz",
- "integrity": "sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/utils": "3.2.4",
- "fflate": "^0.8.2",
- "flatted": "^3.3.3",
- "pathe": "^2.0.3",
- "sirv": "^3.0.1",
- "tinyglobby": "^0.2.14",
- "tinyrainbow": "^2.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "vitest": "3.2.4"
- }
- },
- "node_modules/@vitest/utils": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
- "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/pretty-format": "3.2.4",
- "loupe": "^3.1.4",
- "tinyrainbow": "^2.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/acorn": {
- "version": "8.16.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
- "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/ajv": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
- "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-colors": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
- "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
- "license": "Python-2.0"
- },
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/assertion-error": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
- "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/ast-v8-to-istanbul": {
- "version": "0.3.12",
- "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz",
- "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.31",
- "estree-walker": "^3.0.3",
- "js-tokens": "^10.0.0"
- }
- },
- "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz",
- "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/better-path-resolve": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz",
- "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-windows": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cac": {
- "version": "6.7.14",
- "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
- "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/chai": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz",
- "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "assertion-error": "^2.0.1",
- "check-error": "^2.1.1",
- "deep-eql": "^5.0.1",
- "loupe": "^3.1.0",
- "pathval": "^2.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/chalk": {
- "version": "5.6.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
- "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
- "license": "MIT",
- "engines": {
- "node": "^12.17.0 || ^14.13 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/chardet": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
- "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==",
- "license": "MIT"
- },
- "node_modules/check-error": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz",
- "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 16"
- }
- },
- "node_modules/ci-info": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cli-cursor": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
- "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
- "license": "MIT",
- "dependencies": {
- "restore-cursor": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/cli-spinners": {
- "version": "2.9.2",
- "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
- "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/cli-width": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
- "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
- "license": "ISC",
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "license": "MIT"
- },
- "node_modules/commander": {
- "version": "14.0.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
- "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
- "license": "MIT",
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/dataloader": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz",
- "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/deep-eql": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
- "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/detect-indent": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
- "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dotenv": {
- "version": "8.6.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
- "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/eastasianwidth": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
- "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/emoji-regex": {
- "version": "10.6.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
- "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
- "license": "MIT"
- },
- "node_modules/enquirer": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz",
- "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-colors": "^4.1.1",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/es-module-lexer": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
- "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/esbuild": {
- "version": "0.27.3",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
- "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.3",
- "@esbuild/android-arm": "0.27.3",
- "@esbuild/android-arm64": "0.27.3",
- "@esbuild/android-x64": "0.27.3",
- "@esbuild/darwin-arm64": "0.27.3",
- "@esbuild/darwin-x64": "0.27.3",
- "@esbuild/freebsd-arm64": "0.27.3",
- "@esbuild/freebsd-x64": "0.27.3",
- "@esbuild/linux-arm": "0.27.3",
- "@esbuild/linux-arm64": "0.27.3",
- "@esbuild/linux-ia32": "0.27.3",
- "@esbuild/linux-loong64": "0.27.3",
- "@esbuild/linux-mips64el": "0.27.3",
- "@esbuild/linux-ppc64": "0.27.3",
- "@esbuild/linux-riscv64": "0.27.3",
- "@esbuild/linux-s390x": "0.27.3",
- "@esbuild/linux-x64": "0.27.3",
- "@esbuild/netbsd-arm64": "0.27.3",
- "@esbuild/netbsd-x64": "0.27.3",
- "@esbuild/openbsd-arm64": "0.27.3",
- "@esbuild/openbsd-x64": "0.27.3",
- "@esbuild/openharmony-arm64": "0.27.3",
- "@esbuild/sunos-x64": "0.27.3",
- "@esbuild/win32-arm64": "0.27.3",
- "@esbuild/win32-ia32": "0.27.3",
- "@esbuild/win32-x64": "0.27.3"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint": {
- "version": "9.39.3",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.3.tgz",
- "integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.8.0",
- "@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.21.1",
- "@eslint/config-helpers": "^0.4.2",
- "@eslint/core": "^0.17.0",
- "@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.39.3",
- "@eslint/plugin-kit": "^0.4.1",
- "@humanfs/node": "^0.16.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.4.2",
- "@types/estree": "^1.0.6",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.6",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.4.0",
- "eslint-visitor-keys": "^4.2.1",
- "espree": "^10.4.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-scope": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
- "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
- "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/espree": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
- "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "acorn": "^8.15.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true,
- "license": "BSD-2-Clause",
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/esquery": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
- "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "estraverse": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estree-walker": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
- "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "^1.0.0"
- }
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/expect-type": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
- "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/extendable-error": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz",
- "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fflate": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
- "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/flatted": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
- "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/foreground-child": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
- "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "cross-spawn": "^7.0.6",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/get-east-asian-width": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz",
- "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/glob": {
- "version": "10.5.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
- "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
- "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^3.1.2",
- "minimatch": "^9.0.4",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^1.11.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/glob/node_modules/brace-expansion": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
- "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/glob/node_modules/minimatch": {
- "version": "9.0.9",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
- "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.2"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/human-id": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.1.3.tgz",
- "integrity": "sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "human-id": "dist/cli.js"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
- "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/import-fresh": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
- "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/import-fresh/node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-interactive": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
- "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-subdir": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz",
- "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "better-path-resolve": "1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/is-unicode-supported": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
- "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "license": "ISC"
- },
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-lib-source-maps": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
- "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.23",
- "debug": "^4.1.1",
- "istanbul-lib-coverage": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
- "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jackspeak": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
- "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/cliui": "^8.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- },
- "optionalDependencies": {
- "@pkgjs/parseargs": "^0.11.0"
- }
- },
- "node_modules/js-tokens": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
- "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/js-yaml": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
- "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
- "dev": true,
- "license": "MIT",
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.startcase": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
- "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/log-symbols": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
- "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^5.3.0",
- "is-unicode-supported": "^1.3.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/log-symbols/node_modules/is-unicode-supported": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
- "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/loupe": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
- "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/magicast": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
- "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.25.4",
- "@babel/types": "^7.25.4",
- "source-map-js": "^1.2.0"
- }
- },
- "node_modules/make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.5.3"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/mimic-function": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
- "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
- "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/mrmime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
- "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/mute-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
- "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
- "license": "ISC",
- "engines": {
- "node": "^18.17.0 || >=20.5.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/onetime": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
- "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
- "license": "MIT",
- "dependencies": {
- "mimic-function": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/optionator": {
- "version": "0.9.4",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
- "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.5"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/ora": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz",
- "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^5.3.0",
- "cli-cursor": "^5.0.0",
- "cli-spinners": "^2.9.2",
- "is-interactive": "^2.0.0",
- "is-unicode-supported": "^2.0.0",
- "log-symbols": "^6.0.0",
- "stdin-discarder": "^0.2.2",
- "string-width": "^7.2.0",
- "strip-ansi": "^7.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ora/node_modules/ansi-regex": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
- "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/ora/node_modules/strip-ansi": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
- "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/outdent": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz",
- "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/p-filter": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz",
- "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-map": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/p-map": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
- "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/package-json-from-dist": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
- "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
- "dev": true,
- "license": "BlueOak-1.0.0"
- },
- "node_modules/package-manager-detector": {
- "version": "0.2.11",
- "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz",
- "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "quansync": "^0.2.7"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-scurry": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
- "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "lru-cache": "^10.2.0",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
- },
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/pathval": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
- "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 14.16"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pify": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
- "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.11",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/posthog-node": {
- "version": "5.24.17",
- "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.24.17.tgz",
- "integrity": "sha512-mdb8TKt+YCRbGQdYar3AKNUPCyEiqcprScF4unYpGALF6HlBaEuO6wPuIqXXpCWkw4VclJYCKbb6lq6pH6bJeA==",
- "license": "MIT",
- "dependencies": {
- "@posthog/core": "1.23.1"
- },
- "engines": {
- "node": "^20.20.0 || >=22.22.0"
- }
- },
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/prettier": {
- "version": "2.8.8",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
- "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "prettier": "bin-prettier.js"
- },
- "engines": {
- "node": ">=10.13.0"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/quansync": {
- "version": "0.2.11",
- "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
- "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/antfu"
- },
- {
- "type": "individual",
- "url": "https://github.com/sponsors/sxzz"
- }
- ],
- "license": "MIT"
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/read-yaml-file": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz",
- "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.1.5",
- "js-yaml": "^3.6.1",
- "pify": "^4.0.1",
- "strip-bom": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/read-yaml-file/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/read-yaml-file/node_modules/js-yaml": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
- "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/restore-cursor": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
- "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
- "license": "MIT",
- "dependencies": {
- "onetime": "^7.0.0",
- "signal-exit": "^4.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rollup": {
- "version": "4.58.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.58.0.tgz",
- "integrity": "sha512-wbT0mBmWbIvvq8NeEYWWvevvxnOyhKChir47S66WCxw1SXqhw7ssIYejnQEVt7XYQpsj2y8F9PM+Cr3SNEa0gw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "1.0.8"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.58.0",
- "@rollup/rollup-android-arm64": "4.58.0",
- "@rollup/rollup-darwin-arm64": "4.58.0",
- "@rollup/rollup-darwin-x64": "4.58.0",
- "@rollup/rollup-freebsd-arm64": "4.58.0",
- "@rollup/rollup-freebsd-x64": "4.58.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.58.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.58.0",
- "@rollup/rollup-linux-arm64-gnu": "4.58.0",
- "@rollup/rollup-linux-arm64-musl": "4.58.0",
- "@rollup/rollup-linux-loong64-gnu": "4.58.0",
- "@rollup/rollup-linux-loong64-musl": "4.58.0",
- "@rollup/rollup-linux-ppc64-gnu": "4.58.0",
- "@rollup/rollup-linux-ppc64-musl": "4.58.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.58.0",
- "@rollup/rollup-linux-riscv64-musl": "4.58.0",
- "@rollup/rollup-linux-s390x-gnu": "4.58.0",
- "@rollup/rollup-linux-x64-gnu": "4.58.0",
- "@rollup/rollup-linux-x64-musl": "4.58.0",
- "@rollup/rollup-openbsd-x64": "4.58.0",
- "@rollup/rollup-openharmony-arm64": "4.58.0",
- "@rollup/rollup-win32-arm64-msvc": "4.58.0",
- "@rollup/rollup-win32-ia32-msvc": "4.58.0",
- "@rollup/rollup-win32-x64-gnu": "4.58.0",
- "@rollup/rollup-win32-x64-msvc": "4.58.0",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "7.7.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
- "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/siginfo": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "license": "ISC",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/sirv": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
- "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@polka/url": "^1.0.0-next.24",
- "mrmime": "^2.0.0",
- "totalist": "^3.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/spawndamnit": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz",
- "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==",
- "dev": true,
- "license": "SEE LICENSE IN LICENSE",
- "dependencies": {
- "cross-spawn": "^7.0.5",
- "signal-exit": "^4.0.1"
- }
- },
- "node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/stackback": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/std-env": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
- "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/stdin-discarder": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
- "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/string-width": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
- "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^10.3.0",
- "get-east-asian-width": "^1.0.0",
- "strip-ansi": "^7.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/string-width-cjs": {
- "name": "string-width",
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string-width-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/string-width/node_modules/ansi-regex": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
- "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/string-width/node_modules/strip-ansi": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
- "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi-cjs": {
- "name": "strip-ansi",
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/strip-literal": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz",
- "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "js-tokens": "^9.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/term-size": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
- "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/test-exclude": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz",
- "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@istanbuljs/schema": "^0.1.2",
- "glob": "^10.4.1",
- "minimatch": "^10.2.2"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/test-exclude/node_modules/balanced-match": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
- "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "18 || 20 || >=22"
- }
- },
- "node_modules/test-exclude/node_modules/brace-expansion": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
- "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^4.0.2"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- }
- },
- "node_modules/test-exclude/node_modules/minimatch": {
- "version": "10.2.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
- "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "brace-expansion": "^5.0.5"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/tinybench": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
- "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tinyexec": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
- "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/tinyglobby/node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/tinypool": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
- "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.0.0 || >=20.0.0"
- }
- },
- "node_modules/tinyrainbow": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
- "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/tinyspy": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz",
- "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/totalist": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
- "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/ts-api-utils": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
- "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.12"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4"
- }
- },
- "node_modules/type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/typescript-eslint": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz",
- "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/eslint-plugin": "8.56.0",
- "@typescript-eslint/parser": "8.56.0",
- "@typescript-eslint/typescript-estree": "8.56.0",
- "@typescript-eslint/utils": "8.56.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/undici-types": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
- "devOptional": true,
- "license": "MIT"
- },
- "node_modules/universalify": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
- "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4.0.0"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/vite": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
- "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.27.0",
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3",
- "postcss": "^8.5.6",
- "rollup": "^4.43.0",
- "tinyglobby": "^0.2.15"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^20.19.0 || >=22.12.0",
- "jiti": ">=1.21.0",
- "less": "^4.0.0",
- "lightningcss": "^1.21.0",
- "sass": "^1.70.0",
- "sass-embedded": "^1.70.0",
- "stylus": ">=0.54.8",
- "sugarss": "^5.0.0",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/vite-node": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
- "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cac": "^6.7.14",
- "debug": "^4.4.1",
- "es-module-lexer": "^1.7.0",
- "pathe": "^2.0.3",
- "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
- },
- "bin": {
- "vite-node": "vite-node.mjs"
- },
- "engines": {
- "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vite/node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/vite/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/vitest": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
- "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/chai": "^5.2.2",
- "@vitest/expect": "3.2.4",
- "@vitest/mocker": "3.2.4",
- "@vitest/pretty-format": "^3.2.4",
- "@vitest/runner": "3.2.4",
- "@vitest/snapshot": "3.2.4",
- "@vitest/spy": "3.2.4",
- "@vitest/utils": "3.2.4",
- "chai": "^5.2.0",
- "debug": "^4.4.1",
- "expect-type": "^1.2.1",
- "magic-string": "^0.30.17",
- "pathe": "^2.0.3",
- "picomatch": "^4.0.2",
- "std-env": "^3.9.0",
- "tinybench": "^2.9.0",
- "tinyexec": "^0.3.2",
- "tinyglobby": "^0.2.14",
- "tinypool": "^1.1.1",
- "tinyrainbow": "^2.0.0",
- "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
- "vite-node": "3.2.4",
- "why-is-node-running": "^2.3.0"
- },
- "bin": {
- "vitest": "vitest.mjs"
- },
- "engines": {
- "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@edge-runtime/vm": "*",
- "@types/debug": "^4.1.12",
- "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
- "@vitest/browser": "3.2.4",
- "@vitest/ui": "3.2.4",
- "happy-dom": "*",
- "jsdom": "*"
- },
- "peerDependenciesMeta": {
- "@edge-runtime/vm": {
- "optional": true
- },
- "@types/debug": {
- "optional": true
- },
- "@types/node": {
- "optional": true
- },
- "@vitest/browser": {
- "optional": true
- },
- "@vitest/ui": {
- "optional": true
- },
- "happy-dom": {
- "optional": true
- },
- "jsdom": {
- "optional": true
- }
- }
- },
- "node_modules/vitest/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "dev": true,
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/why-is-node-running": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
- "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "siginfo": "^2.0.0",
- "stackback": "0.0.2"
- },
- "bin": {
- "why-is-node-running": "cli.js"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
- "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi-cjs": {
- "name": "wrap-ansi",
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/wrap-ansi-cjs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/wrap-ansi/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yaml": {
- "version": "2.8.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
- "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
- "license": "ISC",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/eemeli"
- }
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/yoctocolors-cjs": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz",
- "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/zod": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
- "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/scripts/pack-version-check.mjs b/scripts/pack-version-check.mjs
index 43cf8050eb..71131f3833 100644
--- a/scripts/pack-version-check.mjs
+++ b/scripts/pack-version-check.mjs
@@ -53,7 +53,7 @@ function main() {
let tgzPath;
try {
- log(`Packing @fission-ai/openspec@${expected}...`);
+ log(`Packing @fkmatsuda/br-openspec@${expected}...`);
const filename = npmPack();
tgzPath = path.resolve(filename);
log(`Created: ${tgzPath}`);
From da9565a9ab4bd0dd1c4f335cafb61e208236315a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A1bio=20Kenji=20Matsuda?=
Date: Thu, 23 Apr 2026 23:18:16 -0300
Subject: [PATCH 10/23] fix: update vitest coverage dependency to use caret
versioning
Co-authored-by: Copilot
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index bd40fe9c98..8c6275cfc2 100644
--- a/package.json
+++ b/package.json
@@ -63,7 +63,7 @@
"@changesets/changelog-github": "^0.5.2",
"@changesets/cli": "^2.27.7",
"@types/node": "^24.2.0",
- "@vitest/coverage-v8": "3.2.4",
+ "@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4",
"eslint": "^9.39.2",
"typescript": "^5.9.3",
From 23733734067054b46c5b8486ff4df4316f3d8788 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A1bio=20Kenji=20Matsuda?=
Date: Thu, 23 Apr 2026 23:56:44 -0300
Subject: [PATCH 11/23] fix: update supported tool IDs in CLI documentation
---
docs/cli.md | 2 +-
docs/supported-tools.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/cli.md b/docs/cli.md
index fd098014cf..9e8734e388 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -89,7 +89,7 @@ openspec init [path] [options]
`--profile custom` uses whatever workflows are currently selected in global config (`openspec config profile`).
-**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kimi`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
+**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `forgecode`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `lingma`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
**Examples:**
diff --git a/docs/supported-tools.md b/docs/supported-tools.md
index 9192145e82..0681abbe36 100644
--- a/docs/supported-tools.md
+++ b/docs/supported-tools.md
@@ -72,7 +72,7 @@ openspec init --tools none
openspec init --profile core
```
-**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `forgecode`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
+**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `forgecode`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `lingma`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf`
## Workflow-Dependent Installation
From b4de5f984d7ec12eb43f8b18b34a6ddfc371c92f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A1bio=20Kenji=20Matsuda?=
Date: Fri, 24 Apr 2026 00:19:29 -0300
Subject: [PATCH 12/23] fix: update vitest coverage dependency to use caret
versioning
---
pnpm-lock.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index cb91138013..31f0d9a2fa 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,7 +46,7 @@ importers:
specifier: ^24.2.0
version: 24.2.0
'@vitest/coverage-v8':
- specifier: 3.2.4
+ specifier: ^3.2.4
version: 3.2.4(vitest@3.2.4)
'@vitest/ui':
specifier: ^3.2.4
From b6f9e7a435948057dc3c011b94a50e4513e4b706 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A1bio=20Kenji=20Matsuda?=
Date: Fri, 24 Apr 2026 07:15:46 -0300
Subject: [PATCH 13/23] fix: update yaml dependency to version 2.9.0
Co-authored-by: Copilot
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 8c6275cfc2..972e5ed671 100644
--- a/package.json
+++ b/package.json
@@ -78,7 +78,7 @@
"fast-glob": "^3.3.3",
"ora": "^8.2.0",
"posthog-node": "^5.20.0",
- "yaml": "^2.8.2",
+ "yaml": "^2.9.0",
"zod": "^4.0.17"
}
}
From d5c690f7ef91c4e432a6bf89883e5bddc069ca15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A1bio=20Kenji=20Matsuda?=
Date: Thu, 30 Apr 2026 15:51:17 -0300
Subject: [PATCH 14/23] feat: add comprehensive agent guide and project
documentation
---
AGENTS.md | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 192 insertions(+)
diff --git a/AGENTS.md b/AGENTS.md
index e69de29bb2..fbb8012054 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -0,0 +1,192 @@
+# BR-OpenSpec — Agent Guide
+
+## Project Overview
+
+BR-OpenSpec is an AI-native system for spec-driven development. It is a Node.js CLI tool (published as `@fkmatsuda/br-openspec` on npm) that helps teams align on what to build before writing code. Each change gets its own folder with a proposal, specs, design, and tasks. OpenSpec generates AI assistant integrations (skills, slash commands, and config files) for 25+ tools including Claude Code, Cursor, GitHub Copilot, Gemini CLI, Codex, and many others.
+
+The project uses its own spec-driven workflow. You will find active changes under `openspec/changes/` and archived changes under `openspec/changes/archive/`. The project's own specs live in `openspec/specs/`.
+
+## Technology Stack
+
+- **Runtime**: Node.js ≥20.19.0 (ESM modules only)
+- **Language**: TypeScript 5.9+
+- **Package Manager**: pnpm 9
+- **CLI Framework**: Commander.js
+- **Validation**: Zod
+- **Config / Frontmatter**: YAML
+- **Prompts**: @inquirer/prompts (must be dynamically imported — see Code Style)
+- **Styling**: chalk, ora spinners
+- **Telemetry**: PostHog (anonymous, opt-out)
+
+## Build & Development Commands
+
+All commands are run via pnpm:
+
+```bash
+# Install dependencies
+pnpm install
+
+# Build (compiles TypeScript to dist/ via custom build.js)
+pnpm run build
+
+# Watch mode for development
+pnpm run dev
+
+# Develop CLI locally (builds then runs bin/openspec.js)
+pnpm run dev:cli
+
+# Run tests
+pnpm test
+
+# Run tests in watch mode
+pnpm run test:watch
+
+# Run tests with coverage
+pnpm run test:coverage
+
+# Run linting
+pnpm lint
+
+# Type check without emitting
+pnpm exec tsc --noEmit
+```
+
+The build script (`build.js`) cleans `dist/` and invokes `tsc` directly. There is no bundler — the published package uses the raw compiled JavaScript from `dist/`.
+
+## Project Structure
+
+```
+src/
+ cli/ # CLI entry point (Commander.js program setup)
+ commands/ # Command implementations (change, config, schema, show, spec, tools, validate, workflow)
+ core/ # Core business logic
+ archive.ts
+ artifact-graph/ # Artifact graph engine for workflow schemas
+ available-tools.ts
+ command-generation/ # Adapter-based command/skill generation for 25+ AI tools
+ completions/ # Shell completion generation (bash, zsh, fish, powershell)
+ config.ts # AI tool registry and constants
+ config-prompts.ts
+ config-schema.ts
+ global-config.ts # XDG-compliant global config management
+ init.ts # Project initialization command
+ profiles.ts # Workflow profiles (core vs custom)
+ project-config.ts
+ schemas/ # Zod schemas for validation
+ shared/ # Shared skill generation and tool detection
+ templates/ # Workflow template definitions
+ tools-manager.ts
+ update.ts
+ validation/ # Spec/change validation engine
+ prompts/ # Custom prompt components (searchable multi-select)
+ telemetry/ # Anonymous usage analytics (PostHog)
+ ui/ # ASCII art, welcome screens, palette
+ utils/ # File system, interactive mode detection, task progress, etc.
+ index.ts # Public API exports
+
+test/ # Mirror of src/ structure; Vitest tests
+openspec/ # The project's own spec-driven content
+ changes/ # Active and archived change proposals
+ explorations/ # Design explorations
+ specs/ # Living specifications
+ config.yaml # Project-level OpenSpec config
+schemas/ # Built-in workflow schemas (e.g., spec-driven)
+docs/ # Markdown documentation (English + pt-BR)
+```
+
+## Code Style Guidelines
+
+- **ESM only**: All imports must use `.js` extensions (e.g., `import { foo } from './bar.js'`).
+- **Dynamic imports for @inquirer**: `@inquirer/core` and `@inquirer/prompts` **must** be loaded with `import()` at runtime. Static imports of these packages are forbidden by ESLint because they have side effects that can hang the Node.js event loop when stdin is piped (see issue #367). The only exception is `src/core/init.ts`, which is itself dynamically imported from the CLI startup path.
+- **Cross-platform paths**: Always use `path.join()` or `path.resolve()`. Never hardcode `/` or `\`. Tests must use `path.join()` for expected path values.
+- **Constants over magic strings**: Reuse existing constants (e.g., `OPENSPEC_DIR_NAME`, `AI_TOOLS`) rather than inventing new detection mechanisms.
+- **Explicit lookups preferred**: Prefer explicit list lookups over pattern matching or regex when generating or tracking artifacts.
+- **TypeScript strict mode**: Enabled. `any` is allowed in existing code but should be avoided in new code.
+- **Conventional commits**: Use `type(scope): subject` format for commit messages.
+
+## Testing Strategy
+
+- **Framework**: Vitest 3.x with `globals: true`
+- **Pool**: `forks` (process isolation required because tests spawn CLI child processes and make `process.cwd()` assumptions)
+- **Max workers**: Capped at 4 (or via `VITEST_MAX_WORKERS` env var) to prevent runaway CPU/memory in CI
+- **Test timeout**: 10 seconds default; 3 second teardown timeout
+- **Coverage**: `@vitest/coverage-v8`, outputs text/json/html; excludes `dist/`, `bin/`, `test/`, config files
+- **Global setup**: `vitest.setup.ts` ensures the CLI is built before tests run
+- **E2E tests**: Use `test/helpers/run-cli.ts` to spawn the compiled CLI in a child process and capture stdout/stderr
+- **Mocking**: Vitest mocks are used heavily for `@inquirer/prompts`, file system modules, and UI components
+
+## CI / CD
+
+### GitHub Actions Workflows
+
+- **`.github/workflows/ci.yml`**: Runs on PRs, merge groups, and pushes to `main`
+ - `test_pr`: Build + test on Ubuntu (PRs)
+ - `test_matrix`: Build + test on Ubuntu, macOS, and Windows (pushes to `main`)
+ - `lint`: Build, type check (`tsc --noEmit`), lint, and verify `dist/cli/index.js` exists
+ - `nix-flake-validate`: Validates Nix flake build (only when Nix-related files change)
+ - `validate-changesets`: Ensures changesets are valid for PRs
+ - `required-checks-pr` / `required-checks-main`: Aggregates all required checks
+
+- **`.github/workflows/release-prepare.yml`**: Runs on pushes to `main`
+ - Uses Changesets action to open/update a "Version Packages" PR
+ - Publishes to npm via OIDC trusted publishing (no long-lived npm token)
+ - Requires a GitHub App token for checkout so that CI runs on the version PR
+
+### Release Process
+
+- Uses [Changesets](https://github.com/changesets/changesets) for versioning and changelog generation
+- Run `pnpm changeset` to add a changeset
+- The release PR is auto-created; merging it triggers the publish
+- `pnpm run release:ci` is the publish script (verifies version then runs `changeset publish`)
+
+## Deployment & Distribution
+
+- **npm**: Published as `@fkmatsuda/br-openspec`
+- **Nix**: `flake.nix` provides packages, apps, and dev shells for `x86_64-linux`, `aarch64-linux`, `x86_64-darwin`, `aarch64-darwin`
+- **Global install**: `npm install -g @fkmatsuda/br-openspec@latest`
+- **Entry points**:
+ - CLI: `bin/openspec.js` → `dist/cli/index.js`
+ - Library: `dist/index.js` / `dist/index.d.ts`
+
+## Security & Privacy
+
+- **Telemetry**: Anonymous usage stats sent to PostHog. Only command names and version are tracked. No arguments, paths, content, or PII.
+ - Opt-out: `export OPENSPEC_TELEMETRY=0` or `export DO_NOT_TRACK=1`
+ - Auto-disabled in CI (`CI=true`)
+- **npm publishing**: Uses OIDC trusted publishing from GitHub Actions (no static tokens in repo)
+- **Sensitive files**: `.env` files are gitignored. No API keys or secrets should be committed.
+
+## Development Conventions
+
+- **Spec-driven**: The project eats its own dog food. Changes should have a proposal and specs in `openspec/changes/` when they are significant.
+- **Profile system**: Workflows are delivered based on profiles (`core` = streamlined, `custom` = user-selected). The global config controls delivery method (`skills`, `commands`, or `both`).
+- **AI tool adapters**: Each supported AI tool has an adapter in `src/core/command-generation/adapters/`. New tool support requires adding an adapter and registering it in the factory.
+- **Shell completions**: New CLI commands should update completion generators in `src/core/completions/`.
+- **Legacy cleanup**: The init command detects and optionally cleans up legacy file layouts.
+- **Windows awareness**: Any file system or path logic must work on Windows. CI tests on `windows-latest` with PowerShell.
+
+## Useful Environment Variables
+
+- `OPENSPEC_TELEMETRY=0` — Disable telemetry
+- `DO_NOT_TRACK=1` — Disable telemetry (standard)
+- `VITEST_MAX_WORKERS=N` — Override test parallelism
+- `OPENSPEC_INTERACTIVE=0` — Force non-interactive mode (used in tests)
+- `OPENSPEC_CONCURRENCY=N` — Max concurrent validations (default 6)
+- `NO_COLOR=1` — Disable colored output (also `--no-color` flag)
+- `XDG_CONFIG_HOME` — Override global config directory
+
+## Key Files for Agents
+
+| File | Purpose |
+|------|---------|
+| `src/cli/index.ts` | CLI entry point; all commands are registered here |
+| `src/core/config.ts` | AI tool registry (`AI_TOOLS` constant) |
+| `src/core/global-config.ts` | XDG-compliant user config |
+| `src/core/profiles.ts` | Workflow profile definitions |
+| `src/core/init.ts` | Project initialization logic |
+| `src/core/validation/validator.ts` | Spec/change validation engine |
+| `test/helpers/run-cli.ts` | E2E test helper for CLI spawning |
+| `openspec/config.yaml` | This project's own OpenSpec configuration |
+| `build.js` | Build script (tsc wrapper) |
+| `vitest.config.ts` | Test configuration |
+| `eslint.config.js` | ESLint configuration (typescript-eslint) |
From c22a883c1fd55a6f8acbc7122c7443166b30d52d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A1bio=20Kenji=20Matsuda?=
Date: Thu, 30 Apr 2026 18:39:44 -0300
Subject: [PATCH 15/23] refactor: Refactor prompts and UI messages to use
centralized message constants; update translations for consistency
- Updated `searchable-multi-select.ts` to replace hardcoded messages with constants from `PROMPT_MESSAGES`.
- Refactored `welcome-screen.ts` to utilize `UI_MESSAGES` for welcome text and instructions.
- Modified `file-system.ts` to use `FILE_SYSTEM_MESSAGES` for error logging.
- Changed `task-progress.ts` to incorporate `TASK_PROGRESS_MESSAGES` for task status messages.
- Translated various test outputs and error messages to Portuguese for better localization support.
---
src/cli/index.ts | 193 ++---
src/commands/change.ts | 45 +-
src/commands/completion.ts | 45 +-
src/commands/config.ts | 201 ++---
src/commands/feedback.ts | 33 +-
src/commands/schema.ts | 204 ++---
src/commands/show.ts | 35 +-
src/commands/spec.ts | 61 +-
src/commands/tools.ts | 77 +-
src/commands/validate.ts | 56 +-
src/commands/workflow/instructions.ts | 51 +-
src/commands/workflow/new-change.ts | 11 +-
src/commands/workflow/schemas.ts | 9 +-
src/commands/workflow/shared.ts | 9 +-
src/commands/workflow/status.ts | 19 +-
src/commands/workflow/templates.ts | 7 +-
src/core/archive.ts | 63 +-
src/core/init.ts | 89 +-
src/core/list.ts | 21 +-
src/core/migration.ts | 5 +-
src/core/project-config.ts | 15 +-
src/core/templates/workflows/apply-change.ts | 382 ++++-----
.../templates/workflows/archive-change.ts | 312 +++----
.../workflows/bulk-archive-change.ts | 550 ++++++------
.../templates/workflows/continue-change.ts | 298 +++----
src/core/templates/workflows/explore.ts | 490 +++++------
src/core/templates/workflows/feedback.ts | 152 ++--
src/core/templates/workflows/ff-change.ts | 262 +++---
src/core/templates/workflows/new-change.ts | 160 ++--
src/core/templates/workflows/onboard.ts | 520 +++++------
src/core/templates/workflows/propose.ts | 282 +++---
src/core/templates/workflows/sync-specs.ts | 226 ++---
src/core/templates/workflows/verify-change.ts | 498 +++++------
src/core/update.ts | 81 +-
src/core/validation/constants.ts | 50 +-
src/core/validation/validator.ts | 39 +-
src/core/view.ts | 27 +-
src/messages/index.ts | 805 ++++++++++++++++++
src/prompts/searchable-multi-select.ts | 21 +-
src/ui/welcome-screen.ts | 21 +-
src/utils/file-system.ts | 19 +-
src/utils/task-progress.ts | 7 +-
test/commands/artifact-workflow.test.ts | 2 +-
test/commands/spec.test.ts | 4 +-
.../commands/validate.enriched-output.test.ts | 4 +-
test/commands/validate.test.ts | 2 +-
test/core/archive.test.ts | 4 +-
test/core/list.test.ts | 2 +-
48 files changed, 3650 insertions(+), 2819 deletions(-)
create mode 100644 src/messages/index.ts
diff --git a/src/cli/index.ts b/src/cli/index.ts
index 0445461eaa..c948af8dd3 100644
--- a/src/cli/index.ts
+++ b/src/cli/index.ts
@@ -4,6 +4,7 @@ import ora from 'ora';
import path from 'path';
import { promises as fs } from 'fs';
import { AI_TOOLS } from '../core/config.js';
+import { CLI_DESCRIPTIONS, CLI_MESSAGES, CONFIG_MESSAGES } from '../messages/index.js';
import { UpdateCommand } from '../core/update.js';
import { ListCommand } from '../core/list.js';
import { ArchiveCommand } from '../core/archive.js';
@@ -59,11 +60,11 @@ function getCommandPath(command: Command): string {
program
.name('openspec')
- .description('AI-native system for spec-driven development')
+ .description(CLI_DESCRIPTIONS.root)
.version(version);
// Global options
-program.option('--no-color', 'Disable color output');
+program.option('--no-color', CLI_DESCRIPTIONS.noColor);
// Apply global flags and telemetry before any command runs
// Note: preAction receives (thisCommand, actionCommand) where:
@@ -89,14 +90,14 @@ program.hook('postAction', async () => {
});
const availableToolIds = AI_TOOLS.filter((tool) => tool.skillsDir).map((tool) => tool.value);
-const toolsOptionDescription = `Configure AI tools non-interactively. Use "all", "none", or a comma-separated list of: ${availableToolIds.join(', ')}`;
+const toolsOptionDescription = `Configura ferramentas de IA não interativamente. Use "all", "none" ou uma lista separada por vírgula: ${availableToolIds.join(', ')}`;
program
.command('init [path]')
- .description('Initialize OpenSpec in your project')
+ .description(CLI_DESCRIPTIONS.init)
.option('--tools ', toolsOptionDescription)
- .option('--force', 'Auto-cleanup legacy files without prompting')
- .option('--profile ', 'Override global config profile (core or custom)')
+ .option('--force', CLI_DESCRIPTIONS.force)
+ .option('--profile ', CLI_DESCRIPTIONS.profile)
.action(async (targetPath = '.', options?: { tools?: string; force?: boolean; profile?: string }) => {
try {
// Validate that the path is a valid directory
@@ -105,16 +106,16 @@ program
try {
const stats = await fs.stat(resolvedPath);
if (!stats.isDirectory()) {
- throw new Error(`Path "${targetPath}" is not a directory`);
+ throw new Error(CLI_MESSAGES.notADirectory(targetPath));
}
} catch (error: any) {
if (error.code === 'ENOENT') {
// Directory doesn't exist, but we can create it
- console.log(`Directory "${targetPath}" doesn't exist, it will be created.`);
+ console.log(CLI_MESSAGES.directoryWillBeCreated(targetPath));
} else if (error.message && error.message.includes('not a directory')) {
throw error;
} else {
- throw new Error(`Cannot access path "${targetPath}": ${error.message}`);
+ throw new Error(CLI_MESSAGES.cannotAccessPath(targetPath, error.message));
}
}
@@ -127,7 +128,7 @@ program
await initCommand.execute(targetPath);
} catch (error) {
console.log(); // Empty line for spacing
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -135,12 +136,12 @@ program
// Hidden alias: 'experimental' -> 'init' for backwards compatibility
program
.command('experimental', { hidden: true })
- .description('Alias for init (deprecated)')
+ .description(CLI_DESCRIPTIONS.experimental)
.option('--tool ', 'Target AI tool (maps to --tools)')
- .option('--no-interactive', 'Disable interactive prompts')
+ .option('--no-interactive', 'Desativa prompts interativos')
.action(async (options?: { tool?: string; noInteractive?: boolean }) => {
try {
- console.log('Note: "openspec experimental" is deprecated. Use "openspec init" instead.');
+ console.log(CLI_MESSAGES.experimentalDeprecated);
const { InitCommand } = await import('../core/init.js');
const initCommand = new InitCommand({
tools: options?.tool,
@@ -149,15 +150,15 @@ program
await initCommand.execute('.');
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
program
.command('update [path]')
- .description('Update OpenSpec instruction files')
- .option('--force', 'Force update even when tools are up to date')
+ .description(CLI_DESCRIPTIONS.update)
+ .option('--force', 'Força atualização mesmo quando as ferramentas estão atualizadas')
.action(async (targetPath = '.', options?: { force?: boolean }) => {
try {
const resolvedPath = path.resolve(targetPath);
@@ -165,18 +166,18 @@ program
await updateCommand.execute(resolvedPath);
} catch (error) {
console.log(); // Empty line for spacing
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
program
.command('list')
- .description('List items (changes by default). Use --specs to list specs.')
- .option('--specs', 'List specs instead of changes')
- .option('--changes', 'List changes explicitly (default)')
- .option('--sort ', 'Sort order: "recent" (default) or "name"', 'recent')
- .option('--json', 'Output as JSON (for programmatic use)')
+ .description(CLI_DESCRIPTIONS.list)
+ .option('--specs', 'Lista especificações em vez de alterações')
+ .option('--changes', 'Lista alterações explicitamente (padrão)')
+ .option('--sort ', 'Ordem de classificação: "recent" (padrão) ou "name"', 'recent')
+ .option('--json', 'Saída como JSON (para uso programático)')
.action(async (options?: { specs?: boolean; changes?: boolean; sort?: string; json?: boolean }) => {
try {
const listCommand = new ListCommand();
@@ -185,21 +186,21 @@ program
await listCommand.execute('.', mode, { sort, json: options?.json });
} catch (error) {
console.log(); // Empty line for spacing
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
program
.command('view')
- .description('Display an interactive dashboard of specs and changes')
+ .description(CLI_DESCRIPTIONS.view)
.action(async () => {
try {
const viewCommand = new ViewCommand();
await viewCommand.execute('.');
} catch (error) {
console.log(); // Empty line for spacing
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -207,51 +208,51 @@ program
// Change command with subcommands
const changeCmd = program
.command('change')
- .description('Manage OpenSpec change proposals');
+ .description(CLI_DESCRIPTIONS.change);
// Deprecation notice for noun-based commands
changeCmd.hook('preAction', () => {
- console.error('Warning: The "openspec change ..." commands are deprecated. Prefer verb-first commands (e.g., "openspec list", "openspec validate --changes").');
+ console.error(CLI_MESSAGES.changeCommandsDeprecated);
});
changeCmd
.command('show [change-name]')
- .description('Show a change proposal in JSON or markdown format')
- .option('--json', 'Output as JSON')
- .option('--deltas-only', 'Show only deltas (JSON only)')
- .option('--requirements-only', 'Alias for --deltas-only (deprecated)')
+ .description(CLI_DESCRIPTIONS.changeShow)
+ .option('--json', 'Saída como JSON')
+ .option('--deltas-only', 'Exibe apenas deltas (somente JSON)')
+ .option('--requirements-only', 'Alias para --deltas-only (descontinuado)')
.option('--no-interactive', 'Disable interactive prompts')
.action(async (changeName?: string, options?: { json?: boolean; requirementsOnly?: boolean; deltasOnly?: boolean; noInteractive?: boolean }) => {
try {
const changeCommand = new ChangeCommand();
await changeCommand.show(changeName, options);
} catch (error) {
- console.error(`Error: ${(error as Error).message}`);
+ console.error(CLI_MESSAGES.error((error as Error).message));
process.exitCode = 1;
}
});
changeCmd
.command('list')
- .description('List all active changes (DEPRECATED: use "openspec list" instead)')
- .option('--json', 'Output as JSON')
+ .description(CLI_DESCRIPTIONS.changeList)
+ .option('--json', 'Saída como JSON')
.option('--long', 'Show id and title with counts')
.action(async (options?: { json?: boolean; long?: boolean }) => {
try {
- console.error('Warning: "openspec change list" is deprecated. Use "openspec list".');
+ console.error(CLI_MESSAGES.changeListDeprecated);
const changeCommand = new ChangeCommand();
await changeCommand.list(options);
} catch (error) {
- console.error(`Error: ${(error as Error).message}`);
+ console.error(CLI_MESSAGES.error((error as Error).message));
process.exitCode = 1;
}
});
changeCmd
.command('validate [change-name]')
- .description('Validate a change proposal')
- .option('--strict', 'Enable strict validation mode')
- .option('--json', 'Output validation report as JSON')
+ .description(CLI_DESCRIPTIONS.changeValidate)
+ .option('--strict', 'Ativa modo de validação estrita')
+ .option('--json', 'Saída do relatório de validação como JSON')
.option('--no-interactive', 'Disable interactive prompts')
.action(async (changeName?: string, options?: { strict?: boolean; json?: boolean; noInteractive?: boolean }) => {
try {
@@ -261,24 +262,24 @@ changeCmd
process.exit(process.exitCode);
}
} catch (error) {
- console.error(`Error: ${(error as Error).message}`);
+ console.error(CLI_MESSAGES.error((error as Error).message));
process.exitCode = 1;
}
});
program
.command('archive [change-name]')
- .description('Archive a completed change and update main specs')
- .option('-y, --yes', 'Skip confirmation prompts')
- .option('--skip-specs', 'Skip spec update operations (useful for infrastructure, tooling, or doc-only changes)')
- .option('--no-validate', 'Skip validation (not recommended, requires confirmation)')
+ .description(CLI_DESCRIPTIONS.archive)
+ .option('-y, --yes', 'Pula confirmações interativas')
+ .option('--skip-specs', 'Ignora operações de atualização de especificação (útil para alterações de infraestrutura, ferramentas ou apenas documentação)')
+ .option('--no-validate', 'Ignora validação (não recomendado, requer confirmação)')
.action(async (changeName?: string, options?: { yes?: boolean; skipSpecs?: boolean; noValidate?: boolean; validate?: boolean }) => {
try {
const archiveCommand = new ArchiveCommand();
await archiveCommand.execute(changeName, options);
} catch (error) {
console.log(); // Empty line for spacing
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -291,14 +292,14 @@ registerToolsCommand(program);
// Top-level validate command
program
.command('validate [item-name]')
- .description('Validate changes and specs')
- .option('--all', 'Validate all changes and specs')
- .option('--changes', 'Validate all changes')
- .option('--specs', 'Validate all specs')
- .option('--type ', 'Specify item type when ambiguous: change|spec')
- .option('--strict', 'Enable strict validation mode')
- .option('--json', 'Output validation results as JSON')
- .option('--concurrency ', 'Max concurrent validations (defaults to env OPENSPEC_CONCURRENCY or 6)')
+ .description(CLI_DESCRIPTIONS.validate)
+ .option('--all', 'Valida todas as alterações e especificações')
+ .option('--changes', 'Valida todas as alterações')
+ .option('--specs', 'Valida todas as especificações')
+ .option('--type ', 'Especifica o tipo do item quando ambíguo: change|spec')
+ .option('--strict', 'Ativa modo de validação estrita')
+ .option('--json', 'Saída dos resultados de validação como JSON')
+ .option('--concurrency ', 'Máximo de validações concorrentes (padrão: env OPENSPEC_CONCURRENCY ou 6)')
.option('--no-interactive', 'Disable interactive prompts')
.action(async (itemName?: string, options?: { all?: boolean; changes?: boolean; specs?: boolean; type?: string; strict?: boolean; json?: boolean; noInteractive?: boolean; concurrency?: string }) => {
try {
@@ -306,7 +307,7 @@ program
await validateCommand.execute(itemName, options);
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -314,17 +315,17 @@ program
// Top-level show command
program
.command('show [item-name]')
- .description('Show a change or spec')
- .option('--json', 'Output as JSON')
- .option('--type ', 'Specify item type when ambiguous: change|spec')
+ .description(CLI_DESCRIPTIONS.show)
+ .option('--json', 'Saída como JSON')
+ .option('--type ', 'Especifica o tipo do item quando ambíguo: change|spec')
.option('--no-interactive', 'Disable interactive prompts')
// change-only flags
- .option('--deltas-only', 'Show only deltas (JSON only, change)')
- .option('--requirements-only', 'Alias for --deltas-only (deprecated, change)')
+ .option('--deltas-only', 'Exibe apenas deltas (somente JSON, alteração)')
+ .option('--requirements-only', 'Alias para --deltas-only (descontinuado, alteração)')
// spec-only flags
- .option('--requirements', 'JSON only: Show only requirements (exclude scenarios)')
- .option('--no-scenarios', 'JSON only: Exclude scenario content')
- .option('-r, --requirement ', 'JSON only: Show specific requirement by ID (1-based)')
+ .option('--requirements', 'Somente JSON: Exibe apenas requisitos (exclui cenários)')
+ .option('--no-scenarios', 'Somente JSON: Exclui conteúdo de cenários')
+ .option('-r, --requirement ', 'Somente JSON: Exibe requisito específico pelo ID (base 1)')
// allow unknown options to pass-through to underlying command implementation
.allowUnknownOption(true)
.action(async (itemName?: string, options?: { json?: boolean; type?: string; noInteractive?: boolean; [k: string]: any }) => {
@@ -333,7 +334,7 @@ program
await showCommand.execute(itemName, options ?? {});
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -341,15 +342,15 @@ program
// Feedback command
program
.command('feedback ')
- .description('Submit feedback about OpenSpec')
- .option('--body ', 'Detailed description for the feedback')
+ .description(CLI_DESCRIPTIONS.feedback)
+ .option('--body ', 'Descrição detalhada do feedback')
.action(async (message: string, options?: { body?: string }) => {
try {
const feedbackCommand = new FeedbackCommand();
await feedbackCommand.execute(message, options);
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -357,48 +358,48 @@ program
// Completion command with subcommands
const completionCmd = program
.command('completion')
- .description('Manage shell completions for OpenSpec CLI');
+ .description(CLI_DESCRIPTIONS.completion);
completionCmd
.command('generate [shell]')
- .description('Generate completion script for a shell (outputs to stdout)')
+ .description(CLI_DESCRIPTIONS.completionGenerate)
.action(async (shell?: string) => {
try {
const completionCommand = new CompletionCommand();
await completionCommand.generate({ shell });
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
completionCmd
.command('install [shell]')
- .description('Install completion script for a shell')
- .option('--verbose', 'Show detailed installation output')
+ .description(CLI_DESCRIPTIONS.completionInstall)
+ .option('--verbose', 'Mostra saída detalhada da instalação')
.action(async (shell?: string, options?: { verbose?: boolean }) => {
try {
const completionCommand = new CompletionCommand();
await completionCommand.install({ shell, verbose: options?.verbose });
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
completionCmd
.command('uninstall [shell]')
- .description('Uninstall completion script for a shell')
- .option('-y, --yes', 'Skip confirmation prompts')
+ .description(CLI_DESCRIPTIONS.completionUninstall)
+ .option('-y, --yes', CONFIG_MESSAGES.skipConfirmationOption)
.action(async (shell?: string, options?: { yes?: boolean }) => {
try {
const completionCommand = new CompletionCommand();
await completionCommand.uninstall({ shell, yes: options?.yes });
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -406,7 +407,7 @@ completionCmd
// Hidden command for machine-readable completion data
program
.command('__complete ', { hidden: true })
- .description('Output completion data in machine-readable format (internal use)')
+ .description(CLI_DESCRIPTIONS.__complete)
.action(async (type: string) => {
try {
const completionCommand = new CompletionCommand();
@@ -424,16 +425,16 @@ program
// Status command
program
.command('status')
- .description('Display artifact completion status for a change')
- .option('--change ', 'Change name to show status for')
- .option('--schema ', 'Schema override (auto-detected from config.yaml)')
+ .description(CLI_DESCRIPTIONS.status)
+ .option('--change ', 'Nome da alteração para exibir o status')
+ .option('--schema ', 'Sobrescreve o esquema (auto-detectado do config.yaml)')
.option('--json', 'Output as JSON')
.action(async (options: StatusOptions) => {
try {
await statusCommand(options);
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -441,9 +442,9 @@ program
// Instructions command
program
.command('instructions [artifact]')
- .description('Output enriched instructions for creating an artifact or applying tasks')
- .option('--change ', 'Change name')
- .option('--schema ', 'Schema override (auto-detected from config.yaml)')
+ .description(CLI_DESCRIPTIONS.instructions)
+ .option('--change ', 'Nome da alteração')
+ .option('--schema ', 'Sobrescreve o esquema (auto-detectado do config.yaml)')
.option('--json', 'Output as JSON')
.action(async (artifactId: string | undefined, options: InstructionsOptions) => {
try {
@@ -455,7 +456,7 @@ program
}
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -463,15 +464,15 @@ program
// Templates command
program
.command('templates')
- .description('Show resolved template paths for all artifacts in a schema')
- .option('--schema ', `Schema to use (default: ${DEFAULT_SCHEMA})`)
- .option('--json', 'Output as JSON mapping artifact IDs to template paths')
+ .description(CLI_DESCRIPTIONS.templates)
+ .option('--schema ', `Esquema a usar (padrão: ${DEFAULT_SCHEMA})`)
+ .option('--json', 'Saída como JSON mapeando IDs de artefatos para caminhos de templates')
.action(async (options: TemplatesOptions) => {
try {
await templatesCommand(options);
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
@@ -479,32 +480,32 @@ program
// Schemas command
program
.command('schemas')
- .description('List available workflow schemas with descriptions')
- .option('--json', 'Output as JSON (for agent use)')
+ .description(CLI_DESCRIPTIONS.schemas)
+ .option('--json', 'Saída como JSON (para uso por agentes)')
.action(async (options: SchemasOptions) => {
try {
await schemasCommand(options);
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
// New command group with change subcommand
-const newCmd = program.command('new').description('Create new items');
+const newCmd = program.command('new').description(CLI_DESCRIPTIONS.new);
newCmd
.command('change ')
- .description('Create a new change directory')
- .option('--description ', 'Description to add to README.md')
- .option('--schema ', `Workflow schema to use (default: ${DEFAULT_SCHEMA})`)
+ .description(CLI_DESCRIPTIONS.newChange)
+ .option('--description ', 'Descrição a adicionar ao README.md')
+ .option('--schema ', `Esquema de fluxo de trabalho a usar (padrão: ${DEFAULT_SCHEMA})`)
.action(async (name: string, options: NewChangeOptions) => {
try {
await newChangeCommand(name, options);
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
});
diff --git a/src/commands/change.ts b/src/commands/change.ts
index 051b4697c6..26b545b10d 100644
--- a/src/commands/change.ts
+++ b/src/commands/change.ts
@@ -6,6 +6,7 @@ import { ChangeParser } from '../core/parsers/change-parser.js';
import { Change } from '../core/schemas/index.js';
import { isInteractive } from '../utils/interactive.js';
import { getActiveChangeIds } from '../utils/item-discovery.js';
+import { CHANGE_MESSAGES, UTILS_MESSAGES } from '../messages/index.js';
// Constants for better maintainability
const ARCHIVE_DIR = 'archive';
@@ -34,17 +35,17 @@ export class ChangeCommand {
if (canPrompt && changes.length > 0) {
const { select } = await import('@inquirer/prompts');
const selected = await select({
- message: 'Select a change to show',
+ message: CHANGE_MESSAGES.selectChangeToShow,
choices: changes.map(id => ({ name: id, value: id })),
});
changeName = selected;
} else {
if (changes.length === 0) {
- console.error('No change specified. No active changes found.');
+ console.error(CHANGE_MESSAGES.noChangeSpecifiedNoActive);
} else {
- console.error(`No change specified. Available IDs: ${changes.join(', ')}`);
+ console.error(CHANGE_MESSAGES.noChangeSpecifiedAvailable(changes.join(', ')));
}
- console.error('Hint: use "openspec change list" to view available changes.');
+ console.error(CHANGE_MESSAGES.hintViewChanges);
process.exitCode = 1;
return;
}
@@ -55,14 +56,14 @@ export class ChangeCommand {
try {
await fs.access(proposalPath);
} catch {
- throw new Error(`Change "${changeName}" not found at ${proposalPath}`);
+ throw new Error(CHANGE_MESSAGES.changeNotFound(changeName, proposalPath));
}
if (options?.json) {
const jsonOutput = await this.converter.convertChangeToJson(proposalPath);
if (options.requirementsOnly) {
- console.error('Flag --requirements-only is deprecated; use --deltas-only instead.');
+ console.error(CHANGE_MESSAGES.requirementsOnlyDeprecated);
}
const parsed: Change = JSON.parse(jsonOutput);
@@ -118,7 +119,7 @@ export class ChangeCommand {
} catch (error) {
// Tasks file may not exist, which is okay
if (process.env.DEBUG) {
- console.error(`Failed to read tasks file at ${tasksPath}:`, error);
+ console.error(UTILS_MESSAGES.failedToReadTasks(tasksPath, error));
}
}
@@ -143,7 +144,7 @@ export class ChangeCommand {
console.log(JSON.stringify(sorted, null, 2));
} else {
if (changes.length === 0) {
- console.log('No items found');
+ console.log(CHANGE_MESSAGES.noItemsFound);
return;
}
const sorted = [...changes].sort();
@@ -167,16 +168,16 @@ export class ChangeCommand {
taskStatusText = ` [tasks ${completed}/${total}]`;
} catch (error) {
if (process.env.DEBUG) {
- console.error(`Failed to read tasks file at ${tasksPath}:`, error);
+ console.error(UTILS_MESSAGES.failedToReadTasks(tasksPath, error));
}
}
const changeDir = path.join(changesPath, changeName);
const parser = new ChangeParser(await fs.readFile(proposalPath, 'utf-8'), changeDir);
const change = await parser.parseChangeWithDeltas(changeName);
- const deltaCountText = ` [deltas ${change.deltas.length}]`;
+ const deltaCountText = CHANGE_MESSAGES.deltas(change.deltas.length);
console.log(`${changeName}: ${title}${deltaCountText}${taskStatusText}`);
} catch {
- console.log(`${changeName}: (unable to read)`);
+ console.log(`${changeName}: ${CHANGE_MESSAGES.unableToRead}`);
}
}
}
@@ -191,17 +192,17 @@ export class ChangeCommand {
if (canPrompt && changes.length > 0) {
const { select } = await import('@inquirer/prompts');
const selected = await select({
- message: 'Select a change to validate',
+ message: CHANGE_MESSAGES.selectChangeToValidate,
choices: changes.map(id => ({ name: id, value: id })),
});
changeName = selected;
} else {
if (changes.length === 0) {
- console.error('No change specified. No active changes found.');
+ console.error(CHANGE_MESSAGES.noChangeSpecifiedNoActive);
} else {
- console.error(`No change specified. Available IDs: ${changes.join(', ')}`);
+ console.error(CHANGE_MESSAGES.noChangeSpecifiedAvailable(changes.join(', ')));
}
- console.error('Hint: use "openspec change list" to view available changes.');
+ console.error(CHANGE_MESSAGES.hintViewChanges);
process.exitCode = 1;
return;
}
@@ -212,7 +213,7 @@ export class ChangeCommand {
try {
await fs.access(changeDir);
} catch {
- throw new Error(`Change "${changeName}" not found at ${changeDir}`);
+ throw new Error(CHANGE_MESSAGES.changeNotFound(changeName, changeDir));
}
const validator = new Validator(options?.strict || false);
@@ -222,9 +223,9 @@ export class ChangeCommand {
console.log(JSON.stringify(report, null, 2));
} else {
if (report.valid) {
- console.log(`Change "${changeName}" is valid`);
+ console.log(CHANGE_MESSAGES.changeIsValid(changeName));
} else {
- console.error(`Change "${changeName}" has issues`);
+ console.error(CHANGE_MESSAGES.changeHasIssues(changeName));
report.issues.forEach(issue => {
const label = issue.level === 'ERROR' ? 'ERROR' : 'WARNING';
const prefix = issue.level === 'ERROR' ? '✗' : '⚠';
@@ -283,10 +284,10 @@ export class ChangeCommand {
private printNextSteps(): void {
const bullets: string[] = [];
- bullets.push('- Ensure change has deltas in specs/: use headers ## ADDED/MODIFIED/REMOVED/RENAMED Requirements');
- bullets.push('- Each requirement MUST include at least one #### Scenario: block');
- bullets.push('- Debug parsed deltas: openspec change show --json --deltas-only');
- console.error('Next steps:');
+ bullets.push(CHANGE_MESSAGES.ensureDeltasInSpecs);
+ bullets.push(CHANGE_MESSAGES.eachRequirementNeedsScenario);
+ bullets.push(CHANGE_MESSAGES.debugParsedDeltas);
+ console.error(CHANGE_MESSAGES.nextSteps);
bullets.forEach(b => console.error(` ${b}`));
}
}
diff --git a/src/commands/completion.ts b/src/commands/completion.ts
index bbdee7d92a..65c6d0c080 100644
--- a/src/commands/completion.ts
+++ b/src/commands/completion.ts
@@ -4,6 +4,7 @@ import { COMMAND_REGISTRY } from '../core/completions/command-registry.js';
import { detectShell, SupportedShell } from '../utils/shell-detection.js';
import { CompletionProvider } from '../core/completions/completion-provider.js';
import { getArchivedChangeIds } from '../utils/item-discovery.js';
+import { COMPLETION_MESSAGES, CLI_MESSAGES } from '../messages/index.js';
interface GenerateOptions {
shell?: string;
@@ -51,21 +52,21 @@ export class CompletionCommand {
// Shell was detected but not supported
if (detectionResult.detected && !detectionResult.shell) {
- console.error(`Error: Shell '${detectionResult.detected}' is not supported yet. Currently supported: ${CompletionFactory.getSupportedShells().join(', ')}`);
+ console.error(COMPLETION_MESSAGES.shellNotSupported(detectionResult.detected, CompletionFactory.getSupportedShells().join(', ')));
process.exitCode = 1;
return null;
}
// No shell specified and cannot auto-detect
- console.error('Error: Could not auto-detect shell. Please specify shell explicitly.');
- console.error(`Usage: openspec completion ${operationName} [shell]`);
- console.error(`Currently supported: ${CompletionFactory.getSupportedShells().join(', ')}`);
+ console.error(COMPLETION_MESSAGES.couldNotDetectShell);
+ console.error(COMPLETION_MESSAGES.usageCompletion(operationName));
+ console.error(COMPLETION_MESSAGES.currentlySupported(CompletionFactory.getSupportedShells().join(', ')));
process.exitCode = 1;
return null;
}
if (!CompletionFactory.isSupported(normalizedShell)) {
- console.error(`Error: Shell '${normalizedShell}' is not supported yet. Currently supported: ${CompletionFactory.getSupportedShells().join(', ')}`);
+ console.error(COMPLETION_MESSAGES.shellNotSupported(normalizedShell, CompletionFactory.getSupportedShells().join(', ')));
process.exitCode = 1;
return null;
}
@@ -125,7 +126,7 @@ export class CompletionCommand {
const generator = CompletionFactory.createGenerator(shell);
const installer = CompletionFactory.createInstaller(shell);
- const spinner = ora(`Installing ${shell} completion script...`).start();
+ const spinner = ora(COMPLETION_MESSAGES.installingCompletion(shell)).start();
try {
// Generate the completion script
@@ -137,12 +138,12 @@ export class CompletionCommand {
spinner.stop();
if (result.success) {
- console.log(`✓ ${result.message}`);
+ console.log(COMPLETION_MESSAGES.installSuccess(result.message));
if (verbose && result.installedPath) {
- console.log(` Installed to: ${result.installedPath}`);
+ console.log(COMPLETION_MESSAGES.installedTo(result.installedPath));
if (result.backupPath) {
- console.log(` Backup created: ${result.backupPath}`);
+ console.log(COMPLETION_MESSAGES.backupCreated(result.backupPath));
}
// Check if any shell config was updated
@@ -156,7 +157,7 @@ export class CompletionCommand {
powershell: '$PROFILE',
};
const configPath = configPaths[shell] || 'config file';
- console.log(` ${configPath} configured automatically`);
+ console.log(COMPLETION_MESSAGES.configFileConfigured(configPath));
}
}
@@ -190,16 +191,16 @@ export class CompletionCommand {
};
const reloadCmd = reloadCommands[shell] || `restart your ${shell} shell`;
- console.log(`Restart your shell or run: ${reloadCmd}`);
+ console.log(COMPLETION_MESSAGES.restartShell(reloadCmd));
}
}
} else {
- console.error(`✗ ${result.message}`);
+ console.error(COMPLETION_MESSAGES.installFailed(result.message));
process.exitCode = 1;
}
} catch (error) {
spinner.stop();
- console.error(`✗ Failed to install completion script: ${error instanceof Error ? error.message : String(error)}`);
+ console.error(COMPLETION_MESSAGES.failedToInstall(error instanceof Error ? error.message : String(error)));
process.exitCode = 1;
}
}
@@ -224,17 +225,17 @@ export class CompletionCommand {
const configPath = configPaths[shell] || `${shell} configuration`;
const confirmed = await confirm({
- message: `Remove OpenSpec configuration from ${configPath}?`,
+ message: COMPLETION_MESSAGES.removeConfigConfirm(configPath),
default: false,
});
if (!confirmed) {
- console.log('Uninstall cancelled.');
+ console.log(COMPLETION_MESSAGES.uninstallCancelled);
return;
}
}
- const spinner = ora(`Uninstalling ${shell} completion script...`).start();
+ const spinner = ora(COMPLETION_MESSAGES.uninstallingCompletion(shell)).start();
try {
const result = await installer.uninstall();
@@ -242,14 +243,14 @@ export class CompletionCommand {
spinner.stop();
if (result.success) {
- console.log(`✓ ${result.message}`);
+ console.log(COMPLETION_MESSAGES.uninstallSuccess(result.message));
} else {
- console.error(`✗ ${result.message}`);
+ console.error(COMPLETION_MESSAGES.uninstallFailed(result.message));
process.exitCode = 1;
}
} catch (error) {
spinner.stop();
- console.error(`✗ Failed to uninstall completion script: ${error instanceof Error ? error.message : String(error)}`);
+ console.error(COMPLETION_MESSAGES.failedToUninstall(error instanceof Error ? error.message : String(error)));
process.exitCode = 1;
}
}
@@ -268,21 +269,21 @@ export class CompletionCommand {
case 'changes': {
const changeIds = await this.completionProvider.getChangeIds();
for (const id of changeIds) {
- console.log(`${id}\tactive change`);
+ console.log(`${id}\t${COMPLETION_MESSAGES.activeChange}`);
}
break;
}
case 'specs': {
const specIds = await this.completionProvider.getSpecIds();
for (const id of specIds) {
- console.log(`${id}\tspecification`);
+ console.log(`${id}\t${COMPLETION_MESSAGES.specification}`);
}
break;
}
case 'archived-changes': {
const archivedIds = await getArchivedChangeIds();
for (const id of archivedIds) {
- console.log(`${id}\tarchived change`);
+ console.log(`${id}\t${COMPLETION_MESSAGES.archivedChange}`);
}
break;
}
diff --git a/src/commands/config.ts b/src/commands/config.ts
index 42c736d147..8479f5dad0 100644
--- a/src/commands/config.ts
+++ b/src/commands/config.ts
@@ -22,6 +22,7 @@ import {
import { CORE_WORKFLOWS, ALL_WORKFLOWS, getProfileWorkflows } from '../core/profiles.js';
import { OPENSPEC_DIR_NAME } from '../core/config.js';
import { hasProjectConfigDrift } from '../core/profile-sync-drift.js';
+import { CONFIG_MESSAGES, CLI_MESSAGES } from '../messages/index.js';
type ProfileAction = 'both' | 'delivery' | 'workflows' | 'keep';
@@ -43,48 +44,48 @@ interface WorkflowPromptMeta {
const WORKFLOW_PROMPT_META: Record = {
propose: {
- name: 'Propose change',
- description: 'Create proposal, design, and tasks from a request',
+ name: CONFIG_MESSAGES.workflowProposeName,
+ description: CONFIG_MESSAGES.workflowProposeDesc,
},
explore: {
- name: 'Explore ideas',
- description: 'Investigate a problem before implementation',
+ name: CONFIG_MESSAGES.workflowExploreName,
+ description: CONFIG_MESSAGES.workflowExploreDesc,
},
new: {
- name: 'New change',
- description: 'Create a new change scaffold quickly',
+ name: CONFIG_MESSAGES.workflowNewName,
+ description: CONFIG_MESSAGES.workflowNewDesc,
},
continue: {
- name: 'Continue change',
- description: 'Resume work on an existing change',
+ name: CONFIG_MESSAGES.workflowContinueName,
+ description: CONFIG_MESSAGES.workflowContinueDesc,
},
apply: {
- name: 'Apply tasks',
- description: 'Implement tasks from the current change',
+ name: CONFIG_MESSAGES.workflowApplyName,
+ description: CONFIG_MESSAGES.workflowApplyDesc,
},
ff: {
- name: 'Fast-forward',
- description: 'Run a faster implementation workflow',
+ name: CONFIG_MESSAGES.workflowFastForwardName,
+ description: CONFIG_MESSAGES.workflowFastForwardDesc,
},
sync: {
- name: 'Sync specs',
- description: 'Sync change artifacts with specs',
+ name: CONFIG_MESSAGES.workflowSyncName,
+ description: CONFIG_MESSAGES.workflowSyncDesc,
},
archive: {
- name: 'Archive change',
- description: 'Finalize and archive a completed change',
+ name: CONFIG_MESSAGES.workflowArchiveName,
+ description: CONFIG_MESSAGES.workflowArchiveDesc,
},
'bulk-archive': {
- name: 'Bulk archive',
- description: 'Archive multiple completed changes together',
+ name: CONFIG_MESSAGES.workflowBulkArchiveName,
+ description: CONFIG_MESSAGES.workflowBulkArchiveDesc,
},
verify: {
- name: 'Verify change',
- description: 'Run verification checks against a change',
+ name: CONFIG_MESSAGES.workflowVerifyName,
+ description: CONFIG_MESSAGES.workflowVerifyDesc,
},
onboard: {
- name: 'Onboard',
- description: 'Guided onboarding flow for OpenSpec',
+ name: CONFIG_MESSAGES.workflowOnboardName,
+ description: CONFIG_MESSAGES.workflowOnboardDesc,
},
};
@@ -198,7 +199,7 @@ function maybeWarnConfigDrift(
if (!hasProjectConfigDrift(projectDir, state.workflows, state.delivery)) {
return;
}
- console.log(colorize('Warning: Global config is not applied to this project. Run `openspec update` to sync.'));
+ console.log(colorize(CONFIG_MESSAGES.warningGlobalConfigNotApplied));
}
/**
@@ -209,12 +210,12 @@ function maybeWarnConfigDrift(
export function registerConfigCommand(program: Command): void {
const configCmd = program
.command('config')
- .description('View and modify global OpenSpec configuration')
- .option('--scope ', 'Config scope (only "global" supported currently)')
+ .description(CONFIG_MESSAGES.viewAndModify)
+ .option('--scope ', CONFIG_MESSAGES.configScopeOption)
.hook('preAction', (thisCommand) => {
const opts = thisCommand.opts();
if (opts.scope && opts.scope !== 'global') {
- console.error('Error: Project-local config is not yet implemented');
+ console.error(CLI_MESSAGES.projectLocalNotImplemented);
process.exit(1);
}
});
@@ -222,7 +223,7 @@ export function registerConfigCommand(program: Command): void {
// config path
configCmd
.command('path')
- .description('Show config file location')
+ .description(CONFIG_MESSAGES.showLocation)
.action(() => {
console.log(getGlobalConfigPath());
});
@@ -230,8 +231,8 @@ export function registerConfigCommand(program: Command): void {
// config list
configCmd
.command('list')
- .description('Show all current settings')
- .option('--json', 'Output as JSON')
+ .description(CONFIG_MESSAGES.showAllSettings)
+ .option('--json', CONFIG_MESSAGES.outputAsJson)
.action((options: { json?: boolean }) => {
const config = getGlobalConfig();
@@ -254,15 +255,15 @@ export function registerConfigCommand(program: Command): void {
// Annotate profile settings
const profileSource = rawConfig.profile !== undefined ? '(explicit)' : '(default)';
const deliverySource = rawConfig.delivery !== undefined ? '(explicit)' : '(default)';
- console.log(`\nProfile settings:`);
- console.log(` profile: ${config.profile} ${profileSource}`);
- console.log(` delivery: ${config.delivery} ${deliverySource}`);
+ console.log(`\n${CONFIG_MESSAGES.profileSettings}`);
+ console.log(` perfil: ${config.profile} ${profileSource}`);
+ console.log(` entrega: ${config.delivery} ${deliverySource}`);
if (config.profile === 'core') {
- console.log(` workflows: ${CORE_WORKFLOWS.join(', ')} (from core profile)`);
+ console.log(` fluxos: ${CORE_WORKFLOWS.join(', ')} (do perfil core)`);
} else if (config.workflows && config.workflows.length > 0) {
- console.log(` workflows: ${config.workflows.join(', ')} (explicit)`);
+ console.log(` fluxos: ${config.workflows.join(', ')} (explícito)`);
} else {
- console.log(` workflows: (none)`);
+ console.log(` fluxos: (nenhum)`);
}
}
});
@@ -270,7 +271,7 @@ export function registerConfigCommand(program: Command): void {
// config get
configCmd
.command('get ')
- .description('Get a specific value (raw, scriptable)')
+ .description(CONFIG_MESSAGES.getValue)
.action((key: string) => {
const config = getGlobalConfig();
const value = getNestedValue(config as Record, key);
@@ -290,17 +291,17 @@ export function registerConfigCommand(program: Command): void {
// config set
configCmd
.command('set ')
- .description('Set a value (auto-coerce types)')
- .option('--string', 'Force value to be stored as string')
- .option('--allow-unknown', 'Allow setting unknown keys')
+ .description(CONFIG_MESSAGES.setValue)
+ .option('--string', CONFIG_MESSAGES.forceStringOption)
+ .option('--allow-unknown', CONFIG_MESSAGES.allowUnknownOption)
.action((key: string, value: string, options: { string?: boolean; allowUnknown?: boolean }) => {
const allowUnknown = Boolean(options.allowUnknown);
const keyValidation = validateConfigKeyPath(key);
if (!keyValidation.valid && !allowUnknown) {
const reason = keyValidation.reason ? ` ${keyValidation.reason}.` : '';
- console.error(`Error: Invalid configuration key "${key}".${reason}`);
- console.error('Use "openspec config list" to see available keys.');
- console.error('Pass --allow-unknown to bypass this check.');
+ console.error(CONFIG_MESSAGES.invalidConfigKey(key, reason));
+ console.error(CONFIG_MESSAGES.useConfigList);
+ console.error(CONFIG_MESSAGES.passAllowUnknown);
process.exitCode = 1;
return;
}
@@ -315,7 +316,7 @@ export function registerConfigCommand(program: Command): void {
// Validate the new config
const validation = validateConfig(newConfig);
if (!validation.success) {
- console.error(`Error: Invalid configuration - ${validation.error}`);
+ console.error(CONFIG_MESSAGES.invalidConfiguration(validation.error!));
process.exitCode = 1;
return;
}
@@ -326,35 +327,35 @@ export function registerConfigCommand(program: Command): void {
const displayValue =
typeof coercedValue === 'string' ? `"${coercedValue}"` : String(coercedValue);
- console.log(`Set ${key} = ${displayValue}`);
+ console.log(CONFIG_MESSAGES.setKeyValue(key, displayValue));
});
// config unset
configCmd
.command('unset ')
- .description('Remove a key (revert to default)')
+ .description(CONFIG_MESSAGES.removeKey)
.action((key: string) => {
const config = getGlobalConfig() as Record;
const existed = deleteNestedValue(config, key);
if (existed) {
saveGlobalConfig(config as GlobalConfig);
- console.log(`Unset ${key} (reverted to default)`);
+ console.log(CONFIG_MESSAGES.unsetKey(key));
} else {
- console.log(`Key "${key}" was not set`);
+ console.log(CONFIG_MESSAGES.keyNotSet(key));
}
});
// config reset
configCmd
.command('reset')
- .description('Reset configuration to defaults')
- .option('--all', 'Reset all configuration (required)')
- .option('-y, --yes', 'Skip confirmation prompts')
+ .description(CONFIG_MESSAGES.resetConfig)
+ .option('--all', CONFIG_MESSAGES.resetAllOption)
+ .option('-y, --yes', CONFIG_MESSAGES.skipConfirmationOption)
.action(async (options: { all?: boolean; yes?: boolean }) => {
if (!options.all) {
- console.error('Error: --all flag is required for reset');
- console.error('Usage: openspec config reset --all [-y]');
+ console.error(CONFIG_MESSAGES.resetAllRequired);
+ console.error(CONFIG_MESSAGES.resetUsage);
process.exitCode = 1;
return;
}
@@ -364,12 +365,12 @@ export function registerConfigCommand(program: Command): void {
let confirmed: boolean;
try {
confirmed = await confirm({
- message: 'Reset all configuration to defaults?',
+ message: CONFIG_MESSAGES.resetConfirm,
default: false,
});
} catch (error) {
if (isPromptCancellationError(error)) {
- console.log('Reset cancelled.');
+ console.log(CONFIG_MESSAGES.resetCancelled);
process.exitCode = 130;
return;
}
@@ -377,26 +378,26 @@ export function registerConfigCommand(program: Command): void {
}
if (!confirmed) {
- console.log('Reset cancelled.');
+ console.log(CONFIG_MESSAGES.resetCancelled);
return;
}
}
saveGlobalConfig({ ...DEFAULT_CONFIG });
- console.log('Configuration reset to defaults');
+ console.log(CONFIG_MESSAGES.configurationReset);
});
// config edit
configCmd
.command('edit')
- .description('Open config in $EDITOR')
+ .description(CONFIG_MESSAGES.openInEditor)
.action(async () => {
const editor = process.env.EDITOR || process.env.VISUAL;
if (!editor) {
- console.error('Error: No editor configured');
- console.error('Set the EDITOR or VISUAL environment variable to your preferred editor');
- console.error('Example: export EDITOR=vim');
+ console.error(CONFIG_MESSAGES.noEditorConfigured);
+ console.error(CONFIG_MESSAGES.setEditorEnv);
+ console.error(CONFIG_MESSAGES.editorExample);
process.exitCode = 1;
return;
}
@@ -433,17 +434,17 @@ export function registerConfigCommand(program: Command): void {
const validation = validateConfig(parsedConfig);
if (!validation.success) {
- console.error(`Error: Invalid configuration - ${validation.error}`);
+ console.error(CONFIG_MESSAGES.invalidConfiguration(validation.error!));
process.exitCode = 1;
}
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
- console.error(`Error: Config file not found at ${configPath}`);
+ console.error(CONFIG_MESSAGES.configFileNotFound(configPath));
} else if (error instanceof SyntaxError) {
- console.error(`Error: Invalid JSON in ${configPath}`);
+ console.error(CONFIG_MESSAGES.invalidJson(configPath));
console.error(error.message);
} else {
- console.error(`Error: Unable to validate configuration - ${error instanceof Error ? error.message : String(error)}`);
+ console.error(CONFIG_MESSAGES.unableToValidateConfig(error instanceof Error ? error.message : String(error)));
}
process.exitCode = 1;
}
@@ -452,7 +453,7 @@ export function registerConfigCommand(program: Command): void {
// config profile [preset]
configCmd
.command('profile [preset]')
- .description('Configure workflow profile (interactive picker or preset shortcut)')
+ .description(CONFIG_MESSAGES.configureProfile)
.action(async (preset?: string) => {
// Preset shortcut: `openspec config profile core`
if (preset === 'core') {
@@ -461,19 +462,19 @@ export function registerConfigCommand(program: Command): void {
config.workflows = [...CORE_WORKFLOWS];
// Preserve delivery setting
saveGlobalConfig(config);
- console.log('Config updated. Run `openspec update` in your projects to apply.');
+ console.log(CONFIG_MESSAGES.configUpdated);
return;
}
if (preset) {
- console.error(`Error: Unknown profile preset "${preset}". Available presets: core`);
+ console.error(CONFIG_MESSAGES.unknownProfilePreset(preset));
process.exitCode = 1;
return;
}
// Non-interactive check
if (!process.stdout.isTTY) {
- console.error('Interactive mode required. Use `openspec config profile core` or set config via environment/flags.');
+ console.error(CONFIG_MESSAGES.interactiveModeRequired);
process.exitCode = 1;
return;
}
@@ -486,41 +487,41 @@ export function registerConfigCommand(program: Command): void {
const config = getGlobalConfig();
const currentState = resolveCurrentProfileState(config);
- console.log(chalk.bold('\nCurrent profile settings'));
- console.log(` Delivery: ${currentState.delivery}`);
- console.log(` Workflows: ${formatWorkflowSummary(currentState.workflows, currentState.profile)}`);
- console.log(chalk.dim(' Delivery = where workflows are installed (skills, commands, or both)'));
- console.log(chalk.dim(' Workflows = which actions are available (propose, explore, apply, etc.)'));
+ console.log(chalk.bold('\n' + CONFIG_MESSAGES.currentProfileSettings));
+ console.log(CONFIG_MESSAGES.deliveryLabel(currentState.delivery));
+ console.log(CONFIG_MESSAGES.workflowsLabel(formatWorkflowSummary(currentState.workflows, currentState.profile)));
+ console.log(chalk.dim(CONFIG_MESSAGES.deliveryHelp));
+ console.log(chalk.dim(CONFIG_MESSAGES.workflowsHelp));
console.log();
const action = await select({
- message: 'What do you want to configure?',
+ message: CONFIG_MESSAGES.whatToConfigure,
choices: [
{
value: 'both',
- name: 'Delivery and workflows',
- description: 'Update install mode and available actions together',
+ name: CONFIG_MESSAGES.deliveryAndWorkflows,
+ description: CONFIG_MESSAGES.deliveryAndWorkflowsDesc,
},
{
value: 'delivery',
- name: 'Delivery only',
- description: 'Change where workflows are installed',
+ name: CONFIG_MESSAGES.deliveryOnly,
+ description: CONFIG_MESSAGES.deliveryOnlyDesc,
},
{
value: 'workflows',
- name: 'Workflows only',
- description: 'Change which workflow actions are available',
+ name: CONFIG_MESSAGES.workflowsOnly,
+ description: CONFIG_MESSAGES.workflowsOnlyDesc,
},
{
value: 'keep',
- name: 'Keep current settings (exit)',
- description: 'Leave configuration unchanged and exit',
+ name: CONFIG_MESSAGES.keepCurrentSettings,
+ description: CONFIG_MESSAGES.keepCurrentSettingsDesc,
},
],
});
if (action === 'keep') {
- console.log('No config changes.');
+ console.log(CONFIG_MESSAGES.noConfigChanges);
maybeWarnConfigDrift(process.cwd(), currentState, chalk.yellow);
return;
}
@@ -535,28 +536,28 @@ export function registerConfigCommand(program: Command): void {
const deliveryChoices: { value: Delivery; name: string; description: string }[] = [
{
value: 'both' as Delivery,
- name: 'Both (skills + commands)',
- description: 'Install workflows as both skills and slash commands',
+ name: CONFIG_MESSAGES.bothSkillsAndCommands,
+ description: CONFIG_MESSAGES.bothSkillsAndCommandsDesc,
},
{
value: 'skills' as Delivery,
- name: 'Skills only',
- description: 'Install workflows only as skills',
+ name: CONFIG_MESSAGES.skillsOnly,
+ description: CONFIG_MESSAGES.skillsOnlyDesc,
},
{
value: 'commands' as Delivery,
- name: 'Commands only',
- description: 'Install workflows only as slash commands',
+ name: CONFIG_MESSAGES.commandsOnly,
+ description: CONFIG_MESSAGES.commandsOnlyDesc,
},
];
for (const choice of deliveryChoices) {
if (choice.value === currentState.delivery) {
- choice.name += ' [current]';
+ choice.name += CONFIG_MESSAGES.currentSuffix;
}
}
nextState.delivery = await select({
- message: 'Delivery mode (how workflows are installed):',
+ message: CONFIG_MESSAGES.deliveryMode,
choices: deliveryChoices,
default: currentState.delivery,
});
@@ -578,8 +579,8 @@ export function registerConfigCommand(program: Command): void {
};
const selectedWorkflows = await checkbox({
- message: 'Select workflows to make available:',
- instructions: 'Space to toggle, Enter to confirm',
+ message: CONFIG_MESSAGES.selectWorkflows,
+ instructions: CONFIG_MESSAGES.spaceToToggle,
pageSize: ALL_WORKFLOWS.length,
theme: {
icon: {
@@ -595,12 +596,12 @@ export function registerConfigCommand(program: Command): void {
const diff = diffProfileState(currentState, nextState);
if (!diff.hasChanges) {
- console.log('No config changes.');
+ console.log(CONFIG_MESSAGES.noConfigChanges);
maybeWarnConfigDrift(process.cwd(), nextState, chalk.yellow);
return;
}
- console.log(chalk.bold('\nConfig changes:'));
+ console.log(chalk.bold('\n' + CONFIG_MESSAGES.configChanges));
for (const line of diff.lines) {
console.log(` ${line}`);
}
@@ -616,26 +617,26 @@ export function registerConfigCommand(program: Command): void {
const openspecDir = path.join(projectDir, OPENSPEC_DIR_NAME);
if (fs.existsSync(openspecDir)) {
const applyNow = await confirm({
- message: 'Apply changes to this project now?',
+ message: CONFIG_MESSAGES.applyChangesNow,
default: true,
});
if (applyNow) {
try {
execSync('npx openspec update', { stdio: 'inherit', cwd: projectDir });
- console.log('Run `openspec update` in your other projects to apply.');
+ console.log(CONFIG_MESSAGES.configUpdated);
} catch {
- console.error('`openspec update` failed. Please run it manually to apply the profile changes.');
+ console.error(CONFIG_MESSAGES.updateFailed);
process.exitCode = 1;
}
return;
}
}
- console.log('Config updated. Run `openspec update` in your projects to apply.');
+ console.log(CONFIG_MESSAGES.configUpdated);
} catch (error) {
if (isPromptCancellationError(error)) {
- console.log('Config profile cancelled.');
+ console.log(CONFIG_MESSAGES.configProfileCancelled);
process.exitCode = 130;
return;
}
diff --git a/src/commands/feedback.ts b/src/commands/feedback.ts
index 2dd5a00db7..fc7bcc0178 100644
--- a/src/commands/feedback.ts
+++ b/src/commands/feedback.ts
@@ -1,6 +1,7 @@
import { execSync, execFileSync } from 'child_process';
import { createRequire } from 'module';
import os from 'os';
+import { FEEDBACK_MESSAGES } from '../messages/index.js';
const require = createRequire(import.meta.url);
@@ -65,17 +66,17 @@ function generateMetadata(): string {
const timestamp = getTimestamp();
return `---
-Submitted via OpenSpec CLI
-- Version: ${version}
-- Platform: ${platform}
-- Timestamp: ${timestamp}`;
+${FEEDBACK_MESSAGES.submittedVia}
+${FEEDBACK_MESSAGES.versionLabel(version)}
+${FEEDBACK_MESSAGES.platformLabel(platform)}
+${FEEDBACK_MESSAGES.timestampLabel(timestamp)}`;
}
/**
* Format the feedback title
*/
function formatTitle(message: string): string {
- return `Feedback: ${message}`;
+ return FEEDBACK_MESSAGES.feedbackTitle(message);
}
/**
@@ -110,12 +111,12 @@ function generateManualSubmissionUrl(title: string, body: string): string {
* Display formatted feedback content for manual submission
*/
function displayFormattedFeedback(title: string, body: string): void {
- console.log('\n--- FORMATTED FEEDBACK ---');
- console.log(`Title: ${title}`);
- console.log(`Labels: feedback`);
- console.log('\nBody:');
+ console.log(FEEDBACK_MESSAGES.formattedFeedbackHeader);
+ console.log(FEEDBACK_MESSAGES.titleLabel(title));
+ console.log(FEEDBACK_MESSAGES.labelsFeedback);
+ console.log(FEEDBACK_MESSAGES.bodyLabel);
console.log(body);
- console.log('--- END FEEDBACK ---\n');
+ console.log(FEEDBACK_MESSAGES.endFeedback);
}
/**
@@ -142,8 +143,8 @@ function submitViaGhCli(title: string, body: string): void {
);
const issueUrl = result.trim();
- console.log(`\n✓ Feedback submitted successfully!`);
- console.log(`Issue URL: ${issueUrl}\n`);
+ console.log(FEEDBACK_MESSAGES.feedbackSubmitted);
+ console.log(FEEDBACK_MESSAGES.issueUrl(issueUrl));
} catch (error: any) {
// Display the error output from gh CLI
if (error.stderr) {
@@ -162,19 +163,19 @@ function submitViaGhCli(title: string, body: string): void {
*/
function handleFallback(title: string, body: string, reason: 'missing' | 'unauthenticated'): void {
if (reason === 'missing') {
- console.log('⚠️ GitHub CLI not found. Manual submission required.');
+ console.log(FEEDBACK_MESSAGES.githubCliNotFound);
} else {
- console.log('⚠️ GitHub authentication required. Manual submission required.');
+ console.log(FEEDBACK_MESSAGES.githubAuthRequired);
}
displayFormattedFeedback(title, body);
const manualUrl = generateManualSubmissionUrl(title, body);
- console.log('Please submit your feedback manually:');
+ console.log(FEEDBACK_MESSAGES.submitManually);
console.log(manualUrl);
if (reason === 'unauthenticated') {
- console.log('\nTo auto-submit in the future: gh auth login');
+ console.log(FEEDBACK_MESSAGES.autoSubmitHint);
}
// Exit with success code (fallback is successful)
diff --git a/src/commands/schema.ts b/src/commands/schema.ts
index 7f8d0b7888..b20aa395b7 100644
--- a/src/commands/schema.ts
+++ b/src/commands/schema.ts
@@ -12,6 +12,7 @@ import {
} from '../core/artifact-graph/resolver.js';
import { parseSchema, SchemaValidationError } from '../core/artifact-graph/schema.js';
import type { SchemaYaml, Artifact } from '../core/artifact-graph/types.js';
+import { SCHEMA_MESSAGES, CLI_MESSAGES, CONFIG_MESSAGES } from '../messages/index.js';
/**
* Schema source location type
@@ -144,20 +145,20 @@ function validateSchema(
// Check schema.yaml exists
if (verbose) {
- console.log(' Checking schema.yaml exists...');
+ console.log(SCHEMA_MESSAGES.checkingSchemaExists);
}
if (!fs.existsSync(schemaPath)) {
issues.push({
level: 'error',
path: 'schema.yaml',
- message: 'schema.yaml not found',
+ message: SCHEMA_MESSAGES.schemaNotFound,
});
return { valid: false, issues };
}
// Parse YAML
if (verbose) {
- console.log(' Parsing YAML...');
+ console.log(SCHEMA_MESSAGES.parsingYaml);
}
let content: string;
try {
@@ -166,14 +167,14 @@ function validateSchema(
issues.push({
level: 'error',
path: 'schema.yaml',
- message: `Failed to read file: ${(err as Error).message}`,
+ message: SCHEMA_MESSAGES.failedToReadFile((err as Error).message),
});
return { valid: false, issues };
}
// Validate against Zod schema
if (verbose) {
- console.log(' Validating schema structure...');
+ console.log(SCHEMA_MESSAGES.validatingSchemaStructure);
}
let schema: SchemaYaml;
try {
@@ -189,7 +190,7 @@ function validateSchema(
issues.push({
level: 'error',
path: 'schema.yaml',
- message: `Parse error: ${(err as Error).message}`,
+ message: SCHEMA_MESSAGES.parseError((err as Error).message),
});
}
return { valid: false, issues };
@@ -198,7 +199,7 @@ function validateSchema(
// Check template files exist
// Templates can be in schemaDir directly or in a templates/ subdirectory
if (verbose) {
- console.log(' Checking template files...');
+ console.log(SCHEMA_MESSAGES.checkingTemplateFiles);
}
for (const artifact of schema.artifacts) {
// Try templates subdirectory first (standard location), then root
@@ -209,7 +210,7 @@ function validateSchema(
issues.push({
level: 'error',
path: `artifacts.${artifact.id}.template`,
- message: `Template file '${artifact.template}' not found for artifact '${artifact.id}'`,
+ message: SCHEMA_MESSAGES.templateNotFound(artifact.template, artifact.id),
});
}
}
@@ -217,7 +218,7 @@ function validateSchema(
// Dependency graph validation is already done by parseSchema
// (it throws on cycles and invalid references)
if (verbose) {
- console.log(' Dependency graph validation passed (via parseSchema)');
+ console.log(SCHEMA_MESSAGES.dependencyGraphPassed);
}
return { valid: issues.length === 0, issues };
@@ -290,19 +291,19 @@ const DEFAULT_ARTIFACTS: Array<{
export function registerSchemaCommand(program: Command): void {
const schemaCmd = program
.command('schema')
- .description('Manage workflow schemas [experimental]');
+ .description(SCHEMA_MESSAGES.manageWorkflows);
// Experimental warning
schemaCmd.hook('preAction', () => {
- console.error('Note: Schema commands are experimental and may change.');
+ console.error(SCHEMA_MESSAGES.experimentalWarning);
});
// schema which
schemaCmd
.command('which [name]')
- .description('Show where a schema resolves from')
- .option('--json', 'Output as JSON')
- .option('--all', 'List all schemas with their resolution sources')
+ .description(SCHEMA_MESSAGES.showResolve)
+ .option('--json', SCHEMA_MESSAGES.outputAsJson)
+ .option('--all', SCHEMA_MESSAGES.listAllSchemasOption)
.action(async (name?: string, options?: { json?: boolean; all?: boolean }) => {
try {
const projectRoot = process.cwd();
@@ -315,7 +316,7 @@ export function registerSchemaCommand(program: Command): void {
console.log(JSON.stringify(schemas, null, 2));
} else {
if (schemas.length === 0) {
- console.log('No schemas found.');
+ console.log(SCHEMA_MESSAGES.noSchemasFound);
return;
}
@@ -327,27 +328,27 @@ export function registerSchemaCommand(program: Command): void {
};
if (bySource.project.length > 0) {
- console.log('\nProject schemas:');
+ console.log('\n' + SCHEMA_MESSAGES.projectSchemasHeader);
for (const schema of bySource.project) {
const shadowInfo = schema.shadows.length > 0
- ? ` (shadows: ${schema.shadows.map((s) => s.source).join(', ')})`
+ ? SCHEMA_MESSAGES.shadowsLabel(schema.shadows.map((s) => s.source).join(', '))
: '';
console.log(` ${schema.name}${shadowInfo}`);
}
}
if (bySource.user.length > 0) {
- console.log('\nUser schemas:');
+ console.log('\n' + SCHEMA_MESSAGES.userSchemasHeader);
for (const schema of bySource.user) {
const shadowInfo = schema.shadows.length > 0
- ? ` (shadows: ${schema.shadows.map((s) => s.source).join(', ')})`
+ ? SCHEMA_MESSAGES.shadowsLabel(schema.shadows.map((s) => s.source).join(', '))
: '';
console.log(` ${schema.name}${shadowInfo}`);
}
}
if (bySource.package.length > 0) {
- console.log('\nPackage schemas:');
+ console.log('\n' + SCHEMA_MESSAGES.packageSchemasHeader);
for (const schema of bySource.package) {
console.log(` ${schema.name}`);
}
@@ -357,7 +358,7 @@ export function registerSchemaCommand(program: Command): void {
}
if (!name) {
- console.error('Error: Schema name is required (or use --all to list all schemas)');
+ console.error(SCHEMA_MESSAGES.schemaNameRequired);
process.exitCode = 1;
return;
}
@@ -368,12 +369,12 @@ export function registerSchemaCommand(program: Command): void {
const available = listSchemas(projectRoot);
if (options?.json) {
console.log(JSON.stringify({
- error: `Schema '${name}' not found`,
+ error: SCHEMA_MESSAGES.schemaNotFoundError(name),
available,
}, null, 2));
} else {
- console.error(`Error: Schema '${name}' not found`);
- console.error(`Available schemas: ${available.join(', ')}`);
+ console.error(SCHEMA_MESSAGES.schemaNotFoundError(name));
+ console.error(SCHEMA_MESSAGES.availableSchemas(available.join(', ')));
}
process.exitCode = 1;
return;
@@ -382,19 +383,19 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify(resolution, null, 2));
} else {
- console.log(`Schema: ${resolution.name}`);
- console.log(`Source: ${resolution.source}`);
- console.log(`Path: ${resolution.path}`);
+ console.log(SCHEMA_MESSAGES.schemaLabel(resolution.name));
+ console.log(SCHEMA_MESSAGES.sourceLabel(resolution.source));
+ console.log(SCHEMA_MESSAGES.pathLabel(resolution.path));
if (resolution.shadows.length > 0) {
- console.log('\nShadows:');
+ console.log('\n' + SCHEMA_MESSAGES.shadowsHeader);
for (const shadow of resolution.shadows) {
- console.log(` ${shadow.source}: ${shadow.path}`);
+ console.log(SCHEMA_MESSAGES.shadowEntry(shadow.source, shadow.path));
}
}
}
} catch (error) {
- console.error(`Error: ${(error as Error).message}`);
+ console.error(CLI_MESSAGES.error((error as Error).message));
process.exitCode = 1;
}
});
@@ -402,9 +403,9 @@ export function registerSchemaCommand(program: Command): void {
// schema validate
schemaCmd
.command('validate [name]')
- .description('Validate a schema structure and templates')
- .option('--json', 'Output as JSON')
- .option('--verbose', 'Show detailed validation steps')
+ .description(SCHEMA_MESSAGES.validateStructure)
+ .option('--json', SCHEMA_MESSAGES.outputAsJson)
+ .option('--verbose', SCHEMA_MESSAGES.verboseOption)
.action(async (name?: string, options?: { json?: boolean; verbose?: boolean }) => {
try {
const projectRoot = process.cwd();
@@ -417,11 +418,11 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
valid: true,
- message: 'No project schemas directory found',
+ message: SCHEMA_MESSAGES.noProjectSchemasDir,
schemas: [],
}, null, 2));
} else {
- console.log('No project schemas directory found.');
+ console.log(SCHEMA_MESSAGES.noProjectSchemasDir + '.');
}
return;
}
@@ -445,7 +446,7 @@ export function registerSchemaCommand(program: Command): void {
if (!fs.existsSync(schemaPath)) continue;
if (options?.verbose && !options?.json) {
- console.log(`\nValidating ${entry.name}...`);
+ console.log('\n' + SCHEMA_MESSAGES.validatingEntry(entry.name));
}
const result = validateSchema(schemaDir, options?.verbose && !options?.json);
@@ -468,16 +469,15 @@ export function registerSchemaCommand(program: Command): void {
}, null, 2));
} else {
if (schemaResults.length === 0) {
- console.log('No schemas found in project.');
+ console.log(SCHEMA_MESSAGES.noSchemasInProject);
return;
}
- console.log('\nValidation Results:');
+ console.log('\n' + SCHEMA_MESSAGES.validationResultsHeader);
for (const result of schemaResults) {
- const status = result.valid ? '✓' : '✗';
- console.log(` ${status} ${result.name}`);
+ console.log(SCHEMA_MESSAGES.validationStatus(result.valid, result.name));
for (const issue of result.issues) {
- console.log(` ${issue.level}: ${issue.message}`);
+ console.log(SCHEMA_MESSAGES.issueLine(issue.level, issue.message));
}
}
@@ -496,19 +496,19 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
valid: false,
- error: `Schema '${name}' not found`,
+ error: SCHEMA_MESSAGES.schemaNotFoundError(name),
available,
}, null, 2));
} else {
- console.error(`Error: Schema '${name}' not found`);
- console.error(`Available schemas: ${available.join(', ')}`);
+ console.error(SCHEMA_MESSAGES.schemaNotFoundError(name));
+ console.error(SCHEMA_MESSAGES.availableSchemas(available.join(', ')));
}
process.exitCode = 1;
return;
}
if (options?.verbose && !options?.json) {
- console.log(`Validating ${name}...`);
+ console.log(SCHEMA_MESSAGES.validatingEntry(name));
}
const result = validateSchema(schemaDir, options?.verbose && !options?.json);
@@ -522,11 +522,11 @@ export function registerSchemaCommand(program: Command): void {
}, null, 2));
} else {
if (result.valid) {
- console.log(`✓ Schema '${name}' is valid`);
+ console.log(SCHEMA_MESSAGES.schemaIsValid(name));
} else {
- console.log(`✗ Schema '${name}' has errors:`);
+ console.log(SCHEMA_MESSAGES.schemaHasErrors(name));
for (const issue of result.issues) {
- console.log(` ${issue.level}: ${issue.message}`);
+ console.log(SCHEMA_MESSAGES.issueLine(issue.level, issue.message));
}
process.exitCode = 1;
}
@@ -538,7 +538,7 @@ export function registerSchemaCommand(program: Command): void {
error: (error as Error).message,
}, null, 2));
} else {
- console.error(`Error: ${(error as Error).message}`);
+ console.error(CLI_MESSAGES.error((error as Error).message));
}
process.exitCode = 1;
}
@@ -547,9 +547,9 @@ export function registerSchemaCommand(program: Command): void {
// schema fork
schemaCmd
.command('fork [name]')
- .description('Copy an existing schema to project for customization')
- .option('--json', 'Output as JSON')
- .option('--force', 'Overwrite existing destination')
+ .description(SCHEMA_MESSAGES.copySchema)
+ .option('--json', SCHEMA_MESSAGES.outputAsJson)
+ .option('--force', SCHEMA_MESSAGES.forceOption)
.action(async (source: string, name?: string, options?: { json?: boolean; force?: boolean }) => {
const spinner = options?.json ? null : ora();
@@ -562,11 +562,11 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
forked: false,
- error: `Invalid schema name '${destinationName}'. Use kebab-case (e.g., my-workflow)`,
+ error: SCHEMA_MESSAGES.invalidSchemaName(destinationName),
}, null, 2));
} else {
- console.error(`Error: Invalid schema name '${destinationName}'`);
- console.error('Schema names must be kebab-case (e.g., my-workflow)');
+ console.error(SCHEMA_MESSAGES.invalidSchemaName(destinationName).replace(/^Nome/, 'Erro: Nome'));
+ console.error(SCHEMA_MESSAGES.schemaNamesKebabCase);
}
process.exitCode = 1;
return;
@@ -579,12 +579,12 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
forked: false,
- error: `Schema '${source}' not found`,
+ error: SCHEMA_MESSAGES.schemaSourceNotFound(source),
available,
}, null, 2));
} else {
- console.error(`Error: Schema '${source}' not found`);
- console.error(`Available schemas: ${available.join(', ')}`);
+ console.error(SCHEMA_MESSAGES.schemaNotFoundError(source).replace(/^Esquema/, 'Erro: Esquema'));
+ console.error(SCHEMA_MESSAGES.availableSchemas(available.join(', ')));
}
process.exitCode = 1;
return;
@@ -602,24 +602,24 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
forked: false,
- error: `Schema '${destinationName}' already exists`,
- suggestion: 'Use --force to overwrite',
+ error: SCHEMA_MESSAGES.schemaAlreadyExists(destinationName),
+ suggestion: SCHEMA_MESSAGES.suggestionForceOverwrite,
}, null, 2));
} else {
- console.error(`Error: Schema '${destinationName}' already exists at ${destinationDir}`);
- console.error('Use --force to overwrite');
+ console.error(SCHEMA_MESSAGES.schemaAlreadyExistsAt(destinationName, destinationDir));
+ console.error(SCHEMA_MESSAGES.suggestionForceOverwrite);
}
process.exitCode = 1;
return;
}
// Remove existing
- if (spinner) spinner.start(`Removing existing schema '${destinationName}'...`);
+ if (spinner) spinner.start(SCHEMA_MESSAGES.removingExistingSchema(destinationName));
fs.rmSync(destinationDir, { recursive: true });
}
// Copy schema
- if (spinner) spinner.start(`Forking '${source}' to '${destinationName}'...`);
+ if (spinner) spinner.start(SCHEMA_MESSAGES.forkingSchema(source, destinationName));
copyDirRecursive(sourceDir, destinationDir);
// Update name in schema.yaml
@@ -630,7 +630,7 @@ export function registerSchemaCommand(program: Command): void {
fs.writeFileSync(destSchemaPath, stringifyYaml(schema));
- if (spinner) spinner.succeed(`Forked '${source}' to '${destinationName}'`);
+ if (spinner) spinner.succeed(SCHEMA_MESSAGES.forkedSchema(source, destinationName));
if (options?.json) {
console.log(JSON.stringify({
@@ -642,20 +642,20 @@ export function registerSchemaCommand(program: Command): void {
destinationPath: destinationDir,
}, null, 2));
} else {
- console.log(`\nSource: ${sourceDir} (${sourceLocation})`);
- console.log(`Destination: ${destinationDir}`);
- console.log(`\nYou can now customize the schema at:`);
+ console.log('\n' + SCHEMA_MESSAGES.sourceLabel2(sourceDir, sourceLocation));
+ console.log(SCHEMA_MESSAGES.destinationLabel(destinationDir));
+ console.log('\n' + SCHEMA_MESSAGES.customizeSchemaAt);
console.log(` ${destinationDir}/schema.yaml`);
}
} catch (error) {
- if (spinner) spinner.fail(`Fork failed`);
+ if (spinner) spinner.fail(SCHEMA_MESSAGES.forkFailed);
if (options?.json) {
console.log(JSON.stringify({
forked: false,
error: (error as Error).message,
}, null, 2));
} else {
- console.error(`Error: ${(error as Error).message}`);
+ console.error(CLI_MESSAGES.error((error as Error).message));
}
process.exitCode = 1;
}
@@ -664,13 +664,13 @@ export function registerSchemaCommand(program: Command): void {
// schema init
schemaCmd
.command('init ')
- .description('Create a new project-local schema')
- .option('--json', 'Output as JSON')
- .option('--description ', 'Schema description')
+ .description(SCHEMA_MESSAGES.createSchema)
+ .option('--json', SCHEMA_MESSAGES.outputAsJson)
+ .option('--description ', SCHEMA_MESSAGES.descriptionOption)
.option('--artifacts ', 'Comma-separated artifact IDs (proposal,specs,design,tasks)')
- .option('--default', 'Set as project default schema')
- .option('--no-default', 'Do not prompt to set as default')
- .option('--force', 'Overwrite existing schema')
+ .option('--default', SCHEMA_MESSAGES.defaultOption)
+ .option('--no-default', SCHEMA_MESSAGES.noDefaultOption)
+ .option('--force', SCHEMA_MESSAGES.forceOption2)
.action(async (
name: string,
options?: {
@@ -691,11 +691,11 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
created: false,
- error: `Invalid schema name '${name}'. Use kebab-case (e.g., my-workflow)`,
+ error: SCHEMA_MESSAGES.invalidSchemaName(name),
}, null, 2));
} else {
- console.error(`Error: Invalid schema name '${name}'`);
- console.error('Schema names must be kebab-case (e.g., my-workflow)');
+ console.error(SCHEMA_MESSAGES.invalidSchemaName(name).replace(/^Nome/, 'Erro: Nome'));
+ console.error(SCHEMA_MESSAGES.schemaNamesKebabCase);
}
process.exitCode = 1;
return;
@@ -709,18 +709,18 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
created: false,
- error: `Schema '${name}' already exists`,
- suggestion: 'Use --force to overwrite or "openspec schema fork" to copy',
+ error: SCHEMA_MESSAGES.schemaAlreadyExists(name),
+ suggestion: SCHEMA_MESSAGES.suggestionForkOrForce,
}, null, 2));
} else {
- console.error(`Error: Schema '${name}' already exists at ${schemaDir}`);
- console.error('Use --force to overwrite or "openspec schema fork" to copy');
+ console.error(SCHEMA_MESSAGES.schemaAlreadyExistsAt(name, schemaDir));
+ console.error(SCHEMA_MESSAGES.suggestionForkOrForce);
}
process.exitCode = 1;
return;
}
- if (spinner) spinner.start(`Removing existing schema '${name}'...`);
+ if (spinner) spinner.start(SCHEMA_MESSAGES.removingExistingSchema(name));
fs.rmSync(schemaDir, { recursive: true });
}
@@ -737,7 +737,7 @@ export function registerSchemaCommand(program: Command): void {
const { input, checkbox, confirm } = await import('@inquirer/prompts');
description = await input({
- message: 'Schema description:',
+ message: CONFIG_MESSAGES.schemaDescription,
default: `Custom workflow schema for ${name}`,
});
@@ -748,12 +748,12 @@ export function registerSchemaCommand(program: Command): void {
}));
selectedArtifactIds = await checkbox({
- message: 'Select artifacts to include:',
+ message: CONFIG_MESSAGES.selectArtifacts,
choices: artifactChoices,
});
if (selectedArtifactIds.length === 0) {
- console.error('Error: At least one artifact must be selected');
+ console.error(SCHEMA_MESSAGES.atLeastOneArtifact);
process.exitCode = 1;
return;
}
@@ -761,7 +761,7 @@ export function registerSchemaCommand(program: Command): void {
// Ask about setting as default (unless --no-default was passed)
if (options?.default === undefined) {
const setAsDefault = await confirm({
- message: 'Set as project default schema?',
+ message: CONFIG_MESSAGES.setAsDefaultSchema,
default: false,
});
@@ -783,12 +783,12 @@ export function registerSchemaCommand(program: Command): void {
if (options?.json) {
console.log(JSON.stringify({
created: false,
- error: `Unknown artifact '${id}'`,
+ error: SCHEMA_MESSAGES.unknownArtifact(id),
valid: validIds,
}, null, 2));
} else {
- console.error(`Error: Unknown artifact '${id}'`);
- console.error(`Valid artifacts: ${validIds.join(', ')}`);
+ console.error(SCHEMA_MESSAGES.unknownArtifact(id).replace(/^Artefato/, 'Erro: Artefato'));
+ console.error(SCHEMA_MESSAGES.validArtifacts(validIds.join(', ')));
}
process.exitCode = 1;
return;
@@ -801,7 +801,7 @@ export function registerSchemaCommand(program: Command): void {
}
// Create schema directory
- if (spinner) spinner.start(`Creating schema '${name}'...`);
+ if (spinner) spinner.start(SCHEMA_MESSAGES.creatingSchema(name));
fs.mkdirSync(schemaDir, { recursive: true });
// Build artifacts array with proper dependencies
@@ -886,7 +886,7 @@ export function registerSchemaCommand(program: Command): void {
}
}
- if (spinner) spinner.succeed(`Created schema '${name}'`);
+ if (spinner) spinner.succeed(SCHEMA_MESSAGES.schemaCreated(name));
if (options?.json) {
console.log(JSON.stringify({
@@ -897,25 +897,25 @@ export function registerSchemaCommand(program: Command): void {
setAsDefault: options?.default || false,
}, null, 2));
} else {
- console.log(`\nSchema created at: ${schemaDir}`);
- console.log(`\nArtifacts: ${selectedArtifactIds.join(', ')}`);
+ console.log('\n' + SCHEMA_MESSAGES.schemaCreatedAt(schemaDir));
+ console.log('\n' + SCHEMA_MESSAGES.artifactsLabel(selectedArtifactIds.join(', ')));
if (options?.default) {
- console.log(`\nSet as project default schema.`);
+ console.log('\n' + SCHEMA_MESSAGES.setAsDefaultSchemaLabel);
}
- console.log(`\nNext steps:`);
- console.log(` 1. Edit ${schemaDir}/schema.yaml to customize artifacts`);
- console.log(` 2. Modify templates in the schema directory`);
- console.log(` 3. Use with: openspec new --schema ${name}`);
+ console.log('\n' + SCHEMA_MESSAGES.nextStepsHeader);
+ console.log(SCHEMA_MESSAGES.editSchemaYaml(schemaDir));
+ console.log(SCHEMA_MESSAGES.modifyTemplates);
+ console.log(SCHEMA_MESSAGES.useWithSchema(name));
}
} catch (error) {
- if (spinner) spinner.fail(`Creation failed`);
+ if (spinner) spinner.fail(SCHEMA_MESSAGES.creationFailed);
if (options?.json) {
console.log(JSON.stringify({
created: false,
error: (error as Error).message,
}, null, 2));
} else {
- console.error(`Error: ${(error as Error).message}`);
+ console.error(CLI_MESSAGES.error((error as Error).message));
}
process.exitCode = 1;
}
diff --git a/src/commands/show.ts b/src/commands/show.ts
index 6413b5951c..3c6a0ebf95 100644
--- a/src/commands/show.ts
+++ b/src/commands/show.ts
@@ -4,6 +4,7 @@ import { getActiveChangeIds, getSpecIds } from '../utils/item-discovery.js';
import { ChangeCommand } from './change.js';
import { SpecCommand } from './spec.js';
import { nearestMatches } from '../utils/match.js';
+import { SHOW_MESSAGES } from '../messages/index.js';
type ItemType = 'change' | 'spec';
@@ -19,10 +20,10 @@ export class ShowCommand {
if (interactive) {
const { select } = await import('@inquirer/prompts');
const type = await select({
- message: 'What would you like to show?',
+ message: SHOW_MESSAGES.whatToShow,
choices: [
- { name: 'Change', value: 'change' as const },
- { name: 'Spec', value: 'spec' as const },
+ { name: SHOW_MESSAGES.optionChange, value: 'change' as const },
+ { name: SHOW_MESSAGES.optionSpec, value: 'spec' as const },
],
});
await this.runInteractiveByType(type, options);
@@ -48,11 +49,11 @@ export class ShowCommand {
if (type === 'change') {
const changes = await getActiveChangeIds();
if (changes.length === 0) {
- console.error('No changes found.');
+ console.error(SHOW_MESSAGES.noChangesFound);
process.exitCode = 1;
return;
}
- const picked = await select({ message: 'Pick a change', choices: changes.map(id => ({ name: id, value: id })) });
+ const picked = await select({ message: SHOW_MESSAGES.pickChange, choices: changes.map(id => ({ name: id, value: id })) });
const cmd = new ChangeCommand();
await cmd.show(picked, options as any);
return;
@@ -60,11 +61,11 @@ export class ShowCommand {
const specs = await getSpecIds();
if (specs.length === 0) {
- console.error('No specs found.');
+ console.error(SHOW_MESSAGES.noSpecsFound);
process.exitCode = 1;
return;
}
- const picked = await select({ message: 'Pick a spec', choices: specs.map(id => ({ name: id, value: id })) });
+ const picked = await select({ message: SHOW_MESSAGES.pickSpec, choices: specs.map(id => ({ name: id, value: id })) });
const cmd = new SpecCommand();
await cmd.show(picked, options as any);
}
@@ -90,16 +91,16 @@ export class ShowCommand {
const resolvedType = params.typeOverride ?? (isChange ? 'change' : isSpec ? 'spec' : undefined);
if (!resolvedType) {
- console.error(`Unknown item '${itemName}'`);
+ console.error(SHOW_MESSAGES.unknownItem(itemName));
const suggestions = nearestMatches(itemName, [...changes, ...specs]);
- if (suggestions.length) console.error(`Did you mean: ${suggestions.join(', ')}?`);
+ if (suggestions.length) console.error(SHOW_MESSAGES.didYouMean(suggestions.join(', ')));
process.exitCode = 1;
return;
}
if (!params.typeOverride && isChange && isSpec) {
- console.error(`Ambiguous item '${itemName}' matches both a change and a spec.`);
- console.error('Pass --type change|spec, or use: openspec change show / openspec spec show');
+ console.error(SHOW_MESSAGES.ambiguousItem(itemName));
+ console.error(SHOW_MESSAGES.passTypeHint);
process.exitCode = 1;
return;
}
@@ -115,11 +116,11 @@ export class ShowCommand {
}
private printNonInteractiveHint(): void {
- console.error('Nothing to show. Try one of:');
- console.error(' openspec show - ');
- console.error(' openspec change show');
- console.error(' openspec spec show');
- console.error('Or run in an interactive terminal.');
+ console.error(SHOW_MESSAGES.nothingToShow);
+ console.error(SHOW_MESSAGES.showItemHint);
+ console.error(SHOW_MESSAGES.showChangeHint);
+ console.error(SHOW_MESSAGES.showSpecHint);
+ console.error(SHOW_MESSAGES.runInteractiveHint);
}
private warnIrrelevantFlags(type: ItemType, options: { [k: string]: any }): boolean {
@@ -130,7 +131,7 @@ export class ShowCommand {
for (const k of CHANGE_FLAG_KEYS) if (k in options) irrelevant.push(k);
}
if (irrelevant.length > 0) {
- console.error(`Warning: Ignoring flags not applicable to ${type}: ${irrelevant.join(', ')}`);
+ console.error(SHOW_MESSAGES.ignoringFlags(type, irrelevant.join(', ')));
return true;
}
return false;
diff --git a/src/commands/spec.ts b/src/commands/spec.ts
index d28052f140..6bb78f3392 100644
--- a/src/commands/spec.ts
+++ b/src/commands/spec.ts
@@ -6,6 +6,7 @@ import { Validator } from '../core/validation/validator.js';
import type { Spec } from '../core/schemas/index.js';
import { isInteractive } from '../utils/interactive.js';
import { getSpecIds } from '../utils/item-discovery.js';
+import { CLI_DESCRIPTIONS, CLI_MESSAGES, SPEC_MESSAGES } from '../messages/index.js';
const SPECS_DIR = 'openspec/specs';
@@ -74,22 +75,22 @@ export class SpecCommand {
if (canPrompt && specIds.length > 0) {
const { select } = await import('@inquirer/prompts');
specId = await select({
- message: 'Select a spec to show',
+ message: SPEC_MESSAGES.selectSpecToShow,
choices: specIds.map(id => ({ name: id, value: id })),
});
} else {
- throw new Error('Missing required argument
');
+ throw new Error(SPEC_MESSAGES.missingSpecId);
}
}
const specPath = join(this.SPECS_DIR, specId, 'spec.md');
if (!existsSync(specPath)) {
- throw new Error(`Spec '${specId}' not found at openspec/specs/${specId}/spec.md`);
+ throw new Error(SPEC_MESSAGES.specNotFound(specId));
}
if (options.json) {
if (options.requirements && options.requirement) {
- throw new Error('Options --requirements and --requirement cannot be used together');
+ throw new Error(SPEC_MESSAGES.requirementsAndRequirementConflict);
}
const parsed = parseSpecFromFile(specPath, specId);
const filtered = filterSpec(parsed, options);
@@ -111,40 +112,40 @@ export class SpecCommand {
export function registerSpecCommand(rootProgram: typeof program) {
const specCommand = rootProgram
.command('spec')
- .description('Manage and view OpenSpec specifications');
+ .description(CLI_DESCRIPTIONS.spec);
// Deprecation notice for noun-based commands
specCommand.hook('preAction', () => {
- console.error('Warning: The "openspec spec ..." commands are deprecated. Prefer verb-first commands (e.g., "openspec show", "openspec validate --specs").');
+ console.error(CLI_MESSAGES.specCommandsDeprecated);
});
specCommand
.command('show [spec-id]')
- .description('Display a specific specification')
- .option('--json', 'Output as JSON')
- .option('--requirements', 'JSON only: Show only requirements (exclude scenarios)')
- .option('--no-scenarios', 'JSON only: Exclude scenario content')
- .option('-r, --requirement ', 'JSON only: Show specific requirement by ID (1-based)')
- .option('--no-interactive', 'Disable interactive prompts')
+ .description(CLI_DESCRIPTIONS.specShow)
+ .option('--json', 'Saída como JSON')
+ .option('--requirements', 'Somente JSON: Exibe apenas requisitos (exclui cenários)')
+ .option('--no-scenarios', 'Somente JSON: Exclui conteúdo de cenários')
+ .option('-r, --requirement ', 'Somente JSON: Exibe requisito específico pelo ID (base 1)')
+ .option('--no-interactive', 'Desativa prompts interativos')
.action(async (specId: string | undefined, options: ShowOptions & { noInteractive?: boolean }) => {
try {
const cmd = new SpecCommand();
await cmd.show(specId, options as any);
} catch (error) {
- console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
+ console.error(CLI_MESSAGES.error(error instanceof Error ? error.message : CLI_MESSAGES.unknownError));
process.exitCode = 1;
}
});
specCommand
.command('list')
- .description('List all available specifications')
- .option('--json', 'Output as JSON')
- .option('--long', 'Show id and title with counts')
+ .description(CLI_DESCRIPTIONS.specList)
+ .option('--json', 'Saída como JSON')
+ .option('--long', 'Exibe id e título com contagens')
.action((options: { json?: boolean; long?: boolean }) => {
try {
if (!existsSync(SPECS_DIR)) {
- console.log('No items found');
+ console.log(SPEC_MESSAGES.noItemsFound);
return;
}
@@ -178,7 +179,7 @@ export function registerSpecCommand(rootProgram: typeof program) {
console.log(JSON.stringify(specs, null, 2));
} else {
if (specs.length === 0) {
- console.log('No items found');
+ console.log(SPEC_MESSAGES.noItemsFound);
return;
}
if (!options.long) {
@@ -186,21 +187,21 @@ export function registerSpecCommand(rootProgram: typeof program) {
return;
}
specs.forEach(spec => {
- console.log(`${spec.id}: ${spec.title} [requirements ${spec.requirementCount}]`);
+ console.log(`${spec.id}: ${spec.title} ${SPEC_MESSAGES.requirementCount(spec.requirementCount)}`);
});
}
} catch (error) {
- console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
+ console.error(CLI_MESSAGES.error(error instanceof Error ? error.message : CLI_MESSAGES.unknownError));
process.exitCode = 1;
}
});
specCommand
.command('validate [spec-id]')
- .description('Validate a specification structure')
- .option('--strict', 'Enable strict validation mode')
- .option('--json', 'Output validation report as JSON')
- .option('--no-interactive', 'Disable interactive prompts')
+ .description(CLI_DESCRIPTIONS.specValidate)
+ .option('--strict', 'Ativa modo de validação estrita')
+ .option('--json', 'Saída do relatório de validação como JSON')
+ .option('--no-interactive', 'Desativa prompts interativos')
.action(async (specId: string | undefined, options: { strict?: boolean; json?: boolean; noInteractive?: boolean }) => {
try {
if (!specId) {
@@ -209,18 +210,18 @@ export function registerSpecCommand(rootProgram: typeof program) {
if (canPrompt && specIds.length > 0) {
const { select } = await import('@inquirer/prompts');
specId = await select({
- message: 'Select a spec to validate',
+ message: SPEC_MESSAGES.selectSpecToValidate,
choices: specIds.map(id => ({ name: id, value: id })),
});
} else {
- throw new Error('Missing required argument ');
+ throw new Error(SPEC_MESSAGES.missingSpecId);
}
}
const specPath = join(SPECS_DIR, specId, 'spec.md');
if (!existsSync(specPath)) {
- throw new Error(`Spec '${specId}' not found at openspec/specs/${specId}/spec.md`);
+ throw new Error(SPEC_MESSAGES.specNotFound(specId));
}
const validator = new Validator(options.strict);
@@ -230,9 +231,9 @@ export function registerSpecCommand(rootProgram: typeof program) {
console.log(JSON.stringify(report, null, 2));
} else {
if (report.valid) {
- console.log(`Specification '${specId}' is valid`);
+ console.log(SPEC_MESSAGES.specIsValid(specId));
} else {
- console.error(`Specification '${specId}' has issues`);
+ console.error(SPEC_MESSAGES.specHasIssues(specId));
report.issues.forEach(issue => {
const label = issue.level === 'ERROR' ? 'ERROR' : issue.level;
const prefix = issue.level === 'ERROR' ? '✗' : issue.level === 'WARNING' ? '⚠' : 'ℹ';
@@ -242,7 +243,7 @@ export function registerSpecCommand(rootProgram: typeof program) {
}
process.exitCode = report.valid ? 0 : 1;
} catch (error) {
- console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
+ console.error(CLI_MESSAGES.error(error instanceof Error ? error.message : CLI_MESSAGES.unknownError));
process.exitCode = 1;
}
});
diff --git a/src/commands/tools.ts b/src/commands/tools.ts
index 60c5230383..312f7ea236 100644
--- a/src/commands/tools.ts
+++ b/src/commands/tools.ts
@@ -22,6 +22,7 @@ import {
import { AI_TOOLS } from '../core/config.js';
import { getToolStates } from '../core/shared/index.js';
import { isInteractive } from '../utils/interactive.js';
+import { TOOLS_MESSAGES, CLI_MESSAGES } from '../messages/index.js';
// ─────────────────────────────────────────────────────────────────────────────
// Helpers
@@ -29,10 +30,7 @@ import { isInteractive } from '../utils/interactive.js';
function requireInitialized(projectPath: string): void {
if (!isProjectInitialized(projectPath)) {
- ora().fail(
- 'This project has not been initialized with OpenSpec.\n' +
- ' Run `openspec init` first.'
- );
+ ora().fail(TOOLS_MESSAGES.notInitialized);
process.exit(1);
}
}
@@ -44,7 +42,7 @@ function requireInitialized(projectPath: string): void {
async function runAdd(projectPath: string, toolsArg: string): Promise {
const toolIds = resolveToolsArg(toolsArg);
if (toolIds.length === 0) {
- console.log(chalk.dim('No tools specified to add.'));
+ console.log(chalk.dim(TOOLS_MESSAGES.noToolsToAdd));
return;
}
@@ -54,31 +52,31 @@ async function runAdd(projectPath: string, toolsArg: string): Promise {
for (const toolId of toolIds) {
const tool = AI_TOOLS.find((t) => t.value === toolId);
if (!tool) continue;
- const spinner = ora(`Adding ${tool.name}...`).start();
+ const spinner = ora(TOOLS_MESSAGES.adding(tool.name)).start();
try {
await addTool(projectPath, tool);
- spinner.succeed(`Added ${tool.name}`);
+ spinner.succeed(TOOLS_MESSAGES.added(tool.name));
added.push(tool.name);
} catch (err) {
- spinner.fail(`Failed to add ${tool.name}`);
+ spinner.fail(TOOLS_MESSAGES.failedToAdd(tool.name));
failed.push({ name: tool.name, error: err as Error });
}
}
console.log();
if (added.length > 0) {
- console.log(`Added: ${added.join(', ')}`);
+ console.log(TOOLS_MESSAGES.addedList(added.join(', ')));
}
if (failed.length > 0) {
console.log(
chalk.red(
- `Failed: ${failed.map((f) => `${f.name} (${f.error.message})`).join(', ')}`
+ TOOLS_MESSAGES.failedList(failed.map((f) => `${f.name} (${f.error.message})`).join(', '))
)
);
}
if (added.length > 0) {
console.log();
- console.log(chalk.white('Restart your IDE for slash commands to take effect.'));
+ console.log(chalk.white(TOOLS_MESSAGES.restartIDE));
}
}
@@ -89,7 +87,7 @@ async function runAdd(projectPath: string, toolsArg: string): Promise {
async function runRemove(projectPath: string, toolsArg: string): Promise {
const toolIds = resolveToolsArg(toolsArg);
if (toolIds.length === 0) {
- console.log(chalk.dim('No tools specified to remove.'));
+ console.log(chalk.dim(TOOLS_MESSAGES.noToolsToRemove));
return;
}
@@ -99,32 +97,32 @@ async function runRemove(projectPath: string, toolsArg: string): Promise {
for (const toolId of toolIds) {
const tool = AI_TOOLS.find((t) => t.value === toolId);
if (!tool) continue;
- const spinner = ora(`Removing ${tool.name}...`).start();
+ const spinner = ora(TOOLS_MESSAGES.removing(tool.name)).start();
try {
const counts = await removeTool(projectPath, tool);
- spinner.succeed(`Removed ${tool.name}`);
+ spinner.succeed(TOOLS_MESSAGES.removed(tool.name));
removed.push(tool.name);
if (counts.removedSkillCount > 0 || counts.removedCommandCount > 0) {
console.log(
chalk.dim(
- ` ${counts.removedSkillCount} skill dir(s) and ${counts.removedCommandCount} command file(s) removed`
+ TOOLS_MESSAGES.removedCounts(counts.removedSkillCount, counts.removedCommandCount)
)
);
}
} catch (err) {
- spinner.fail(`Failed to remove ${tool.name}`);
+ spinner.fail(TOOLS_MESSAGES.failedToRemove(tool.name));
failed.push({ name: tool.name, error: err as Error });
}
}
console.log();
if (removed.length > 0) {
- console.log(`Removed: ${removed.join(', ')}`);
+ console.log(TOOLS_MESSAGES.removedList(removed.join(', ')));
}
if (failed.length > 0) {
console.log(
chalk.red(
- `Failed: ${failed.map((f) => `${f.name} (${f.error.message})`).join(', ')}`
+ TOOLS_MESSAGES.failedList(failed.map((f) => `${f.name} (${f.error.message})`).join(', '))
)
);
}
@@ -161,16 +159,16 @@ async function runInteractive(projectPath: string): Promise {
const names = [...currentlyConfigured]
.map((id) => AI_TOOLS.find((t) => t.value === id)?.name ?? id)
.join(', ');
- console.log(`Currently configured: ${names}`);
+ console.log(TOOLS_MESSAGES.currentlyConfigured(names));
} else {
- console.log(chalk.dim('No tools currently configured.'));
+ console.log(chalk.dim(TOOLS_MESSAGES.noToolsConfigured));
}
console.log();
const { searchableMultiSelect } = await import('../prompts/searchable-multi-select.js');
const newSelection: string[] = await searchableMultiSelect({
- message: `Select tools to configure (${eligibleTools.length} available)`,
+ message: TOOLS_MESSAGES.selectToolsToConfigure(eligibleTools.length),
pageSize: 15,
choices,
});
@@ -182,7 +180,7 @@ async function runInteractive(projectPath: string): Promise {
const toRemove = [...currentlyConfigured].filter((id) => !newSet.has(id));
if (toAdd.length === 0 && toRemove.length === 0) {
- console.log(chalk.dim('\nNo changes.'));
+ console.log(chalk.dim('\n' + TOOLS_MESSAGES.noChanges));
return;
}
@@ -195,13 +193,13 @@ async function runInteractive(projectPath: string): Promise {
for (const toolId of toAdd) {
const tool = AI_TOOLS.find((t) => t.value === toolId);
if (!tool) continue;
- const spinner = ora(`Adding ${tool.name}...`).start();
+ const spinner = ora(TOOLS_MESSAGES.adding(tool.name)).start();
try {
await addTool(projectPath, tool);
- spinner.succeed(`Added ${tool.name}`);
+ spinner.succeed(TOOLS_MESSAGES.added(tool.name));
addedNames.push(tool.name);
} catch (err) {
- spinner.fail(`Failed to add ${tool.name}`);
+ spinner.fail(TOOLS_MESSAGES.failedToAdd(tool.name));
failed.push({ name: tool.name, error: err as Error });
}
}
@@ -209,34 +207,34 @@ async function runInteractive(projectPath: string): Promise {
for (const toolId of toRemove) {
const tool = AI_TOOLS.find((t) => t.value === toolId);
if (!tool) continue;
- const spinner = ora(`Removing ${tool.name}...`).start();
+ const spinner = ora(TOOLS_MESSAGES.removing(tool.name)).start();
try {
await removeTool(projectPath, tool);
- spinner.succeed(`Removed ${tool.name}`);
+ spinner.succeed(TOOLS_MESSAGES.removed(tool.name));
removedNames.push(tool.name);
} catch (err) {
- spinner.fail(`Failed to remove ${tool.name}`);
+ spinner.fail(TOOLS_MESSAGES.failedToRemove(tool.name));
failed.push({ name: tool.name, error: err as Error });
}
}
console.log();
if (addedNames.length > 0) {
- console.log(`Added: ${addedNames.join(', ')}`);
+ console.log(TOOLS_MESSAGES.addedList(addedNames.join(', ')));
}
if (removedNames.length > 0) {
- console.log(`Removed: ${removedNames.join(', ')}`);
+ console.log(TOOLS_MESSAGES.removedList(removedNames.join(', ')));
}
if (failed.length > 0) {
console.log(
chalk.red(
- `Failed: ${failed.map((f) => `${f.name} (${f.error.message})`).join(', ')}`
+ TOOLS_MESSAGES.failedList(failed.map((f) => `${f.name} (${f.error.message})`).join(', '))
)
);
}
if (addedNames.length > 0) {
console.log();
- console.log(chalk.white('Restart your IDE for slash commands to take effect.'));
+ console.log(chalk.white(TOOLS_MESSAGES.restartIDE));
}
}
@@ -247,11 +245,9 @@ async function runInteractive(projectPath: string): Promise {
export function registerToolsCommand(program: Command): void {
program
.command('tools [path]')
- .description(
- 'Add or remove IDE/Code Agent configurations. Shows an interactive checklist when no flags are provided.'
- )
- .option('--add ', 'Add tools (comma-separated IDs or "all")')
- .option('--remove ', 'Remove tools (comma-separated IDs or "all")')
+ .description(TOOLS_MESSAGES.description)
+ .option('--add ', TOOLS_MESSAGES.addOption)
+ .option('--remove ', TOOLS_MESSAGES.removeOption)
.action(
async (
targetPath = '.',
@@ -272,7 +268,7 @@ export function registerToolsCommand(program: Command): void {
const overlap = addIds.filter((id) => removeIds.includes(id));
if (overlap.length > 0) {
throw new Error(
- `Cannot add and remove the same tool(s): ${overlap.join(', ')}`
+ TOOLS_MESSAGES.cannotAddAndRemoveSame(overlap.join(', '))
);
}
// Run both sequentially
@@ -294,15 +290,14 @@ export function registerToolsCommand(program: Command): void {
// Interactive mode
if (!isInteractive()) {
throw new Error(
- 'No --add or --remove flag provided and the terminal is not interactive.\n' +
- ' Use --add or --remove to operate non-interactively.'
+ TOOLS_MESSAGES.noFlagNonInteractive
);
}
await runInteractive(projectPath);
} catch (error) {
console.log();
- ora().fail(`Error: ${(error as Error).message}`);
+ ora().fail(CLI_MESSAGES.error((error as Error).message));
process.exit(1);
}
}
diff --git a/src/commands/validate.ts b/src/commands/validate.ts
index 9e59a4d48d..2d6a2fdddb 100644
--- a/src/commands/validate.ts
+++ b/src/commands/validate.ts
@@ -4,6 +4,7 @@ import { Validator } from '../core/validation/validator.js';
import { isInteractive, resolveNoInteractive } from '../utils/interactive.js';
import { getActiveChangeIds, getSpecIds } from '../utils/item-discovery.js';
import { nearestMatches } from '../utils/match.js';
+import { VALIDATE_MESSAGES } from '../messages/index.js';
type ItemType = 'change' | 'spec';
@@ -66,9 +67,12 @@ export class ValidateCommand {
private async runInteractiveSelector(opts: { strict: boolean; json: boolean; concurrency?: string }): Promise {
const { select } = await import('@inquirer/prompts');
const choice = await select({
- message: 'What would you like to validate?',
+ message: VALIDATE_MESSAGES.whatToValidate,
choices: [
- { name: 'All (changes + specs)', value: 'all' },
+ { name: VALIDATE_MESSAGES.optionAll, value: 'all' },
+ { name: VALIDATE_MESSAGES.optionAllChanges, value: 'changes' },
+ { name: VALIDATE_MESSAGES.optionAllSpecs, value: 'specs' },
+ { name: VALIDATE_MESSAGES.optionPickOne, value: 'one' },
{ name: 'All changes', value: 'changes' },
{ name: 'All specs', value: 'specs' },
{ name: 'Pick a specific change or spec', value: 'one' },
@@ -85,21 +89,21 @@ export class ValidateCommand {
items.push(...changes.map(id => ({ name: `change/${id}`, value: { type: 'change' as const, id } })));
items.push(...specs.map(id => ({ name: `spec/${id}`, value: { type: 'spec' as const, id } })));
if (items.length === 0) {
- console.error('No items found to validate.');
+ console.error(VALIDATE_MESSAGES.noItemsToValidate);
process.exitCode = 1;
return;
}
- const picked = await select<{ type: ItemType; id: string }>({ message: 'Pick an item', choices: items });
+ const picked = await select<{ type: ItemType; id: string }>({ message: VALIDATE_MESSAGES.pickAnItem, choices: items });
await this.validateByType(picked.type, picked.id, opts);
}
private printNonInteractiveHint(): void {
- console.error('Nothing to validate. Try one of:');
- console.error(' openspec validate --all');
- console.error(' openspec validate --changes');
- console.error(' openspec validate --specs');
- console.error(' openspec validate ');
- console.error('Or run in an interactive terminal.');
+ console.error(VALIDATE_MESSAGES.nothingToValidate);
+ console.error(VALIDATE_MESSAGES.validateAllHint);
+ console.error(VALIDATE_MESSAGES.validateChangesHint);
+ console.error(VALIDATE_MESSAGES.validateSpecsHint);
+ console.error(VALIDATE_MESSAGES.validateItemHint);
+ console.error(VALIDATE_MESSAGES.runInteractiveHint);
}
private async validateDirectItem(itemName: string, opts: { typeOverride?: ItemType; strict: boolean; json: boolean }): Promise {
@@ -110,16 +114,16 @@ export class ValidateCommand {
const type = opts.typeOverride ?? (isChange ? 'change' : isSpec ? 'spec' : undefined);
if (!type) {
- console.error(`Unknown item '${itemName}'`);
+ console.error(VALIDATE_MESSAGES.unknownItem(itemName));
const suggestions = nearestMatches(itemName, [...changes, ...specs]);
- if (suggestions.length) console.error(`Did you mean: ${suggestions.join(', ')}?`);
+ if (suggestions.length) console.error(VALIDATE_MESSAGES.didYouMean(suggestions.join(', ')));
process.exitCode = 1;
return;
}
if (!opts.typeOverride && isChange && isSpec) {
- console.error(`Ambiguous item '${itemName}' matches both a change and a spec.`);
- console.error('Pass --type change|spec, or use: openspec change validate / openspec spec validate');
+ console.error(VALIDATE_MESSAGES.ambiguousItem(itemName));
+ console.error(VALIDATE_MESSAGES.passTypeHint);
process.exitCode = 1;
return;
}
@@ -154,9 +158,9 @@ export class ValidateCommand {
return;
}
if (report.valid) {
- console.log(`${type === 'change' ? 'Change' : 'Specification'} '${id}' is valid`);
+ console.log(type === 'change' ? VALIDATE_MESSAGES.changeIsValid(id) : VALIDATE_MESSAGES.specIsValid(id));
} else {
- console.error(`${type === 'change' ? 'Change' : 'Specification'} '${id}' has issues`);
+ console.error(type === 'change' ? VALIDATE_MESSAGES.changeHasIssues(id) : VALIDATE_MESSAGES.specHasIssues(id));
for (const issue of report.issues) {
const label = issue.level === 'ERROR' ? 'ERROR' : issue.level;
const prefix = issue.level === 'ERROR' ? '✗' : issue.level === 'WARNING' ? '⚠' : 'ℹ';
@@ -169,20 +173,20 @@ export class ValidateCommand {
private printNextSteps(type: ItemType): void {
const bullets: string[] = [];
if (type === 'change') {
- bullets.push('- Ensure change has deltas in specs/: use headers ## ADDED/MODIFIED/REMOVED/RENAMED Requirements');
- bullets.push('- Each requirement MUST include at least one #### Scenario: block');
- bullets.push('- Debug parsed deltas: openspec change show --json --deltas-only');
+ bullets.push(VALIDATE_MESSAGES.ensureDeltasInSpecs);
+ bullets.push(VALIDATE_MESSAGES.eachRequirementNeedsScenario);
+ bullets.push(VALIDATE_MESSAGES.debugParsedDeltas);
} else {
- bullets.push('- Ensure spec includes ## Purpose and ## Requirements sections');
+ bullets.push(VALIDATE_MESSAGES.ensurePurposeAndRequirements);
bullets.push('- Each requirement MUST include at least one #### Scenario: block');
- bullets.push('- Re-run with --json to see structured report');
+ bullets.push(VALIDATE_MESSAGES.rerunWithJson);
}
- console.error('Next steps:');
+ console.error(VALIDATE_MESSAGES.nextStepsChange);
bullets.forEach(b => console.error(` ${b}`));
}
private async runBulkValidation(scope: { changes: boolean; specs: boolean }, opts: { strict: boolean; json: boolean; concurrency?: string; noInteractive?: boolean }): Promise {
- const spinner = !opts.json && !opts.noInteractive ? ora('Validating...').start() : undefined;
+ const spinner = !opts.json && !opts.noInteractive ? ora(VALIDATE_MESSAGES.validating).start() : undefined;
const [changeIds, specIds] = await Promise.all([
scope.changes ? getActiveChangeIds() : Promise.resolve([]),
scope.specs ? getSpecIds() : Promise.resolve([]),
@@ -228,7 +232,7 @@ export class ValidateCommand {
const out = { items: [] as BulkItemResult[], summary, version: '1.0' };
console.log(JSON.stringify(out, null, 2));
} else {
- console.log('No items found to validate.');
+ console.log(VALIDATE_MESSAGES.noItemsFoundToValidate);
}
process.exitCode = 0;
@@ -247,7 +251,7 @@ export class ValidateCommand {
const currentIndex = index++;
const task = queue[currentIndex];
running++;
- if (spinner) spinner.text = `Validating (${currentIndex + 1}/${queue.length})...`;
+ if (spinner) spinner.text = VALIDATE_MESSAGES.validatingProgress(currentIndex + 1, queue.length);
task()
.then(res => {
results.push(res);
@@ -288,7 +292,7 @@ export class ValidateCommand {
if (res.valid) console.log(`✓ ${res.type}/${res.id}`);
else console.error(`✗ ${res.type}/${res.id}`);
}
- console.log(`Totals: ${summary.totals.passed} passed, ${summary.totals.failed} failed (${summary.totals.items} items)`);
+ console.log(VALIDATE_MESSAGES.totals(summary.totals.passed, summary.totals.failed, summary.totals.items));
}
process.exitCode = failed > 0 ? 1 : 0;
diff --git a/src/commands/workflow/instructions.ts b/src/commands/workflow/instructions.ts
index 7afba14753..a16c7e51ce 100644
--- a/src/commands/workflow/instructions.ts
+++ b/src/commands/workflow/instructions.ts
@@ -21,6 +21,7 @@ import {
type TaskItem,
type ApplyInstructions,
} from './shared.js';
+import { WORKFLOW_MESSAGES } from '../../messages/index.js';
// -----------------------------------------------------------------------------
// Types
@@ -46,7 +47,7 @@ export async function instructionsCommand(
artifactId: string | undefined,
options: InstructionsOptions
): Promise {
- const spinner = options.json ? undefined : ora('Generating instructions...').start();
+ const spinner = options.json ? undefined : ora(WORKFLOW_MESSAGES.generatingInstructions).start();
try {
const projectRoot = process.cwd();
@@ -64,7 +65,7 @@ export async function instructionsCommand(
spinner?.stop();
const validIds = context.graph.getAllArtifacts().map((a) => a.id);
throw new Error(
- `Missing required argument . Valid artifacts:\n ${validIds.join('\n ')}`
+ WORKFLOW_MESSAGES.missingArtifactArgument(validIds.join('\n '))
);
}
@@ -74,7 +75,7 @@ export async function instructionsCommand(
spinner?.stop();
const validIds = context.graph.getAllArtifacts().map((a) => a.id);
throw new Error(
- `Artifact '${artifactId}' not found in schema '${context.schemaName}'. Valid artifacts:\n ${validIds.join('\n ')}`
+ WORKFLOW_MESSAGES.artifactNotFound(artifactId, context.schemaName, validIds.join('\n '))
);
}
@@ -119,8 +120,8 @@ export function printInstructionsText(instructions: ArtifactInstructions, isBloc
if (isBlocked) {
const missing = dependencies.filter((d) => !d.done).map((d) => d.id);
console.log('');
- console.log('This artifact has unmet dependencies. Complete them first or proceed with caution.');
- console.log(`Missing: ${missing.join(', ')}`);
+ console.log(WORKFLOW_MESSAGES.unmetDependenciesWarning);
+ console.log(WORKFLOW_MESSAGES.missingDependencies(missing.join(', ')));
console.log(' ');
console.log();
}
@@ -155,7 +156,7 @@ export function printInstructionsText(instructions: ArtifactInstructions, isBloc
// Dependencies (files to read for context)
if (dependencies.length > 0) {
console.log('');
- console.log('Read these files for context before creating this artifact:');
+ console.log(WORKFLOW_MESSAGES.readFilesForContext);
console.log();
for (const dep of dependencies) {
const status = dep.done ? 'done' : 'missing';
@@ -199,7 +200,7 @@ export function printInstructionsText(instructions: ArtifactInstructions, isBloc
// Unlocks
if (unlocks.length > 0) {
console.log('');
- console.log(`Completing this artifact enables: ${unlocks.join(', ')}`);
+ console.log(WORKFLOW_MESSAGES.unlocksArtifacts(unlocks.join(', ')));
console.log(' ');
console.log();
}
@@ -303,27 +304,27 @@ export async function generateApplyInstructions(
if (missingArtifacts.length > 0) {
state = 'blocked';
- instruction = `Cannot apply this change yet. Missing artifacts: ${missingArtifacts.join(', ')}.\nUse the openspec-continue-change skill to create the missing artifacts first.`;
+ instruction = WORKFLOW_MESSAGES.cannotApplyMissingArtifacts(missingArtifacts.join(', '));
} else if (tracksFile && !tracksFileExists) {
// Tracking file configured but doesn't exist yet
const tracksFilename = path.basename(tracksFile);
state = 'blocked';
- instruction = `The ${tracksFilename} file is missing and must be created.\nUse openspec-continue-change to generate the tracking file.`;
+ instruction = WORKFLOW_MESSAGES.missingTrackingFile(tracksFilename);
} else if (tracksFile && tracksFileExists && total === 0) {
// Tracking file exists but contains no tasks
const tracksFilename = path.basename(tracksFile);
state = 'blocked';
- instruction = `The ${tracksFilename} file exists but contains no tasks.\nAdd tasks to ${tracksFilename} or regenerate it with openspec-continue-change.`;
+ instruction = WORKFLOW_MESSAGES.trackingFileNoTasks(tracksFilename);
} else if (tracksFile && remaining === 0 && total > 0) {
state = 'all_done';
- instruction = 'All tasks are complete! This change is ready to be archived.\nConsider running tests and reviewing the changes before archiving.';
+ instruction = WORKFLOW_MESSAGES.allTasksComplete;
} else if (!tracksFile) {
// No tracking file configured in schema - ready to apply
state = 'ready';
- instruction = schemaInstruction?.trim() ?? 'All required artifacts complete. Proceed with implementation.';
+ instruction = schemaInstruction?.trim() ?? WORKFLOW_MESSAGES.allArtifactsCompleteProceed;
} else {
state = 'ready';
- instruction = schemaInstruction?.trim() ?? 'Read context files, work through pending tasks, mark complete as you go.\nPause if you hit blockers or need clarification.';
+ instruction = schemaInstruction?.trim() ?? WORKFLOW_MESSAGES.readContextAndWorkTasks;
}
return {
@@ -340,7 +341,7 @@ export async function generateApplyInstructions(
}
export async function applyInstructionsCommand(options: ApplyInstructionsOptions): Promise {
- const spinner = options.json ? undefined : ora('Generating apply instructions...').start();
+ const spinner = options.json ? undefined : ora(WORKFLOW_MESSAGES.generatingApplyInstructions).start();
try {
const projectRoot = process.cwd();
@@ -371,23 +372,23 @@ export async function applyInstructionsCommand(options: ApplyInstructionsOptions
export function printApplyInstructionsText(instructions: ApplyInstructions): void {
const { changeName, schemaName, contextFiles, progress, tasks, state, missingArtifacts, instruction } = instructions;
- console.log(`## Apply: ${changeName}`);
- console.log(`Schema: ${schemaName}`);
+ console.log(WORKFLOW_MESSAGES.applyTitle(changeName));
+ console.log(WORKFLOW_MESSAGES.schemaLabel(schemaName));
console.log();
// Warning for blocked state
if (state === 'blocked' && missingArtifacts) {
- console.log('### ⚠️ Blocked');
+ console.log(WORKFLOW_MESSAGES.blockedTitle);
console.log();
- console.log(`Missing artifacts: ${missingArtifacts.join(', ')}`);
- console.log('Use the openspec-continue-change skill to create these first.');
+ console.log(WORKFLOW_MESSAGES.missingArtifactsLabel(missingArtifacts.join(', ')));
+ console.log(WORKFLOW_MESSAGES.createMissingFirst);
console.log();
}
// Context files (dynamically from schema)
const contextFileEntries = Object.entries(contextFiles);
if (contextFileEntries.length > 0) {
- console.log('### Context Files');
+ console.log(WORKFLOW_MESSAGES.contextFilesTitle);
for (const [artifactId, filePaths] of contextFileEntries) {
for (const filePath of filePaths) {
console.log(`- ${artifactId}: ${filePath}`);
@@ -398,18 +399,18 @@ export function printApplyInstructionsText(instructions: ApplyInstructions): voi
// Progress (only show if we have tracking)
if (progress.total > 0 || tasks.length > 0) {
- console.log('### Progress');
+ console.log(WORKFLOW_MESSAGES.progressTitle);
if (state === 'all_done') {
- console.log(`${progress.complete}/${progress.total} complete ✓`);
+ console.log(WORKFLOW_MESSAGES.progressCompleteWithCheck(progress.complete, progress.total));
} else {
- console.log(`${progress.complete}/${progress.total} complete`);
+ console.log(WORKFLOW_MESSAGES.progressComplete(progress.complete, progress.total));
}
console.log();
}
// Tasks
if (tasks.length > 0) {
- console.log('### Tasks');
+ console.log(WORKFLOW_MESSAGES.tasksTitle);
for (const task of tasks) {
const checkbox = task.done ? '[x]' : '[ ]';
console.log(`- ${checkbox} ${task.description}`);
@@ -418,6 +419,6 @@ export function printApplyInstructionsText(instructions: ApplyInstructions): voi
}
// Instruction
- console.log('### Instruction');
+ console.log(WORKFLOW_MESSAGES.instructionTitle);
console.log(instruction);
}
diff --git a/src/commands/workflow/new-change.ts b/src/commands/workflow/new-change.ts
index 1435e1addb..f947fcba00 100644
--- a/src/commands/workflow/new-change.ts
+++ b/src/commands/workflow/new-change.ts
@@ -8,6 +8,7 @@ import ora from 'ora';
import path from 'path';
import { createChange, validateChangeName } from '../../utils/change-utils.js';
import { validateSchemaExists } from './shared.js';
+import { WORKFLOW_MESSAGES } from '../../messages/index.js';
// -----------------------------------------------------------------------------
// Types
@@ -24,7 +25,7 @@ export interface NewChangeOptions {
export async function newChangeCommand(name: string | undefined, options: NewChangeOptions): Promise {
if (!name) {
- throw new Error('Missing required argument ');
+ throw new Error(WORKFLOW_MESSAGES.missingNameArgument);
}
const validation = validateChangeName(name);
@@ -39,8 +40,8 @@ export async function newChangeCommand(name: string | undefined, options: NewCha
validateSchemaExists(options.schema, projectRoot);
}
- const schemaDisplay = options.schema ? ` with schema '${options.schema}'` : '';
- const spinner = ora(`Creating change '${name}'${schemaDisplay}...`).start();
+ const schemaDisplay = options.schema ? ` com esquema '${options.schema}'` : '';
+ const spinner = ora(WORKFLOW_MESSAGES.creatingChange(name, schemaDisplay)).start();
try {
const result = await createChange(projectRoot, name, { schema: options.schema });
@@ -53,9 +54,9 @@ export async function newChangeCommand(name: string | undefined, options: NewCha
await fs.writeFile(readmePath, `# ${name}\n\n${options.description}\n`, 'utf-8');
}
- spinner.succeed(`Created change '${name}' at openspec/changes/${name}/ (schema: ${result.schema})`);
+ spinner.succeed(WORKFLOW_MESSAGES.createdChange(name, result.schema));
} catch (error) {
- spinner.fail(`Failed to create change '${name}'`);
+ spinner.fail(WORKFLOW_MESSAGES.failedToCreateChange(name));
throw error;
}
}
diff --git a/src/commands/workflow/schemas.ts b/src/commands/workflow/schemas.ts
index b9af74a677..2f591c46d6 100644
--- a/src/commands/workflow/schemas.ts
+++ b/src/commands/workflow/schemas.ts
@@ -6,6 +6,7 @@
import chalk from 'chalk';
import { listSchemasWithInfo } from '../../core/artifact-graph/index.js';
+import { WORKFLOW_MESSAGES } from '../../messages/index.js';
// -----------------------------------------------------------------------------
// Types
@@ -28,19 +29,19 @@ export async function schemasCommand(options: SchemasOptions): Promise {
return;
}
- console.log('Available schemas:');
+ console.log(WORKFLOW_MESSAGES.availableSchemas);
console.log();
for (const schema of schemas) {
let sourceLabel = '';
if (schema.source === 'project') {
- sourceLabel = chalk.cyan(' (project)');
+ sourceLabel = chalk.cyan(WORKFLOW_MESSAGES.projectLabel);
} else if (schema.source === 'user') {
- sourceLabel = chalk.dim(' (user override)');
+ sourceLabel = chalk.dim(WORKFLOW_MESSAGES.userOverrideLabel);
}
console.log(` ${chalk.bold(schema.name)}${sourceLabel}`);
console.log(` ${schema.description}`);
- console.log(` Artifacts: ${schema.artifacts.join(' → ')}`);
+ console.log(` ${WORKFLOW_MESSAGES.artifactsLabel(schema.artifacts.join(' → '))}`);
console.log();
}
}
diff --git a/src/commands/workflow/shared.ts b/src/commands/workflow/shared.ts
index 43c9aa46c9..67217d159c 100644
--- a/src/commands/workflow/shared.ts
+++ b/src/commands/workflow/shared.ts
@@ -10,6 +10,7 @@ import path from 'path';
import * as fs from 'fs';
import { getSchemaDir, listSchemas } from '../../core/artifact-graph/index.js';
import { validateChangeName } from '../../utils/change-utils.js';
+import { WORKFLOW_MESSAGES } from '../../messages/index.js';
// -----------------------------------------------------------------------------
// Types
@@ -114,7 +115,7 @@ export async function validateChangeExists(
if (!changeName) {
const available = await getAvailableChanges(projectRoot);
if (available.length === 0) {
- throw new Error('No changes found. Create one with: openspec new change ');
+ throw new Error(WORKFLOW_MESSAGES.noChangesFound);
}
throw new Error(
`Missing required option --change. Available changes:\n ${available.join('\n ')}`
@@ -124,7 +125,7 @@ export async function validateChangeExists(
// Validate change name format to prevent path traversal
const nameValidation = validateChangeName(changeName);
if (!nameValidation.valid) {
- throw new Error(`Invalid change name '${changeName}': ${nameValidation.error}`);
+ throw new Error(WORKFLOW_MESSAGES.invalidChangeName(changeName, nameValidation.error!));
}
// Check directory existence directly
@@ -135,7 +136,7 @@ export async function validateChangeExists(
const available = await getAvailableChanges(projectRoot);
if (available.length === 0) {
throw new Error(
- `Change '${changeName}' not found. No changes exist. Create one with: openspec new change `
+ WORKFLOW_MESSAGES.changeNotFoundNoChanges(changeName)
);
}
throw new Error(
@@ -157,7 +158,7 @@ export function validateSchemaExists(schemaName: string, projectRoot?: string):
if (!schemaDir) {
const availableSchemas = listSchemas(projectRoot);
throw new Error(
- `Schema '${schemaName}' not found. Available schemas:\n ${availableSchemas.join('\n ')}`
+ WORKFLOW_MESSAGES.schemaNotFound(schemaName, availableSchemas.join('\n '))
);
}
return schemaName;
diff --git a/src/commands/workflow/status.ts b/src/commands/workflow/status.ts
index 1109ab1886..94b9ec0029 100644
--- a/src/commands/workflow/status.ts
+++ b/src/commands/workflow/status.ts
@@ -18,6 +18,7 @@ import {
getStatusIndicator,
getStatusColor,
} from './shared.js';
+import { WORKFLOW_MESSAGES } from '../../messages/index.js';
// -----------------------------------------------------------------------------
// Types
@@ -34,7 +35,7 @@ export interface StatusOptions {
// -----------------------------------------------------------------------------
export async function statusCommand(options: StatusOptions): Promise {
- const spinner = options.json ? undefined : ora('Loading change status...').start();
+ const spinner = options.json ? undefined : ora(WORKFLOW_MESSAGES.loadingChangeStatus).start();
try {
const projectRoot = process.cwd();
@@ -46,16 +47,16 @@ export async function statusCommand(options: StatusOptions): Promise {
if (available.length === 0) {
spinner?.stop();
if (options.json) {
- console.log(JSON.stringify({ changes: [], message: 'No active changes.' }, null, 2));
+ console.log(JSON.stringify({ changes: [], message: WORKFLOW_MESSAGES.noActiveChanges }, null, 2));
return;
}
- console.log('No active changes. Create one with: openspec new change ');
+ console.log(WORKFLOW_MESSAGES.noActiveChanges);
return;
}
// Changes exist but --change not provided
spinner?.stop();
throw new Error(
- `Missing required option --change. Available changes:\n ${available.join('\n ')}`
+ WORKFLOW_MESSAGES.missingChangeOption(available.join('\n '))
);
}
@@ -88,9 +89,9 @@ export function printStatusText(status: ChangeStatus): void {
const doneCount = status.artifacts.filter((a) => a.status === 'done').length;
const total = status.artifacts.length;
- console.log(`Change: ${status.changeName}`);
- console.log(`Schema: ${status.schemaName}`);
- console.log(`Progress: ${doneCount}/${total} artifacts complete`);
+ console.log(WORKFLOW_MESSAGES.changeLabel(status.changeName));
+ console.log(WORKFLOW_MESSAGES.schemaLabel2(status.schemaName));
+ console.log(WORKFLOW_MESSAGES.progressArtifacts(doneCount, total));
console.log();
for (const artifact of status.artifacts) {
@@ -99,7 +100,7 @@ export function printStatusText(status: ChangeStatus): void {
let line = `${indicator} ${artifact.id}`;
if (artifact.status === 'blocked' && artifact.missingDeps && artifact.missingDeps.length > 0) {
- line += color(` (blocked by: ${artifact.missingDeps.join(', ')})`);
+ line += color(WORKFLOW_MESSAGES.blockedBy(artifact.missingDeps.join(', ')));
}
console.log(line);
@@ -107,6 +108,6 @@ export function printStatusText(status: ChangeStatus): void {
if (status.isComplete) {
console.log();
- console.log(chalk.green('All artifacts complete!'));
+ console.log(chalk.green(WORKFLOW_MESSAGES.allArtifactsComplete));
}
}
diff --git a/src/commands/workflow/templates.ts b/src/commands/workflow/templates.ts
index fedd323e0d..272fa0529a 100644
--- a/src/commands/workflow/templates.ts
+++ b/src/commands/workflow/templates.ts
@@ -13,6 +13,7 @@ import {
} from '../../core/artifact-graph/index.js';
import { FileSystemUtils } from '../../utils/file-system.js';
import { validateSchemaExists, DEFAULT_SCHEMA } from './shared.js';
+import { WORKFLOW_MESSAGES } from '../../messages/index.js';
// -----------------------------------------------------------------------------
// Types
@@ -34,7 +35,7 @@ export interface TemplateInfo {
// -----------------------------------------------------------------------------
export async function templatesCommand(options: TemplatesOptions): Promise {
- const spinner = options.json ? undefined : ora('Loading templates...').start();
+ const spinner = options.json ? undefined : ora(WORKFLOW_MESSAGES.loadingTemplates).start();
try {
const projectRoot = process.cwd();
@@ -86,8 +87,8 @@ export async function templatesCommand(options: TemplatesOptions): Promise
return;
}
- console.log(`Schema: ${schemaName}`);
- console.log(`Source: ${source}`);
+ console.log(WORKFLOW_MESSAGES.schemaLabel3(schemaName));
+ console.log(WORKFLOW_MESSAGES.sourceLabel(source));
console.log();
for (const t of templates) {
diff --git a/src/core/archive.ts b/src/core/archive.ts
index 5af7181fce..f70e62f275 100644
--- a/src/core/archive.ts
+++ b/src/core/archive.ts
@@ -3,6 +3,7 @@ import path from 'path';
import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
import { Validator } from './validation/validator.js';
import chalk from 'chalk';
+import { ARCHIVE_MESSAGES } from '../messages/index.js';
import {
findSpecUpdates,
buildUpdatedSpec,
@@ -68,7 +69,7 @@ export class ArchiveCommand {
if (!changeName) {
const selectedChange = await this.selectChange(changesDir);
if (!selectedChange) {
- console.log('No change selected. Aborting.');
+ console.log(ARCHIVE_MESSAGES.noChangeSelected);
return;
}
changeName = selectedChange;
@@ -80,10 +81,10 @@ export class ArchiveCommand {
try {
const stat = await fs.stat(changeDir);
if (!stat.isDirectory()) {
- throw new Error(`Change '${changeName}' not found.`);
+ throw new Error(ARCHIVE_MESSAGES.changeNotFound(changeName));
}
} catch {
- throw new Error(`Change '${changeName}' not found.`);
+ throw new Error(ARCHIVE_MESSAGES.changeNotFound(changeName));
}
const skipValidation = options.validate === false || options.noValidate === true;
@@ -100,7 +101,7 @@ export class ArchiveCommand {
const changeReport = await validator.validateChange(changeFile);
// Proposal validation is informative only (do not block archive)
if (!changeReport.valid) {
- console.log(chalk.yellow(`\nProposal warnings in proposal.md (non-blocking):`));
+ console.log(chalk.yellow(`\n${ARCHIVE_MESSAGES.proposalWarnings}`));
for (const issue of changeReport.issues) {
const symbol = issue.level === 'ERROR' ? '⚠' : (issue.level === 'WARNING' ? '⚠' : 'ℹ');
console.log(chalk.yellow(` ${symbol} ${issue.message}`));
@@ -133,7 +134,7 @@ export class ArchiveCommand {
const deltaReport = await validator.validateChangeDeltaSpecs(changeDir);
if (!deltaReport.valid) {
hasValidationErrors = true;
- console.log(chalk.red(`\nValidation errors in change delta specs:`));
+ console.log(chalk.red(`\n${ARCHIVE_MESSAGES.validationErrorsInDeltas}`));
for (const issue of deltaReport.issues) {
if (issue.level === 'ERROR') {
console.log(chalk.red(` ✗ ${issue.message}`));
@@ -145,8 +146,8 @@ export class ArchiveCommand {
}
if (hasValidationErrors) {
- console.log(chalk.red('\nValidation failed. Please fix the errors before archiving.'));
- console.log(chalk.yellow('To skip validation (not recommended), use --no-validate flag.'));
+ console.log(chalk.red(`\n${ARCHIVE_MESSAGES.validationFailed}`));
+ console.log(chalk.yellow(ARCHIVE_MESSAGES.skipValidationHint));
return;
}
} else {
@@ -156,67 +157,67 @@ export class ArchiveCommand {
if (!options.yes) {
const { confirm } = await import('@inquirer/prompts');
const proceed = await confirm({
- message: chalk.yellow('⚠️ WARNING: Skipping validation may archive invalid specs. Continue? (y/N)'),
+ message: chalk.yellow(ARCHIVE_MESSAGES.skipValidationWarning),
default: false
});
if (!proceed) {
- console.log('Archive cancelled.');
+ console.log(ARCHIVE_MESSAGES.archiveCancelled);
return;
}
} else {
- console.log(chalk.yellow(`\n⚠️ WARNING: Skipping validation may archive invalid specs.`));
+ console.log(chalk.yellow(`\n${ARCHIVE_MESSAGES.skipValidationFlagWarning}`));
}
- console.log(chalk.yellow(`[${timestamp}] Validation skipped for change: ${changeName}`));
- console.log(chalk.yellow(`Affected files: ${changeDir}`));
+ console.log(chalk.yellow(ARCHIVE_MESSAGES.skipValidationLog(timestamp, changeName)));
+ console.log(chalk.yellow(ARCHIVE_MESSAGES.affectedFiles(changeDir)));
}
// Show progress and check for incomplete tasks
const progress = await getTaskProgressForChange(changesDir, changeName);
const status = formatTaskStatus(progress);
- console.log(`Task status: ${status}`);
+ console.log(ARCHIVE_MESSAGES.taskStatus(status));
const incompleteTasks = Math.max(progress.total - progress.completed, 0);
if (incompleteTasks > 0) {
if (!options.yes) {
const { confirm } = await import('@inquirer/prompts');
const proceed = await confirm({
- message: `Warning: ${incompleteTasks} incomplete task(s) found. Continue?`,
+ message: ARCHIVE_MESSAGES.incompleteTasksWarning(incompleteTasks),
default: false
});
if (!proceed) {
- console.log('Archive cancelled.');
+ console.log(ARCHIVE_MESSAGES.archiveCancelled);
return;
}
} else {
- console.log(`Warning: ${incompleteTasks} incomplete task(s) found. Continuing due to --yes flag.`);
+ console.log(ARCHIVE_MESSAGES.incompleteTasksContinuing(incompleteTasks));
}
}
// Handle spec updates unless skipSpecs flag is set
if (options.skipSpecs) {
- console.log('Skipping spec updates (--skip-specs flag provided).');
+ console.log(ARCHIVE_MESSAGES.skipSpecUpdates);
} else {
// Find specs to update
const specUpdates = await findSpecUpdates(changeDir, mainSpecsDir);
if (specUpdates.length > 0) {
- console.log('\nSpecs to update:');
+ console.log(`\n${ARCHIVE_MESSAGES.specsToUpdate}`);
for (const update of specUpdates) {
- const status = update.exists ? 'update' : 'create';
+ const status = update.exists ? 'atualizar' : 'criar';
const capability = path.basename(path.dirname(update.target));
- console.log(` ${capability}: ${status}`);
+ console.log(ARCHIVE_MESSAGES.specUpdateStatus(capability, status));
}
let shouldUpdateSpecs = true;
if (!options.yes) {
const { confirm } = await import('@inquirer/prompts');
shouldUpdateSpecs = await confirm({
- message: 'Proceed with spec updates?',
+ message: ARCHIVE_MESSAGES.proceedWithSpecUpdates,
default: true
});
if (!shouldUpdateSpecs) {
- console.log('Skipping spec updates. Proceeding with archive.');
+ console.log(ARCHIVE_MESSAGES.skipSpecUpdatesProceeding);
}
}
@@ -230,7 +231,7 @@ export class ArchiveCommand {
}
} catch (err: any) {
console.log(String(err.message || err));
- console.log('Aborted. No files were changed.');
+ console.log(ARCHIVE_MESSAGES.abortedNoChanges);
return;
}
@@ -241,12 +242,12 @@ export class ArchiveCommand {
if (!skipValidation) {
const report = await new Validator().validateSpecContent(specName, p.rebuilt);
if (!report.valid) {
- console.log(chalk.red(`\nValidation errors in rebuilt spec for ${specName} (will not write changes):`));
+ console.log(chalk.red(`\n${ARCHIVE_MESSAGES.validationErrorsInRebuiltSpec(specName)}`));
for (const issue of report.issues) {
if (issue.level === 'ERROR') console.log(chalk.red(` ✗ ${issue.message}`));
else if (issue.level === 'WARNING') console.log(chalk.yellow(` ⚠ ${issue.message}`));
}
- console.log('Aborted. No files were changed.');
+ console.log(ARCHIVE_MESSAGES.abortedNoChanges);
return;
}
}
@@ -257,9 +258,9 @@ export class ArchiveCommand {
totals.renamed += p.counts.renamed;
}
console.log(
- `Totals: + ${totals.added}, ~ ${totals.modified}, - ${totals.removed}, → ${totals.renamed}`
+ ARCHIVE_MESSAGES.totals(totals.added, totals.modified, totals.removed, totals.renamed)
);
- console.log('Specs updated successfully.');
+ console.log(ARCHIVE_MESSAGES.specsUpdatedSuccessfully);
}
}
}
@@ -271,7 +272,7 @@ export class ArchiveCommand {
// Check if archive already exists
try {
await fs.access(archivePath);
- throw new Error(`Archive '${archiveName}' already exists.`);
+ throw new Error(ARCHIVE_MESSAGES.archiveAlreadyExists(archiveName));
} catch (error: any) {
if (error.code !== 'ENOENT') {
throw error;
@@ -284,7 +285,7 @@ export class ArchiveCommand {
// Move change to archive (uses copy+remove on EPERM/EXDEV, e.g. Windows)
await moveDirectory(changeDir, archivePath);
- console.log(`Change '${changeName}' archived as '${archiveName}'.`);
+ console.log(ARCHIVE_MESSAGES.changeArchived(changeName, archiveName));
}
private async selectChange(changesDir: string): Promise {
@@ -297,7 +298,7 @@ export class ArchiveCommand {
.sort();
if (changeDirs.length === 0) {
- console.log('No active changes found.');
+ console.log(ARCHIVE_MESSAGES.noActiveChanges);
return null;
}
@@ -322,7 +323,7 @@ export class ArchiveCommand {
try {
const answer = await select({
- message: 'Select a change to archive',
+ message: ARCHIVE_MESSAGES.selectChangeToArchive,
choices
});
return answer;
diff --git a/src/core/init.ts b/src/core/init.ts
index 1e177c2b6b..c4fea87b4b 100644
--- a/src/core/init.ts
+++ b/src/core/init.ts
@@ -19,6 +19,7 @@ import {
} from './config.js';
import { PALETTE } from './styles/palette.js';
import { isInteractive } from '../utils/interactive.js';
+import { INIT_MESSAGES } from '../messages/index.js';
import { serializeConfig } from './config-prompts.js';
import {
generateCommands,
@@ -157,7 +158,7 @@ export class InitCommand {
// Check write permissions
if (!(await FileSystemUtils.ensureWritePermissions(projectPath))) {
- throw new Error(`Insufficient permissions to write to ${projectPath}`);
+ throw new Error(INIT_MESSAGES.insufficientPermissions(projectPath));
}
return extendMode;
}
@@ -210,13 +211,13 @@ export class InitCommand {
// Interactive mode: prompt for confirmation
const { confirm } = await import('@inquirer/prompts');
const shouldCleanup = await confirm({
- message: 'Upgrade and clean up legacy files?',
+ message: INIT_MESSAGES.upgradeLegacyPrompt,
default: true,
});
if (!shouldCleanup) {
- console.log(chalk.dim('Initialization cancelled.'));
- console.log(chalk.dim('Run with --force to skip this prompt, or manually remove legacy files.'));
+ console.log(chalk.dim(INIT_MESSAGES.initializationCancelled));
+ console.log(chalk.dim(INIT_MESSAGES.skipPromptHint));
process.exit(0);
}
@@ -224,11 +225,11 @@ export class InitCommand {
}
private async performLegacyCleanup(projectPath: string, detection: LegacyDetectionResult): Promise {
- const spinner = ora('Cleaning up legacy files...').start();
+ const spinner = ora(INIT_MESSAGES.cleaningLegacy).start();
const result = await cleanupLegacyArtifacts(projectPath, detection);
- spinner.succeed('Legacy files cleaned up');
+ spinner.succeed(INIT_MESSAGES.legacyCleaned);
const summary = formatCleanupSummary(result);
if (summary) {
@@ -271,13 +272,13 @@ export class InitCommand {
return [...detectedToolIds];
}
throw new Error(
- `No tools detected and no --tools flag provided. Valid tools:\n ${validTools.join('\n ')}\n\nUse --tools all, --tools none, or --tools claude,cursor,...`
+ INIT_MESSAGES.noToolsDetected(validTools.join('\n '))
);
}
if (validTools.length === 0) {
throw new Error(
- `No tools available for skill generation.`
+ INIT_MESSAGES.noToolsAvailable
);
}
@@ -314,7 +315,7 @@ export class InitCommand {
.map((toolId) => AI_TOOLS.find((t) => t.value === toolId)?.name || toolId);
if (configuredNames.length > 0) {
- console.log(`OpenSpec configured: ${configuredNames.join(', ')} (pre-selected)`);
+ console.log(INIT_MESSAGES.configuredPreselected(configuredNames.join(', ')));
}
const detectedOnlyNames = detectedTools
@@ -323,20 +324,20 @@ export class InitCommand {
if (detectedOnlyNames.length > 0) {
const detectionLabel = shouldPreselectDetected
- ? 'pre-selected for first-time setup'
- : 'not pre-selected';
- console.log(`Detected tool directories: ${detectedOnlyNames.join(', ')} (${detectionLabel})`);
+ ? INIT_MESSAGES.preselectedFirstTime
+ : INIT_MESSAGES.notPreselected;
+ console.log(INIT_MESSAGES.detectedToolsLabel(detectedOnlyNames.join(', '), detectionLabel));
}
const selectedTools = await searchableMultiSelect({
- message: `Select tools to set up (${validTools.length} available)`,
+ message: INIT_MESSAGES.selectToolsPrompt(validTools.length),
pageSize: 15,
choices: sortedChoices,
- validate: (selected: string[]) => selected.length > 0 || 'Select at least one tool',
+ validate: (selected: string[]) => selected.length > 0 || INIT_MESSAGES.selectAtLeastOneTool,
});
if (selectedTools.length === 0) {
- throw new Error('At least one tool must be selected');
+ throw new Error(INIT_MESSAGES.atLeastOneToolRequired);
}
return selectedTools;
@@ -350,7 +351,7 @@ export class InitCommand {
const raw = this.toolsArg.trim();
if (raw.length === 0) {
throw new Error(
- 'The --tools option requires a value. Use "all", "none", or a comma-separated list of tool IDs.'
+ INIT_MESSAGES.toolsOptionRequired
);
}
@@ -374,14 +375,14 @@ export class InitCommand {
if (tokens.length === 0) {
throw new Error(
- 'The --tools option requires at least one tool ID when not using "all" or "none".'
+ INIT_MESSAGES.toolsOptionRequiresToolId
);
}
const normalizedTokens = tokens.map((token) => token.toLowerCase());
if (normalizedTokens.some((token) => token === 'all' || token === 'none')) {
- throw new Error('Cannot combine reserved values "all" or "none" with specific tool IDs.');
+ throw new Error(INIT_MESSAGES.cannotCombineReservedValues);
}
const invalidTokens = tokens.filter(
@@ -390,7 +391,7 @@ export class InitCommand {
if (invalidTokens.length > 0) {
throw new Error(
- `Invalid tool(s): ${invalidTokens.join(', ')}. Available values: ${availableList}`
+ INIT_MESSAGES.invalidTools(invalidTokens.join(', '), availableList)
);
}
@@ -416,14 +417,14 @@ export class InitCommand {
if (!tool) {
const validToolIds = getToolsWithSkillsDir();
throw new Error(
- `Unknown tool '${toolId}'. Valid tools:\n ${validToolIds.join('\n ')}`
+ INIT_MESSAGES.unknownTool(toolId, validToolIds.join('\n '))
);
}
if (!tool.skillsDir) {
const validToolsWithSkills = getToolsWithSkillsDir();
throw new Error(
- `Tool '${toolId}' does not support skill generation.\nTools with skill generation support:\n ${validToolsWithSkills.join('\n ')}`
+ INIT_MESSAGES.toolNoSkillSupport(toolId, validToolsWithSkills.join('\n '))
);
}
@@ -459,7 +460,7 @@ export class InitCommand {
return;
}
- const spinner = this.startSpinner('Creating OpenSpec structure...');
+ const spinner = this.startSpinner(INIT_MESSAGES.creatingStructure);
const directories = [
openspecPath,
@@ -474,7 +475,7 @@ export class InitCommand {
spinner.stopAndPersist({
symbol: PALETTE.white('▌'),
- text: PALETTE.white('OpenSpec structure created'),
+ text: PALETTE.white(INIT_MESSAGES.structureCreated),
});
}
@@ -514,7 +515,7 @@ export class InitCommand {
// Process each tool
for (const tool of tools) {
- const spinner = ora(`Setting up ${tool.name}...`).start();
+ const spinner = ora(INIT_MESSAGES.settingUp(tool.name)).start();
try {
// Generate skill files if delivery includes skills
@@ -559,7 +560,7 @@ export class InitCommand {
removedCommandCount += await this.removeCommandFiles(projectPath, tool.value);
}
- spinner.succeed(`Setup complete for ${tool.name}`);
+ spinner.succeed(INIT_MESSAGES.setupComplete(tool.name));
if (tool.wasConfigured) {
refreshedTools.push(tool);
@@ -567,7 +568,7 @@ export class InitCommand {
createdTools.push(tool);
}
} catch (error) {
- spinner.fail(`Failed for ${tool.name}`);
+ spinner.fail(INIT_MESSAGES.setupFailed(tool.name));
failedTools.push({ name: tool.name, error: error as Error });
}
}
@@ -628,15 +629,15 @@ export class InitCommand {
configStatus: 'created' | 'exists' | 'skipped'
): void {
console.log();
- console.log(chalk.bold('OpenSpec Setup Complete'));
+ console.log(chalk.bold(INIT_MESSAGES.setupCompleteTitle));
console.log();
// Show created vs refreshed tools
if (results.createdTools.length > 0) {
- console.log(`Created: ${results.createdTools.map((t) => t.name).join(', ')}`);
+ console.log(INIT_MESSAGES.created(results.createdTools.map((t) => t.name).join(', ')));
}
if (results.refreshedTools.length > 0) {
- console.log(`Refreshed: ${results.refreshedTools.map((t) => t.name).join(', ')}`);
+ console.log(INIT_MESSAGES.refreshed(results.refreshedTools.map((t) => t.name).join(', ')));
}
// Show counts (respecting profile filter)
@@ -660,31 +661,31 @@ export class InitCommand {
// Show failures
if (results.failedTools.length > 0) {
- console.log(chalk.red(`Failed: ${results.failedTools.map((f) => `${f.name} (${f.error.message})`).join(', ')}`));
+ console.log(chalk.red(INIT_MESSAGES.failed(results.failedTools.map((f) => `${f.name} (${f.error.message})`).join(', '))));
}
// Show skipped commands
if (results.commandsSkipped.length > 0) {
- console.log(chalk.dim(`Commands skipped for: ${results.commandsSkipped.join(', ')} (no adapter)`));
+ console.log(chalk.dim(INIT_MESSAGES.commandsSkipped(results.commandsSkipped.join(', '))));
}
if (results.removedCommandCount > 0) {
- console.log(chalk.dim(`Removed: ${results.removedCommandCount} command files (delivery: skills)`));
+ console.log(chalk.dim(INIT_MESSAGES.removedCommands(results.removedCommandCount)));
}
if (results.removedSkillCount > 0) {
- console.log(chalk.dim(`Removed: ${results.removedSkillCount} skill directories (delivery: commands)`));
+ console.log(chalk.dim(INIT_MESSAGES.removedSkills(results.removedSkillCount)));
}
// Config status
if (configStatus === 'created') {
- console.log(`Config: openspec/config.yaml (schema: ${DEFAULT_SCHEMA})`);
+ console.log(INIT_MESSAGES.configCreated(DEFAULT_SCHEMA));
} else if (configStatus === 'exists') {
// Show actual filename (config.yaml or config.yml)
const configYaml = path.join(projectPath, OPENSPEC_DIR_NAME, 'config.yaml');
const configYml = path.join(projectPath, OPENSPEC_DIR_NAME, 'config.yml');
const configName = fs.existsSync(configYaml) ? 'config.yaml' : fs.existsSync(configYml) ? 'config.yml' : 'config.yaml';
- console.log(`Config: openspec/${configName} (exists)`);
+ console.log(INIT_MESSAGES.configExists(configName));
} else {
- console.log(chalk.dim(`Config: skipped (non-interactive mode)`));
+ console.log(chalk.dim(INIT_MESSAGES.configSkipped));
}
// Getting started (task 7.6: show propose if in profile)
@@ -693,24 +694,24 @@ export class InitCommand {
const activeWorkflows = [...getProfileWorkflows(activeProfile, globalCfg.workflows)];
console.log();
if (activeWorkflows.includes('propose')) {
- console.log(chalk.bold('Getting started:'));
- console.log(' Start your first change: /opsx:propose "your idea"');
+ console.log(chalk.bold(INIT_MESSAGES.gettingStarted));
+ console.log(INIT_MESSAGES.startFirstChangePropose('/opsx:propose "sua ideia"'));
} else if (activeWorkflows.includes('new')) {
- console.log(chalk.bold('Getting started:'));
- console.log(' Start your first change: /opsx:new "your idea"');
+ console.log(chalk.bold(INIT_MESSAGES.gettingStarted));
+ console.log(INIT_MESSAGES.startFirstChangeNew('/opsx:new "sua ideia"'));
} else {
- console.log("Done. Run 'openspec config profile' to configure your workflows.");
+ console.log(INIT_MESSAGES.configureWorkflowsHint);
}
// Links
console.log();
- console.log(`Learn more: ${chalk.cyan('https://github.com/fkmatsuda/BR-OpenSpec')}`);
- console.log(`Feedback: ${chalk.cyan('https://github.com/fkmatsuda/BR-OpenSpec/issues')}`);
+ console.log(INIT_MESSAGES.learnMore(chalk.cyan('https://github.com/fkmatsuda/BR-OpenSpec')));
+ console.log(INIT_MESSAGES.feedback(chalk.cyan('https://github.com/fkmatsuda/BR-OpenSpec/issues')));
// Restart instruction if any tools were configured
if (results.createdTools.length > 0 || results.refreshedTools.length > 0) {
console.log();
- console.log(chalk.white('Restart your IDE for slash commands to take effect.'));
+ console.log(chalk.white(INIT_MESSAGES.restartIDE));
}
console.log();
diff --git a/src/core/list.ts b/src/core/list.ts
index 3f40829a63..72e2523bda 100644
--- a/src/core/list.ts
+++ b/src/core/list.ts
@@ -4,6 +4,7 @@ import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progre
import { readFileSync } from 'fs';
import { join } from 'path';
import { MarkdownParser } from './parsers/markdown-parser.js';
+import { LIST_MESSAGES } from '../messages/index.js';
interface ChangeInfo {
name: string;
@@ -64,13 +65,13 @@ function formatRelativeTime(date: Date): string {
if (diffDays > 30) {
return date.toLocaleDateString();
} else if (diffDays > 0) {
- return `${diffDays}d ago`;
+ return LIST_MESSAGES.relativeTime.daysAgo(diffDays);
} else if (diffHours > 0) {
- return `${diffHours}h ago`;
+ return LIST_MESSAGES.relativeTime.hoursAgo(diffHours);
} else if (diffMins > 0) {
- return `${diffMins}m ago`;
+ return LIST_MESSAGES.relativeTime.minutesAgo(diffMins);
} else {
- return 'just now';
+ return LIST_MESSAGES.relativeTime.justNow;
}
}
@@ -85,7 +86,7 @@ export class ListCommand {
try {
await fs.access(changesDir);
} catch {
- throw new Error("No OpenSpec changes directory found. Run 'openspec init' first.");
+ throw new Error(LIST_MESSAGES.noChangesDir);
}
// Get all directories in changes (excluding archive)
@@ -98,7 +99,7 @@ export class ListCommand {
if (json) {
console.log(JSON.stringify({ changes: [] }));
} else {
- console.log('No active changes found.');
+ console.log(LIST_MESSAGES.noActiveChanges);
}
return;
}
@@ -139,7 +140,7 @@ export class ListCommand {
}
// Display results
- console.log('Changes:');
+ console.log(LIST_MESSAGES.changesHeader);
const padding = ' ';
const nameWidth = Math.max(...changes.map(c => c.name.length));
for (const change of changes) {
@@ -156,14 +157,14 @@ export class ListCommand {
try {
await fs.access(specsDir);
} catch {
- console.log('No specs found.');
+ console.log(LIST_MESSAGES.noSpecsFound);
return;
}
const entries = await fs.readdir(specsDir, { withFileTypes: true });
const specDirs = entries.filter(e => e.isDirectory()).map(e => e.name);
if (specDirs.length === 0) {
- console.log('No specs found.');
+ console.log(LIST_MESSAGES.noSpecsFound);
return;
}
@@ -183,7 +184,7 @@ export class ListCommand {
}
specs.sort((a, b) => a.id.localeCompare(b.id));
- console.log('Specs:');
+ console.log(LIST_MESSAGES.specsHeader);
const padding = ' ';
const nameWidth = Math.max(...specs.map(s => s.id.length));
for (const spec of specs) {
diff --git a/src/core/migration.ts b/src/core/migration.ts
index 48aaa41eee..5250b911be 100644
--- a/src/core/migration.ts
+++ b/src/core/migration.ts
@@ -5,6 +5,7 @@
* Called by both init and update commands before profile resolution.
*/
+import { MIGRATION_MESSAGES } from '../messages/index.js';
import type { AIToolOption } from './config.js';
import { getGlobalConfig, getGlobalConfigPath, saveGlobalConfig, type Delivery } from './global-config.js';
import { CommandAdapterRegistry } from './command-generation/index.js';
@@ -126,6 +127,6 @@ export function migrateIfNeeded(projectPath: string, tools: AIToolOption[]): voi
}
saveGlobalConfig(config);
- console.log(`Migrated: custom profile with ${installedWorkflows.length} workflows`);
- console.log("New in this version: /opsx:propose. Try 'openspec config profile core' for the streamlined experience.");
+ console.log(MIGRATION_MESSAGES.migrated(installedWorkflows.length));
+ console.log(MIGRATION_MESSAGES.newInThisVersion);
}
diff --git a/src/core/project-config.ts b/src/core/project-config.ts
index 6c1ea04a5b..7bc4788e73 100644
--- a/src/core/project-config.ts
+++ b/src/core/project-config.ts
@@ -1,3 +1,4 @@
+import { PROJECT_CONFIG_MESSAGES } from '../messages/index.js';
import { existsSync, readFileSync, statSync } from 'fs';
import path from 'path';
import { parse as parseYaml } from 'yaml';
@@ -90,7 +91,7 @@ export function readProjectConfig(projectRoot: string): ProjectConfig | null {
if (schemaResult.success) {
config.schema = schemaResult.data;
} else if (raw.schema !== undefined) {
- console.warn(`Invalid 'schema' field in config (must be non-empty string)`);
+ console.warn(PROJECT_CONFIG_MESSAGES.invalidSchemaField);
}
// Parse context field with size limit
@@ -102,14 +103,14 @@ export function readProjectConfig(projectRoot: string): ProjectConfig | null {
const contextSize = Buffer.byteLength(contextResult.data, 'utf-8');
if (contextSize > MAX_CONTEXT_SIZE) {
console.warn(
- `Context too large (${(contextSize / 1024).toFixed(1)}KB, limit: ${MAX_CONTEXT_SIZE / 1024}KB)`
+ PROJECT_CONFIG_MESSAGES.contextTooLarge((contextSize / 1024).toFixed(1), String(MAX_CONTEXT_SIZE / 1024))
);
- console.warn(`Ignoring context field`);
+ console.warn(PROJECT_CONFIG_MESSAGES.ignoringContextField);
} else {
config.context = contextResult.data;
}
} else {
- console.warn(`Invalid 'context' field in config (must be string)`);
+ console.warn(PROJECT_CONFIG_MESSAGES.invalidContextField);
}
}
@@ -134,12 +135,12 @@ export function readProjectConfig(projectRoot: string): ProjectConfig | null {
}
if (validRules.length < rulesArrayResult.data.length) {
console.warn(
- `Some rules for '${artifactId}' are empty strings, ignoring them`
+ PROJECT_CONFIG_MESSAGES.emptyRulesForArtifact(artifactId)
);
}
} else {
console.warn(
- `Rules for '${artifactId}' must be an array of strings, ignoring this artifact's rules`
+ PROJECT_CONFIG_MESSAGES.rulesMustBeArrayOfStrings(artifactId)
);
}
}
@@ -148,7 +149,7 @@ export function readProjectConfig(projectRoot: string): ProjectConfig | null {
config.rules = parsedRules;
}
} else {
- console.warn(`Invalid 'rules' field in config (must be object)`);
+ console.warn(PROJECT_CONFIG_MESSAGES.invalidRulesField);
}
}
diff --git a/src/core/templates/workflows/apply-change.ts b/src/core/templates/workflows/apply-change.ts
index be60210a7a..6b7425d34d 100644
--- a/src/core/templates/workflows/apply-change.ts
+++ b/src/core/templates/workflows/apply-change.ts
@@ -9,154 +9,154 @@ import type { SkillTemplate, CommandTemplate } from '../types.js';
export function getApplyChangeSkillTemplate(): SkillTemplate {
return {
name: 'openspec-apply-change',
- description: 'Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.',
- instructions: `Implement tasks from an OpenSpec change.
+ description: 'Implementa tarefas de uma change do OpenSpec. Use quando o usuário quiser iniciar a implementação, continuar a implementação ou trabalhar nas tarefas.',
+ instructions: `Implementa tarefas de uma change do OpenSpec.
-**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
+**Entrada**: Opcionalmente especifique um nome de change. Se omitido, verifique se pode ser inferido do contexto da conversa. Se vago ou ambíguo, você DEVE solicitar as changes disponíveis.
-**Steps**
+**Passos**
-1. **Select the change**
+1. **Selecione a change**
- If a name is provided, use it. Otherwise:
- - Infer from conversation context if the user mentioned a change
- - Auto-select if only one active change exists
- - If ambiguous, run \`openspec list --json\` to get available changes and use the **AskUserQuestion tool** to let the user select
+ Se um nome for fornecido, use-o. Caso contrário:
+ - Infira do contexto da conversa se o usuário mencionou uma change
+ - Selecione automaticamente se existir apenas uma change ativa
+ - Se ambíguo, execute \`openspec list --json\` para obter as changes disponíveis e use a ferramenta **AskUserQuestion** para permitir que o usuário selecione
- Always announce: "Using change: " and how to override (e.g., \`/opsx:apply \`).
+ Sempre anuncie: "Usando change: " e como substituir (por exemplo, \`/opsx:apply \`).
-2. **Check status to understand the schema**
+2. **Verifique o status para entender o schema**
\`\`\`bash
- openspec status --change "" --json
+ openspec status --change "" --json
\`\`\`
- Parse the JSON to understand:
- - \`schemaName\`: The workflow being used (e.g., "spec-driven")
- - Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)
+ Analise o JSON para entender:
+ - \`schemaName\`: O workflow sendo usado (por exemplo, "spec-driven")
+ - Qual artifact contém as tarefas (tipicamente "tasks" para spec-driven, verifique o status para outros)
-3. **Get apply instructions**
+3. **Obtenha as instruções de apply**
\`\`\`bash
- openspec instructions apply --change "" --json
+ openspec instructions apply --change "" --json
\`\`\`
- This returns:
- - \`contextFiles\`: artifact ID -> array of concrete file paths (varies by schema - could be proposal/specs/design/tasks or spec/tests/implementation/docs)
- - Progress (total, complete, remaining)
- - Task list with status
- - Dynamic instruction based on current state
+ Isso retorna:
+ - \`contextFiles\`: artifact ID -> array de caminhos de arquivos concretos (varia por schema - pode ser proposal/specs/design/tasks ou spec/tests/implementation/docs)
+ - Progresso (total, completo, restante)
+ - Lista de tarefas com status
+ - Instrução dinâmica baseada no estado atual
- **Handle states:**
- - If \`state: "blocked"\` (missing artifacts): show message, suggest using openspec-continue-change
- - If \`state: "all_done"\`: congratulate, suggest archive
- - Otherwise: proceed to implementation
+ **Trate os estados:**
+ - Se \`state: "blocked"\` (artifacts ausentes): exiba mensagem, sugira usar openspec-continue-change
+ - Se \`state: "all_done"\`: parabenize, sugira arquivar
+ - Caso contrário: prossiga para a implementação
-4. **Read context files**
+4. **Leia os arquivos de contexto**
- Read every file path listed under \`contextFiles\` from the apply instructions output.
- The files depend on the schema being used:
+ Leia cada caminho de arquivo listado em \`contextFiles\` da saída das instruções de apply.
+ Os arquivos dependem do schema sendo usado:
- **spec-driven**: proposal, specs, design, tasks
- - Other schemas: follow the contextFiles from CLI output
+ - Outros schemas: siga os contextFiles da saída do CLI
-5. **Show current progress**
+5. **Mostre o progresso atual**
- Display:
- - Schema being used
- - Progress: "N/M tasks complete"
- - Remaining tasks overview
- - Dynamic instruction from CLI
+ Exiba:
+ - Schema sendo usado
+ - Progresso: "N/M tarefas concluídas"
+ - Visão geral das tarefas restantes
+ - Instrução dinâmica do CLI
-6. **Implement tasks (loop until done or blocked)**
+6. **Implemente as tarefas (loop até concluir ou bloquear)**
- For each pending task:
- - Show which task is being worked on
- - Make the code changes required
- - Keep changes minimal and focused
- - Mark task complete in the tasks file: \`- [ ]\` → \`- [x]\`
- - Continue to next task
+ Para cada tarefa pendente:
+ - Mostre qual tarefa está sendo trabalhada
+ - Faça as alterações de código necessárias
+ - Mantenha as alterações mínimas e focadas
+ - Marque a tarefa como concluída no arquivo de tasks: \`- [ ]\` → \`- [x]\`
+ - Continue para a próxima tarefa
- **Pause if:**
- - Task is unclear → ask for clarification
- - Implementation reveals a design issue → suggest updating artifacts
- - Error or blocker encountered → report and wait for guidance
- - User interrupts
+ **Pare se:**
+ - A tarefa estiver incerta → peça esclarecimento
+ - A implementação revelar um problema de design → sugira atualizar artifacts
+ - Encontrar erro ou bloqueio → reporte e aguarde orientação
+ - O usuário interromper
-7. **On completion or pause, show status**
+7. **Ao concluir ou pausar, mostre o status**
- Display:
- - Tasks completed this session
- - Overall progress: "N/M tasks complete"
- - If all done: suggest archive
- - If paused: explain why and wait for guidance
+ Exiba:
+ - Tarefas concluídas nesta sessão
+ - Progresso geral: "N/M tarefas concluídas"
+ - Se tudo concluído: sugira arquivar
+ - Se pausado: explique o porquê e aguarde orientação
-**Output During Implementation**
+**Saída Durante a Implementação**
\`\`\`
-## Implementing: (schema: )
+## Implementando: (schema: )
-Working on task 3/7:
-[...implementation happening...]
-✓ Task complete
+Trabalhando na tarefa 3/7:
+[...implementação acontecendo...]
+✓ Tarefa concluída
-Working on task 4/7:
-[...implementation happening...]
-✓ Task complete
+Trabalhando na tarefa 4/7:
+[...implementação acontecendo...]
+✓ Tarefa concluída
\`\`\`
-**Output On Completion**
+**Saída ao Concluir**
\`\`\`
-## Implementation Complete
+## Implementação Concluída
-**Change:**
-**Schema:**
-**Progress:** 7/7 tasks complete ✓
+**Change:**
+**Schema:**
+**Progresso:** 7/7 tarefas concluídas ✓
-### Completed This Session
-- [x] Task 1
-- [x] Task 2
+### Concluídas Nesta Sessão
+- [x] Tarefa 1
+- [x] Tarefa 2
...
-All tasks complete! Ready to archive this change.
+Todas as tarefas concluídas! Pronto para arquivar esta change.
\`\`\`
-**Output On Pause (Issue Encountered)**
+**Saída ao Pausar (Problema Encontrado)**
\`\`\`
-## Implementation Paused
+## Implementação Pausada
-**Change:**
-**Schema:**
-**Progress:** 4/7 tasks complete
+**Change:**
+**Schema:**
+**Progresso:** 4/7 tarefas concluídas
-### Issue Encountered
-
+### Problema Encontrado
+
-**Options:**
-1.
-2.
-3. Other approach
+**Opções:**
+1.
+2.
+3. Outra abordagem
-What would you like to do?
+O que você gostaria de fazer?
\`\`\`
**Guardrails**
-- Keep going through tasks until done or blocked
-- Always read context files before starting (from the apply instructions output)
-- If task is ambiguous, pause and ask before implementing
-- If implementation reveals issues, pause and suggest artifact updates
-- Keep code changes minimal and scoped to each task
-- Update task checkbox immediately after completing each task
-- Pause on errors, blockers, or unclear requirements - don't guess
-- Use contextFiles from CLI output, don't assume specific file names
+- Continue pelas tarefas até concluir ou bloquear
+- Sempre leia os arquivos de contexto antes de começar (da saída das instruções de apply)
+- Se a tarefa for ambígua, pause e pergunte antes de implementar
+- Se a implementação revelar problemas, pause e sugira atualizar artifacts
+- Mantenha as alterações de código mínimas e limitadas a cada tarefa
+- Atualize a checkbox da tarefa imediatamente após concluir cada tarefa
+- Pare em erros, bloqueios ou requisitos incertos - não adivinhe
+- Use os contextFiles da saída do CLI, não assuma nomes de arquivos específicos
-**Fluid Workflow Integration**
+**Integração com Fluxo Fluido**
-This skill supports the "actions on a change" model:
+Esta skill suporta o modelo de "ações em uma change":
-- **Can be invoked anytime**: Before all artifacts are done (if tasks exist), after partial implementation, interleaved with other actions
-- **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly`,
+- **Pode ser invocada a qualquer momento**: Antes de todos os artifacts estarem prontos (se tasks existirem), após implementação parcial, intercalada com outras ações
+- **Permite atualizações de artifacts**: Se a implementação revelar problemas de design, sugira atualizar artifacts - não está travada em fases, trabalhe de forma fluida`,
license: 'MIT',
- compatibility: 'Requires openspec CLI.',
+ compatibility: 'Requer openspec CLI.',
metadata: { author: 'openspec', version: '1.0' },
};
}
@@ -164,153 +164,153 @@ This skill supports the "actions on a change" model:
export function getOpsxApplyCommandTemplate(): CommandTemplate {
return {
name: 'OPSX: Apply',
- description: 'Implement tasks from an OpenSpec change (Experimental)',
+ description: 'Implementa tarefas de uma change do OpenSpec (Experimental)',
category: 'Workflow',
tags: ['workflow', 'artifacts', 'experimental'],
- content: `Implement tasks from an OpenSpec change.
+ content: `Implementa tarefas de uma change do OpenSpec.
-**Input**: Optionally specify a change name (e.g., \`/opsx:apply add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
+**Entrada**: Opcionalmente especifique um nome de change (por exemplo, \`/opsx:apply add-auth\`). Se omitido, verifique se pode ser inferido do contexto da conversa. Se vago ou ambíguo, você DEVE solicitar as changes disponíveis.
-**Steps**
+**Passos**
-1. **Select the change**
+1. **Selecione a change**
- If a name is provided, use it. Otherwise:
- - Infer from conversation context if the user mentioned a change
- - Auto-select if only one active change exists
- - If ambiguous, run \`openspec list --json\` to get available changes and use the **AskUserQuestion tool** to let the user select
+ Se um nome for fornecido, use-o. Caso contrário:
+ - Infira do contexto da conversa se o usuário mencionou uma change
+ - Selecione automaticamente se existir apenas uma change ativa
+ - Se ambíguo, execute \`openspec list --json\` para obter as changes disponíveis e use a ferramenta **AskUserQuestion** para permitir que o usuário selecione
- Always announce: "Using change: " and how to override (e.g., \`/opsx:apply \`).
+ Sempre anuncie: "Usando change: " e como substituir (por exemplo, \`/opsx:apply \`).
-2. **Check status to understand the schema**
+2. **Verifique o status para entender o schema**
\`\`\`bash
- openspec status --change "" --json
+ openspec status --change "" --json
\`\`\`
- Parse the JSON to understand:
- - \`schemaName\`: The workflow being used (e.g., "spec-driven")
- - Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)
+ Analise o JSON para entender:
+ - \`schemaName\`: O workflow sendo usado (por exemplo, "spec-driven")
+ - Qual artifact contém as tarefas (tipicamente "tasks" para spec-driven, verifique o status para outros)
-3. **Get apply instructions**
+3. **Obtenha as instruções de apply**
\`\`\`bash
- openspec instructions apply --change "" --json
+ openspec instructions apply --change "" --json
\`\`\`
- This returns:
- - \`contextFiles\`: artifact ID -> array of concrete file paths (varies by schema)
- - Progress (total, complete, remaining)
- - Task list with status
- - Dynamic instruction based on current state
+ Isso retorna:
+ - \`contextFiles\`: artifact ID -> array de caminhos de arquivos concretos (varia por schema)
+ - Progresso (total, completo, restante)
+ - Lista de tarefas com status
+ - Instrução dinâmica baseada no estado atual
- **Handle states:**
- - If \`state: "blocked"\` (missing artifacts): show message, suggest using \`/opsx:continue\`
- - If \`state: "all_done"\`: congratulate, suggest archive
- - Otherwise: proceed to implementation
+ **Trate os estados:**
+ - Se \`state: "blocked"\` (artifacts ausentes): exiba mensagem, sugira usar \`/opsx:continue\`
+ - Se \`state: "all_done"\`: parabenize, sugira arquivar
+ - Caso contrário: prossiga para a implementação
-4. **Read context files**
+4. **Leia os arquivos de contexto**
- Read every file path listed under \`contextFiles\` from the apply instructions output.
- The files depend on the schema being used:
+ Leia cada caminho de arquivo listado em \`contextFiles\` da saída das instruções de apply.
+ Os arquivos dependem do schema sendo usado:
- **spec-driven**: proposal, specs, design, tasks
- - Other schemas: follow the contextFiles from CLI output
+ - Outros schemas: siga os contextFiles da saída do CLI
-5. **Show current progress**
+5. **Mostre o progresso atual**
- Display:
- - Schema being used
- - Progress: "N/M tasks complete"
- - Remaining tasks overview
- - Dynamic instruction from CLI
+ Exiba:
+ - Schema sendo usado
+ - Progresso: "N/M tarefas concluídas"
+ - Visão geral das tarefas restantes
+ - Instrução dinâmica do CLI
-6. **Implement tasks (loop until done or blocked)**
+6. **Implemente as tarefas (loop até concluir ou bloquear)**
- For each pending task:
- - Show which task is being worked on
- - Make the code changes required
- - Keep changes minimal and focused
- - Mark task complete in the tasks file: \`- [ ]\` → \`- [x]\`
- - Continue to next task
+ Para cada tarefa pendente:
+ - Mostre qual tarefa está sendo trabalhada
+ - Faça as alterações de código necessárias
+ - Mantenha as alterações mínimas e focadas
+ - Marque a tarefa como concluída no arquivo de tasks: \`- [ ]\` → \`- [x]\`
+ - Continue para a próxima tarefa
- **Pause if:**
- - Task is unclear → ask for clarification
- - Implementation reveals a design issue → suggest updating artifacts
- - Error or blocker encountered → report and wait for guidance
- - User interrupts
+ **Pare se:**
+ - A tarefa estiver incerta → peça esclarecimento
+ - A implementação revelar um problema de design → sugira atualizar artifacts
+ - Encontrar erro ou bloqueio → reporte e aguarde orientação
+ - O usuário interromper
-7. **On completion or pause, show status**
+7. **Ao concluir ou pausar, mostre o status**
- Display:
- - Tasks completed this session
- - Overall progress: "N/M tasks complete"
- - If all done: suggest archive
- - If paused: explain why and wait for guidance
+ Exiba:
+ - Tarefas concluídas nesta sessão
+ - Progresso geral: "N/M tarefas concluídas"
+ - Se tudo concluído: sugira arquivar
+ - Se pausado: explique o porquê e aguarde orientação
-**Output During Implementation**
+**Saída Durante a Implementação**
\`\`\`
-## Implementing: (schema: