stk-codegen 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +70 -0
- package/README.md +213 -0
- package/dist/96.index.js +189 -0
- package/dist/984.index.js +99 -0
- package/dist/App.d.ts +4 -0
- package/dist/cli.d.ts +1 -0
- package/dist/components/AgentStatus.d.ts +6 -0
- package/dist/components/Conversation.d.ts +11 -0
- package/dist/components/DiffView.d.ts +9 -0
- package/dist/components/EscapeClearIndicator.d.ts +3 -0
- package/dist/components/ExitIndicator.d.ts +3 -0
- package/dist/components/Footer.d.ts +3 -0
- package/dist/components/Input.d.ts +13 -0
- package/dist/components/Message.d.ts +11 -0
- package/dist/components/ShellConfirmation.d.ts +6 -0
- package/dist/components/ShellExecution.d.ts +9 -0
- package/dist/components/SplashScreen.d.ts +4 -0
- package/dist/components/ToolExecution.d.ts +8 -0
- package/dist/config.d.ts +8 -0
- package/dist/hooks/hooks.d.ts +5 -0
- package/dist/hooks/useAgent.d.ts +28 -0
- package/dist/hooks/useMagicCommands.d.ts +1 -0
- package/dist/index.js +112 -0
- package/dist/package.json +3 -0
- package/dist/services/versionCheck.d.ts +1 -0
- package/dist/services/websocketClient.d.ts +17 -0
- package/dist/tools/Edit.d.ts +14 -0
- package/dist/tools/FindFiles.d.ts +12 -0
- package/dist/tools/GoogleSearch.d.ts +9 -0
- package/dist/tools/ReadFile.d.ts +11 -0
- package/dist/tools/ReadFolder.d.ts +12 -0
- package/dist/tools/ReadManyFiles.d.ts +10 -0
- package/dist/tools/SaveMemory.d.ts +9 -0
- package/dist/tools/SearchText.d.ts +18 -0
- package/dist/tools/Shell.d.ts +11 -0
- package/dist/tools/WebFetch.d.ts +9 -0
- package/dist/tools/WriteFile.d.ts +10 -0
- package/dist/tools/WriteTodos.d.ts +9 -0
- package/dist/tools/index.d.ts +12 -0
- package/dist/tools/runShellCommandAsync.d.ts +2 -0
- package/dist/types/index.d.ts +116 -0
- package/dist/utils/display.d.ts +1 -0
- package/dist/utils/keyMatchers.d.ts +3 -0
- package/dist/utils/paths.d.ts +1 -0
- package/dist/utils/projectSpecLoader.d.ts +5 -0
- package/dist/utils/text-buffer.d.ts +25 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Business Source License 1.1
|
|
3
|
+
|
|
4
|
+
This License is made available by the Licensor under the terms of the Business Source License Version 1.1.
|
|
5
|
+
It is a "source-available" license that ensures the software remains proprietary for a specified "Change Date"
|
|
6
|
+
and then converts to an Open Source License.
|
|
7
|
+
|
|
8
|
+
Before the Change Date you may use this software as provided, copy, distribute, make available, and prepare
|
|
9
|
+
derivative works of this software, but you may not use this software for production purposes (meaning for use
|
|
10
|
+
in a live, operational system or service that is used by anyone other than yourself or a limited number of
|
|
11
|
+
designated testing users), or offer this software as a service, or any similar offering that competes with
|
|
12
|
+
the Licensor’s business of providing this software.
|
|
13
|
+
|
|
14
|
+
On the Change Date, the software will be relicensed under the Change License.
|
|
15
|
+
|
|
16
|
+
Licensor: Pedro Naves
|
|
17
|
+
Change Date: 2028-11-27
|
|
18
|
+
Change License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
19
|
+
|
|
20
|
+
This Business Source License (this "License") applies to the software ("Software") identified in
|
|
21
|
+
this header.
|
|
22
|
+
|
|
23
|
+
By exercising any rights to the Software, You agree to be bound by the terms of this License.
|
|
24
|
+
To the extent this License is deemed a "Contributor Agreement", "Contributor" refers to You.
|
|
25
|
+
You represent that You are of legal age to form a binding contract.
|
|
26
|
+
|
|
27
|
+
1. Definitions.
|
|
28
|
+
"Change Date" is the date specified in the header.
|
|
29
|
+
"Change License" is the license specified in the header.
|
|
30
|
+
"Licensor" is the entity specified in the header.
|
|
31
|
+
"Software" means the computer program identified in this header, in object code and source code form,
|
|
32
|
+
and any accompanying documentation.
|
|
33
|
+
"You" (or "Your") means an individual or legal entity exercising rights under this License.
|
|
34
|
+
|
|
35
|
+
2. Permitted Uses.
|
|
36
|
+
You may use, copy, distribute, make available, and prepare derivative works of the Software, provided that
|
|
37
|
+
You do not use the Software for:
|
|
38
|
+
a) production purposes (meaning for use in a live, operational system or service that is used by anyone
|
|
39
|
+
other than Yourself or a limited number of designated testing users);
|
|
40
|
+
b) offering the Software as a service; or
|
|
41
|
+
c) any similar offering that competes with the Licensor’s business of providing the Software.
|
|
42
|
+
|
|
43
|
+
This Section 2 applies before the Change Date.
|
|
44
|
+
|
|
45
|
+
3. Change Date.
|
|
46
|
+
On the Change Date, the Software will be relicensed under the Change License.
|
|
47
|
+
|
|
48
|
+
4. No Warranties.
|
|
49
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
50
|
+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
51
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
52
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
53
|
+
DEALINGS IN THE SOFTWARE.
|
|
54
|
+
|
|
55
|
+
5. Limitation of Liability.
|
|
56
|
+
IN NO EVENT WILL LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
57
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
58
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
59
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
60
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
61
|
+
|
|
62
|
+
6. General.
|
|
63
|
+
This License is governed by the laws of State of São Paulo, Brazil, excluding its conflict of laws provisions.
|
|
64
|
+
If any provision of this License is held to be unenforceable, that provision will be removed, and the
|
|
65
|
+
remaining provisions will remain in full force and effect.
|
|
66
|
+
The Licensor may modify this License from time to time by publishing a new version of this License with
|
|
67
|
+
a new effective date.
|
|
68
|
+
This License constitutes the entire agreement between You and the Licensor concerning the Software,
|
|
69
|
+
and it supersedes all prior or contemporaneous understandings, communications, or agreements.
|
|
70
|
+
*/
|
package/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# CodeGen CLI Executor
|
|
2
|
+
|
|
3
|
+
CLI interativa (TUI com Ink/React) para se conectar a um agente CodeGen via HTTP/WebSocket.
|
|
4
|
+
|
|
5
|
+
Este README foca em como qualquer desenvolvedor pode **clonar, configurar, rodar, testar e depurar** o CLI em ambiente local.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Pré‑requisitos
|
|
10
|
+
|
|
11
|
+
- [Node.js](https://nodejs.org/) (versão LTS recomendada)
|
|
12
|
+
- [npm](https://www.npmjs.com/) (vem junto com o Node.js)
|
|
13
|
+
- Backend HTTP/WebSocket compatível com o protocolo do CodeGen CLI, exposto (por padrão) em `http://localhost:8000`
|
|
14
|
+
|
|
15
|
+
> Dica: este repositório **não** inclui o backend; ele precisa estar rodando em outro processo/máquina.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. Instalação do projeto
|
|
20
|
+
|
|
21
|
+
1. Clone o repositório e entre na pasta do projeto:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git clone <URL_DO_REPO>
|
|
25
|
+
cd cli_executor
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Instale as dependências:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. Configuração do backend
|
|
37
|
+
|
|
38
|
+
O CLI depende de um backend para:
|
|
39
|
+
- Criar/retomar sessões de conversa (HTTP + WebSocket)
|
|
40
|
+
- Verificar a versão do CLI (version check obrigatório na inicialização)
|
|
41
|
+
|
|
42
|
+
### 3.1. URL do backend
|
|
43
|
+
|
|
44
|
+
A URL base do backend é lida da variável de ambiente `CLI_BACKEND_URL`.
|
|
45
|
+
|
|
46
|
+
- Caso **não** seja definida, será usado o valor padrão:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
http://localhost:8000
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- Para apontar para outro servidor (por exemplo, staging ou remoto), defina antes de rodar o CLI:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
export CLI_BACKEND_URL="http://meu-backend:8000"
|
|
56
|
+
# ou no Windows (PowerShell):
|
|
57
|
+
# $env:CLI_BACKEND_URL = "http://meu-backend:8000"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3.2. Endpoints esperados
|
|
61
|
+
|
|
62
|
+
O backend deve expor pelo menos:
|
|
63
|
+
|
|
64
|
+
1. **Version check** (obrigatório na inicialização):
|
|
65
|
+
|
|
66
|
+
- Método: `GET`
|
|
67
|
+
- URL: `${CLI_BACKEND_URL}/v1/cli/version`
|
|
68
|
+
- Resposta esperada:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"version": "1.0.1"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
O valor deve estar sincronizado com:
|
|
77
|
+
- `version` em `package.json`
|
|
78
|
+
- `config.CURRENT_VERSION` em `src/config.ts`
|
|
79
|
+
|
|
80
|
+
Se a versão retornada for diferente, o CLI tentará um auto‑update via `npm install -g cli_executor-<version>.tgz`.
|
|
81
|
+
|
|
82
|
+
2. **Criação de sessão**:
|
|
83
|
+
|
|
84
|
+
- Método: `POST`
|
|
85
|
+
- URL: `${CLI_BACKEND_URL}/v1/tasks`
|
|
86
|
+
- Corpo mínimo esperado (do lado do CLI):
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"prompt": "New interactive session"
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- Resposta esperada:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"id": "<SESSION_ID>"
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
3. **WebSocket da sessão**:
|
|
103
|
+
|
|
104
|
+
- URL: `${CLI_BACKEND_URL}/v1/ws/session/start_or_resume/<SESSION_ID>`
|
|
105
|
+
- Protocolo de mensagens em JSON (handshake + mensagens do agente + comandos de ferramenta).
|
|
106
|
+
|
|
107
|
+
> Importante: **inicie o backend** antes de rodar o CLI, caso contrário o version check e a criação de sessão vão falhar.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 4. Rodando o CLI em modo desenvolvimento
|
|
112
|
+
|
|
113
|
+
O fluxo mais simples para compilar e executar o CLI é usar o script `start`:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm run start
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Esse comando executa:
|
|
120
|
+
1. `npm run build` – compila o código TypeScript em `dist/`
|
|
121
|
+
2. `node dist/cli.js` – roda o binário da CLI (entrypoint `src/cli.tsx`)
|
|
122
|
+
|
|
123
|
+
### 4.1. Rodar diretamente o binário compilado
|
|
124
|
+
|
|
125
|
+
Depois de rodar `npm run build` pelo menos uma vez, você pode executar diretamente:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
node dist/cli.js
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Ou, se quiser usar o bin definido no `package.json` (`codegen-cli`) de forma global:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# dentro do diretório do projeto
|
|
135
|
+
npm link
|
|
136
|
+
|
|
137
|
+
# em qualquer lugar
|
|
138
|
+
codegen-cli
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
> Se preferir, você também pode publicar/instalar o pacote como global (`npm install -g`), desde que tenha cuidado para manter a versão alinhada com o backend.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 5. Scripts disponíveis (npm scripts)
|
|
146
|
+
|
|
147
|
+
### 5.1. Build
|
|
148
|
+
|
|
149
|
+
Compila o código TypeScript para JavaScript em `dist/` usando `tsc`:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
npm run build
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 5.2. Testes
|
|
156
|
+
|
|
157
|
+
Roda a suíte de testes com [Vitest](https://vitest.dev/):
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm test
|
|
161
|
+
``;
|
|
162
|
+
|
|
163
|
+
- Os testes estão sob `src/**/*.test.{ts,tsx}`.
|
|
164
|
+
- O ambiente de teste é `jsdom`, adequado para componentes Ink/React.
|
|
165
|
+
|
|
166
|
+
### 5.3. Start (build + execução)
|
|
167
|
+
|
|
168
|
+
Atalho para buildar e executar o CLI em sequência:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
npm run start
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 6. Fluxo de desenvolvimento
|
|
177
|
+
|
|
178
|
+
Sugestão de workflow para mexer no código:
|
|
179
|
+
|
|
180
|
+
1. Garanta que o backend está rodando (`CLI_BACKEND_URL` apontando para ele).
|
|
181
|
+
2. Rode os testes unitários/localmente conforme for alterando o código:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npm test
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
3. Para testar a experiência interativa da CLI:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npm run start
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
4. Ao mexer em funcionalidades que dependem de ferramentas locais (filesystem, shell, busca, etc.), teste num diretório de trabalho isolado para evitar efeitos colaterais indesejados.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 7. Problemas comuns
|
|
198
|
+
|
|
199
|
+
- **Erro de versão / auto‑update falhando**
|
|
200
|
+
- Verifique se o endpoint `/v1/cli/version` está acessível e retornando JSON válido.
|
|
201
|
+
- Confirme se a versão bate com a do `package.json` e de `src/config.ts`.
|
|
202
|
+
|
|
203
|
+
- **Falha ao criar sessão (`/v1/tasks`)**
|
|
204
|
+
- Cheque se o backend está rodando e se a `CLI_BACKEND_URL` está configurada corretamente.
|
|
205
|
+
- Veja logs do backend para entender o erro.
|
|
206
|
+
|
|
207
|
+
- **WebSocket não conecta / desconecta imediatamente**
|
|
208
|
+
- Confirme se a URL de WebSocket está correta (`/v1/ws/session/start_or_resume/{sessionId}`).
|
|
209
|
+
- Verifique se não há firewall/bloqueio de rede entre o CLI e o backend.
|
|
210
|
+
|
|
211
|
+
Se precisar de mais detalhes sobre arquitetura, padrões e decisões do projeto, consulte o arquivo [`CODEGEN.md`](./CODEGEN.md).
|
|
212
|
+
|
|
213
|
+
---
|
package/dist/96.index.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
export const id = 96;
|
|
2
|
+
export const ids = [96];
|
|
3
|
+
export const modules = {
|
|
4
|
+
|
|
5
|
+
/***/ 2096:
|
|
6
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
7
|
+
|
|
8
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
9
|
+
/* harmony export */ loadProjectSpec: () => (/* binding */ loadProjectSpec)
|
|
10
|
+
/* harmony export */ });
|
|
11
|
+
/* harmony import */ var node_fs_promises__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1455);
|
|
12
|
+
/* harmony import */ var node_fs_promises__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(node_fs_promises__WEBPACK_IMPORTED_MODULE_0__);
|
|
13
|
+
/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6760);
|
|
14
|
+
/* harmony import */ var node_path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(node_path__WEBPACK_IMPORTED_MODULE_1__);
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async function findProjectRoot(startDir) {
|
|
18
|
+
let currentDir = node_path__WEBPACK_IMPORTED_MODULE_1__.resolve(startDir);
|
|
19
|
+
// Walk upwards until we find a .git directory or hit filesystem root
|
|
20
|
+
while (true) {
|
|
21
|
+
const gitPath = node_path__WEBPACK_IMPORTED_MODULE_1__.join(currentDir, '.git');
|
|
22
|
+
try {
|
|
23
|
+
const stats = await node_fs_promises__WEBPACK_IMPORTED_MODULE_0__.lstat(gitPath);
|
|
24
|
+
if (stats.isDirectory()) {
|
|
25
|
+
return currentDir;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// .git not found here, keep going up
|
|
30
|
+
}
|
|
31
|
+
const parentDir = node_path__WEBPACK_IMPORTED_MODULE_1__.dirname(currentDir);
|
|
32
|
+
if (parentDir === currentDir) {
|
|
33
|
+
// Reached filesystem root, fall back to startDir
|
|
34
|
+
return node_path__WEBPACK_IMPORTED_MODULE_1__.resolve(startDir);
|
|
35
|
+
}
|
|
36
|
+
currentDir = parentDir;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function isSubpath(parent, candidate) {
|
|
40
|
+
const parentResolved = node_path__WEBPACK_IMPORTED_MODULE_1__.resolve(parent);
|
|
41
|
+
const candidateResolved = node_path__WEBPACK_IMPORTED_MODULE_1__.resolve(candidate);
|
|
42
|
+
if (parentResolved === candidateResolved)
|
|
43
|
+
return true;
|
|
44
|
+
const rel = node_path__WEBPACK_IMPORTED_MODULE_1__.relative(parentResolved, candidateResolved);
|
|
45
|
+
return !!rel && !rel.startsWith('..') && !node_path__WEBPACK_IMPORTED_MODULE_1__.isAbsolute(rel);
|
|
46
|
+
}
|
|
47
|
+
function validateImportPath(importPath, basePath, allowedRoot) {
|
|
48
|
+
// Reject URLs
|
|
49
|
+
if (/^(file|https?):\/\//.test(importPath)) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const resolved = node_path__WEBPACK_IMPORTED_MODULE_1__.resolve(basePath, importPath);
|
|
53
|
+
if (!isSubpath(allowedRoot, resolved)) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return resolved;
|
|
57
|
+
}
|
|
58
|
+
function findImports(content) {
|
|
59
|
+
const results = [];
|
|
60
|
+
let i = 0;
|
|
61
|
+
const len = content.length;
|
|
62
|
+
while (i < len) {
|
|
63
|
+
const atIndex = content.indexOf('@', i);
|
|
64
|
+
if (atIndex === -1)
|
|
65
|
+
break;
|
|
66
|
+
// Require word boundary before '@' (start of line or whitespace)
|
|
67
|
+
if (atIndex > 0) {
|
|
68
|
+
const prev = content[atIndex - 1];
|
|
69
|
+
if (prev !== ' ' && prev !== '\t' && prev !== '\n' && prev !== '\r') {
|
|
70
|
+
i = atIndex + 1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
let j = atIndex + 1;
|
|
75
|
+
while (j < len) {
|
|
76
|
+
const ch = content[j];
|
|
77
|
+
if (ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r')
|
|
78
|
+
break;
|
|
79
|
+
j++;
|
|
80
|
+
}
|
|
81
|
+
const importPath = content.slice(atIndex + 1, j).trim();
|
|
82
|
+
if (importPath.length === 0) {
|
|
83
|
+
i = atIndex + 1;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
results.push({ start: atIndex, end: j, importPath });
|
|
87
|
+
i = j + 1;
|
|
88
|
+
}
|
|
89
|
+
return results;
|
|
90
|
+
}
|
|
91
|
+
function findCodeBlockRegions(content) {
|
|
92
|
+
const regions = [];
|
|
93
|
+
let index = 0;
|
|
94
|
+
const len = content.length;
|
|
95
|
+
while (index < len) {
|
|
96
|
+
const fenceStart = content.indexOf('```', index);
|
|
97
|
+
if (fenceStart === -1)
|
|
98
|
+
break;
|
|
99
|
+
const fenceEnd = content.indexOf('```', fenceStart + 3);
|
|
100
|
+
if (fenceEnd === -1) {
|
|
101
|
+
// Unclosed fence, treat until end-of-file as code
|
|
102
|
+
regions.push([fenceStart, len]);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
regions.push([fenceStart, fenceEnd + 3]);
|
|
106
|
+
index = fenceEnd + 3;
|
|
107
|
+
}
|
|
108
|
+
return regions;
|
|
109
|
+
}
|
|
110
|
+
function isInRegion(index, regions) {
|
|
111
|
+
return regions.some(([start, end]) => index >= start && index < end);
|
|
112
|
+
}
|
|
113
|
+
async function processImports(content, basePath, projectRoot, state) {
|
|
114
|
+
if (state.currentDepth >= state.maxDepth) {
|
|
115
|
+
return { content, filePaths: [] };
|
|
116
|
+
}
|
|
117
|
+
const codeRegions = findCodeBlockRegions(content);
|
|
118
|
+
const imports = findImports(content);
|
|
119
|
+
let result = '';
|
|
120
|
+
let lastIndex = 0;
|
|
121
|
+
const filePaths = [];
|
|
122
|
+
for (const { start, end, importPath } of imports) {
|
|
123
|
+
// Copy text before this import
|
|
124
|
+
result += content.slice(lastIndex, start);
|
|
125
|
+
lastIndex = end;
|
|
126
|
+
// Skip imports inside code blocks
|
|
127
|
+
if (isInRegion(start, codeRegions)) {
|
|
128
|
+
result += content.slice(start, end);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const resolvedPath = validateImportPath(importPath, basePath, projectRoot);
|
|
132
|
+
if (!resolvedPath) {
|
|
133
|
+
// Leave a comment indicating failure, but keep going
|
|
134
|
+
result += `<!-- Import skipped: ${importPath} (invalid or outside project root) -->`;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const normalized = node_path__WEBPACK_IMPORTED_MODULE_1__.normalize(resolvedPath);
|
|
138
|
+
if (state.processedFiles.has(normalized)) {
|
|
139
|
+
result += `<!-- Import skipped: ${importPath} (already processed) -->`;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const importedContent = await node_fs_promises__WEBPACK_IMPORTED_MODULE_0__.readFile(normalized, 'utf-8');
|
|
144
|
+
state.processedFiles.add(normalized);
|
|
145
|
+
filePaths.push(normalized);
|
|
146
|
+
const { content: processed, filePaths: nestedPaths } = await processImports(importedContent, node_path__WEBPACK_IMPORTED_MODULE_1__.dirname(normalized), projectRoot, {
|
|
147
|
+
processedFiles: state.processedFiles,
|
|
148
|
+
maxDepth: state.maxDepth,
|
|
149
|
+
currentDepth: state.currentDepth + 1,
|
|
150
|
+
});
|
|
151
|
+
filePaths.push(...nestedPaths);
|
|
152
|
+
result += `<!-- Imported from: ${importPath} -->\n${processed}\n<!-- End of import from: ${importPath} -->`;
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
156
|
+
result += `<!-- Import failed: ${importPath} - ${message} -->`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Remainder after last import
|
|
160
|
+
result += content.slice(lastIndex);
|
|
161
|
+
return { content: result, filePaths };
|
|
162
|
+
}
|
|
163
|
+
async function loadProjectSpec(cwd) {
|
|
164
|
+
const startDir = node_path__WEBPACK_IMPORTED_MODULE_1__.resolve(cwd);
|
|
165
|
+
const codegenPath = node_path__WEBPACK_IMPORTED_MODULE_1__.join(startDir, 'CODEGEN.md');
|
|
166
|
+
try {
|
|
167
|
+
await node_fs_promises__WEBPACK_IMPORTED_MODULE_0__.access(codegenPath);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
const projectRoot = await findProjectRoot(startDir);
|
|
173
|
+
const rawContent = await node_fs_promises__WEBPACK_IMPORTED_MODULE_0__.readFile(codegenPath, 'utf-8');
|
|
174
|
+
const initialState = {
|
|
175
|
+
processedFiles: new Set([node_path__WEBPACK_IMPORTED_MODULE_1__.normalize(codegenPath)]),
|
|
176
|
+
maxDepth: 5,
|
|
177
|
+
currentDepth: 0,
|
|
178
|
+
};
|
|
179
|
+
const { content, filePaths } = await processImports(rawContent, node_path__WEBPACK_IMPORTED_MODULE_1__.dirname(codegenPath), projectRoot, initialState);
|
|
180
|
+
return {
|
|
181
|
+
content,
|
|
182
|
+
filePaths: [node_path__WEBPACK_IMPORTED_MODULE_1__.normalize(codegenPath), ...filePaths],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
/***/ })
|
|
188
|
+
|
|
189
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export const id = 984;
|
|
2
|
+
export const ids = [984];
|
|
3
|
+
export const modules = {
|
|
4
|
+
|
|
5
|
+
/***/ 263:
|
|
6
|
+
/***/ ((module) => {
|
|
7
|
+
|
|
8
|
+
module.exports = eval("require")("react-devtools-core");
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/***/ }),
|
|
12
|
+
|
|
13
|
+
/***/ 2984:
|
|
14
|
+
/***/ ((__unused_webpack___webpack_module__, __unused_webpack___webpack_exports__, __webpack_require__) => {
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
// EXTERNAL MODULE: ./node_modules/ws/wrapper.mjs
|
|
18
|
+
var wrapper = __webpack_require__(2977);
|
|
19
|
+
;// CONCATENATED MODULE: ./node_modules/ink/build/devtools-window-polyfill.js
|
|
20
|
+
// Ignoring missing types error to avoid adding another dependency for this hack to work
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
23
|
+
const customGlobal = global;
|
|
24
|
+
// These things must exist before importing `react-devtools-core`
|
|
25
|
+
customGlobal.WebSocket ||= wrapper/* default */.Ay;
|
|
26
|
+
customGlobal.window ||= global;
|
|
27
|
+
customGlobal.self ||= global;
|
|
28
|
+
// Filter out Ink's internal components from devtools for a cleaner view.
|
|
29
|
+
// Also, ince `react-devtools-shared` package isn't published on npm, we can't
|
|
30
|
+
// use its types, that's why there are hard-coded values in `type` fields below.
|
|
31
|
+
// See https://github.com/facebook/react/blob/edf6eac8a181860fd8a2d076a43806f1237495a1/packages/react-devtools-shared/src/types.js#L24
|
|
32
|
+
customGlobal.window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = [
|
|
33
|
+
{
|
|
34
|
+
// ComponentFilterElementType
|
|
35
|
+
type: 1,
|
|
36
|
+
// ElementTypeHostComponent
|
|
37
|
+
value: 7,
|
|
38
|
+
isEnabled: true,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
// ComponentFilterDisplayName
|
|
42
|
+
type: 2,
|
|
43
|
+
value: 'InternalApp',
|
|
44
|
+
isEnabled: true,
|
|
45
|
+
isValid: true,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
// ComponentFilterDisplayName
|
|
49
|
+
type: 2,
|
|
50
|
+
value: 'InternalAppContext',
|
|
51
|
+
isEnabled: true,
|
|
52
|
+
isValid: true,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
// ComponentFilterDisplayName
|
|
56
|
+
type: 2,
|
|
57
|
+
value: 'InternalStdoutContext',
|
|
58
|
+
isEnabled: true,
|
|
59
|
+
isValid: true,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
// ComponentFilterDisplayName
|
|
63
|
+
type: 2,
|
|
64
|
+
value: 'InternalStderrContext',
|
|
65
|
+
isEnabled: true,
|
|
66
|
+
isValid: true,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
// ComponentFilterDisplayName
|
|
70
|
+
type: 2,
|
|
71
|
+
value: 'InternalStdinContext',
|
|
72
|
+
isEnabled: true,
|
|
73
|
+
isValid: true,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
// ComponentFilterDisplayName
|
|
77
|
+
type: 2,
|
|
78
|
+
value: 'InternalFocusContext',
|
|
79
|
+
isEnabled: true,
|
|
80
|
+
isValid: true,
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
//# sourceMappingURL=devtools-window-polyfill.js.map
|
|
84
|
+
// EXTERNAL MODULE: ./node_modules/@vercel/ncc/dist/ncc/@@notfound.js?react-devtools-core
|
|
85
|
+
var _notfoundreact_devtools_core = __webpack_require__(263);
|
|
86
|
+
;// CONCATENATED MODULE: ./node_modules/ink/build/devtools.js
|
|
87
|
+
/* eslint-disable import/order */
|
|
88
|
+
// eslint-disable-next-line import/no-unassigned-import
|
|
89
|
+
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
91
|
+
// @ts-expect-error
|
|
92
|
+
|
|
93
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
94
|
+
_notfoundreact_devtools_core.connectToDevTools();
|
|
95
|
+
//# sourceMappingURL=devtools.js.map
|
|
96
|
+
|
|
97
|
+
/***/ })
|
|
98
|
+
|
|
99
|
+
};
|
package/dist/App.d.ts
ADDED
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ConversationMessage } from '../types/index.js';
|
|
3
|
+
import { ChildProcess } from 'child_process';
|
|
4
|
+
interface ConversationProps {
|
|
5
|
+
conversation: ConversationMessage[];
|
|
6
|
+
activeShellCommand: any;
|
|
7
|
+
childProcess: ChildProcess | null;
|
|
8
|
+
handleShellCompletion: (result: any) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const Conversation: React.FC<ConversationProps>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface DiffViewProps {
|
|
3
|
+
oldContent: string;
|
|
4
|
+
newContent: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
onComplete: (action: 'accept' | 'reject' | 'edit', editedContent?: string) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const _default: React.MemoExoticComponent<({ oldContent, newContent, filePath, onComplete, }: DiffViewProps) => React.JSX.Element>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
value: string;
|
|
4
|
+
onChange: (value: string) => void;
|
|
5
|
+
onSubmit: (value: string) => void;
|
|
6
|
+
searchFiles: (pattern: string, options?: {
|
|
7
|
+
ignore?: string[];
|
|
8
|
+
}) => Promise<string[]>;
|
|
9
|
+
isShellActive?: boolean;
|
|
10
|
+
setShowEscapeClear: (show: boolean) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const _default: React.MemoExoticComponent<({ value, onChange, onSubmit, searchFiles, isShellActive, setShowEscapeClear, }: Props) => React.JSX.Element>;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ConversationMessage } from '../types/index.js';
|
|
3
|
+
import { ChildProcess } from 'child_process';
|
|
4
|
+
interface MessageProps {
|
|
5
|
+
message: ConversationMessage;
|
|
6
|
+
activeShellCommand: any;
|
|
7
|
+
childProcess: ChildProcess | null;
|
|
8
|
+
handleShellCompletion: (result: any) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const MemoizedMessage: React.NamedExoticComponent<MessageProps>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ChildProcess } from 'child_process';
|
|
3
|
+
interface ShellExecutionProps {
|
|
4
|
+
command: string;
|
|
5
|
+
childProcess: ChildProcess | null;
|
|
6
|
+
onComplete: (result: any) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const ShellExecution: React.FC<ShellExecutionProps>;
|
|
9
|
+
export default ShellExecution;
|