shimwrappercheck 0.2.0
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/AGENTS.md +21 -0
- package/README.md +286 -0
- package/bin/git +5 -0
- package/bin/shim +5 -0
- package/bin/shimwrappercheck +2 -0
- package/bin/supabase +5 -0
- package/dashboard/.next/cache/config.json +7 -0
- package/dashboard/.next/package.json +1 -0
- package/dashboard/.next/routes-manifest.json +1 -0
- package/dashboard/.next/trace +1 -0
- package/dashboard/README.md +32 -0
- package/dashboard/app/agents/page.tsx +88 -0
- package/dashboard/app/api/agents-md/route.ts +68 -0
- package/dashboard/app/api/config/route.ts +51 -0
- package/dashboard/app/api/run-checks/route.ts +54 -0
- package/dashboard/app/api/settings/route.ts +126 -0
- package/dashboard/app/api/status/route.ts +38 -0
- package/dashboard/app/config/page.tsx +77 -0
- package/dashboard/app/globals.css +20 -0
- package/dashboard/app/layout.tsx +23 -0
- package/dashboard/app/page.tsx +122 -0
- package/dashboard/app/settings/page.tsx +422 -0
- package/dashboard/components/Nav.tsx +33 -0
- package/dashboard/components/StatusCard.tsx +27 -0
- package/dashboard/lib/presets.ts +97 -0
- package/dashboard/lib/projectRoot.ts +25 -0
- package/dashboard/next.config.js +6 -0
- package/dashboard/package-lock.json +5307 -0
- package/dashboard/package.json +28 -0
- package/dashboard/postcss.config.js +6 -0
- package/dashboard/tailwind.config.js +14 -0
- package/dashboard/tsconfig.json +20 -0
- package/docs/SHIM_WRAPPER_CONCEPT.md +79 -0
- package/docs/WORKFLOW_AND_GAP_ANALYSIS.md +159 -0
- package/package.json +24 -0
- package/scripts/cli-checked.sh +307 -0
- package/scripts/cli.js +23 -0
- package/scripts/fetch-edge-logs.sh +96 -0
- package/scripts/git-checked.sh +194 -0
- package/scripts/init.js +341 -0
- package/scripts/install.js +303 -0
- package/scripts/ping-edge-health.sh +113 -0
- package/scripts/setup.js +55 -0
- package/scripts/supabase-checked.sh +330 -0
- package/templates/ai-code-review.sh +217 -0
- package/templates/git-pre-push +41 -0
- package/templates/husky-pre-push +46 -0
- package/templates/run-checks.sh +67 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Agent instructions (shimwrappercheck)
|
|
2
|
+
|
|
3
|
+
This file is used by AI agents (Cursor, Codex, etc.) when working with this repo.
|
|
4
|
+
It can be edited via the dashboard (Config → AGENTS.md) so agents and humans share one source of truth.
|
|
5
|
+
|
|
6
|
+
## Shim usage
|
|
7
|
+
|
|
8
|
+
- Use `npx supabase ...` or `npm run supabase:checked -- ...` so checks run before deploy.
|
|
9
|
+
- Use `npx git push` or `npm run git:checked -- push` so checks run before push.
|
|
10
|
+
- Run `npx shimwrappercheck init` for setup; `npx shimwrappercheck install` for PATH shims.
|
|
11
|
+
|
|
12
|
+
## Dashboard
|
|
13
|
+
|
|
14
|
+
- The project includes a **dashboard** (Next.js app in `dashboard/`). Start with `cd dashboard && npm install && npm run dev`.
|
|
15
|
+
- In the dashboard you can: view status, run checks, edit `.shimwrappercheckrc`, and **edit this AGENTS.md**.
|
|
16
|
+
- Agents should respect AGENTS.md; editing it via the dashboard keeps agent instructions in sync.
|
|
17
|
+
|
|
18
|
+
## Project rules
|
|
19
|
+
|
|
20
|
+
- Keep checks fast; run lint/type/build in `scripts/run-checks.sh`.
|
|
21
|
+
- When changing shim behavior, update README and docs/SHIM_WRAPPER_CONCEPT.md if needed.
|
package/README.md
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# shimwrappercheck
|
|
2
|
+
|
|
3
|
+
CLI shim wrapper that enforces project checks before running a real CLI command.
|
|
4
|
+
|
|
5
|
+
Out of the box, this package ships **Supabase**, **Git**, and a **generic shim** (`supabase`, `git`, `shim` bins), but the pattern is generic:
|
|
6
|
+
you can reuse the scripts for other CLIs by copying/adapting them in your repo.
|
|
7
|
+
|
|
8
|
+
This package provides a `supabase` bin that you can use via `npx supabase ...` or `npm run supabase:checked -- ...`.
|
|
9
|
+
It is repo-agnostic: you plug in your own `scripts/run-checks.sh` and optional hooks.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Wraps a CLI command and enforces checks before deploy/push (Supabase + Git wrappers included, generic shim for anything else)
|
|
14
|
+
- Diff-aware checks (frontend/backend) based on staged/unstaged changes
|
|
15
|
+
- Command filtering (only run checks/hooks for specific Supabase commands)
|
|
16
|
+
- Network retry for flaky Supabase CLI calls
|
|
17
|
+
- Post-deploy hooks: health ping + logs
|
|
18
|
+
- Auto git push when ahead of upstream (optional)
|
|
19
|
+
- AI review integration (Codex default, Cursor fallback)
|
|
20
|
+
- Interactive setup wizard that scans your repo and configures everything
|
|
21
|
+
- Global installer that drops PATH shims (`supabase`, `git`, `shim`)
|
|
22
|
+
- Generic shim supports pre/post hooks
|
|
23
|
+
- **Dashboard**: Web UI to view status, run checks, **Presets & check toggles** (Einstellungen), edit `.shimwrappercheckrc`, and **edit AGENTS.md**
|
|
24
|
+
- **Presets**: default "Vibe Code" (GitHub + Supabase, all commands); custom presets with provider toggles; check toggles (frontend, backend, AI review)
|
|
25
|
+
|
|
26
|
+
## Setup (one command)
|
|
27
|
+
|
|
28
|
+
Run the full setup in one go (installs package if needed, then runs the wizard):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx shimwrappercheck setup
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This installs `shimwrappercheck` as a devDependency if missing, then runs the init wizard (Supabase/Git shims, which commands, AI review, hooks, run-checks.sh, etc.). At the end you get a link to start the dashboard to change settings later.
|
|
35
|
+
|
|
36
|
+
## Dashboard (Web UI)
|
|
37
|
+
|
|
38
|
+
A Next.js dashboard lets you manage presets, checks, config, and AGENTS.md:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cd node_modules/shimwrappercheck/dashboard && npm install && npm run dev
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then open http://localhost:3000. You can:
|
|
45
|
+
|
|
46
|
+
- **Einstellungen**: Presets (Vibe Code default, custom presets), Supabase/Git command toggles (which commands run checks/hooks), check toggles (frontend, backend, AI review)
|
|
47
|
+
- View status (config, presets file, AGENTS.md, run-checks script, hooks)
|
|
48
|
+
- Run checks only (button)
|
|
49
|
+
- Edit `.shimwrappercheckrc` (Config, raw)
|
|
50
|
+
- Edit **AGENTS.md** (agent instructions for Cursor/Codex; changes apply immediately)
|
|
51
|
+
|
|
52
|
+
**AGENTS.md** is used by AI agents; editing it in the dashboard keeps agent instructions in sync. Set `SHIM_PROJECT_ROOT` when deploying the dashboard (e.g. on Vercel) to the repo root path where `.shimwrappercheckrc` and `AGENTS.md` live.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm i -D shimwrappercheck
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Global install (PATH shims)
|
|
61
|
+
|
|
62
|
+
This installs small shims into a bin directory (default: `~/.local/bin`) so you can run
|
|
63
|
+
`supabase`, `git`, or `shim` directly without `npx`.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx shimwrappercheck install
|
|
67
|
+
# options
|
|
68
|
+
# --bin-dir <path> (default: ~/.local/bin)
|
|
69
|
+
# --interactive (default when no flags)
|
|
70
|
+
# --no-interactive
|
|
71
|
+
# --add-path (auto-append PATH in shell config)
|
|
72
|
+
# --overwrite
|
|
73
|
+
# --dry-run
|
|
74
|
+
# --no-supabase | --no-git | --no-shim
|
|
75
|
+
# --only supabase,git,shim
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If the bin dir is not in PATH, add (or use `--add-path` to append automatically):
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
When multiple shell configs exist (e.g. `.zshrc` + `.zprofile`), the installer asks which file to update.
|
|
85
|
+
|
|
86
|
+
## Quick start
|
|
87
|
+
|
|
88
|
+
1) Add a checks script in your repo (example template below).
|
|
89
|
+
2) Use the shim instead of the raw CLI.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Copy templates (customize to your repo)
|
|
93
|
+
cp node_modules/shimwrappercheck/templates/run-checks.sh scripts/run-checks.sh
|
|
94
|
+
cp node_modules/shimwrappercheck/templates/ai-code-review.sh scripts/ai-code-review.sh
|
|
95
|
+
cp node_modules/shimwrappercheck/templates/husky-pre-push .husky/pre-push
|
|
96
|
+
|
|
97
|
+
# Make scripts executable
|
|
98
|
+
chmod +x scripts/run-checks.sh scripts/ai-code-review.sh .husky/pre-push
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Add a package.json script (optional):
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"scripts": {
|
|
106
|
+
"supabase:checked": "supabase"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then run:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm run supabase:checked -- functions deploy <function-name>
|
|
115
|
+
# or
|
|
116
|
+
npx supabase functions deploy <function-name>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Setup wizard (init)
|
|
120
|
+
|
|
121
|
+
Run the interactive init to scan your codebase and configure the shim (or use `npx shimwrappercheck setup` to install + init in one step):
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npx shimwrappercheck init
|
|
125
|
+
# or
|
|
126
|
+
npm exec shimwrappercheck init
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The wizard can (defaults are tuned based on repo type):
|
|
130
|
+
|
|
131
|
+
- detect Supabase and Git usage
|
|
132
|
+
- ask which commands should trigger checks/hooks
|
|
133
|
+
- install pre-push hooks
|
|
134
|
+
- enable AI review and guide you through login
|
|
135
|
+
- create a `.shimwrappercheckrc` config
|
|
136
|
+
|
|
137
|
+
## How it works
|
|
138
|
+
|
|
139
|
+
- The shim determines which checks to run based on git changes (e.g. `src/` vs `supabase/functions/`).
|
|
140
|
+
- The shim runs your checks script first (default: `scripts/run-checks.sh`).
|
|
141
|
+
- If checks pass, it calls the real Supabase CLI.
|
|
142
|
+
- Optional hooks run after deploy to ping health and fetch logs.
|
|
143
|
+
- Optional git auto-push can be enabled (this is **not** a git wrapper; it runs after the CLI succeeds).
|
|
144
|
+
- Git push checks are enforced via pre-push hooks (template provided).
|
|
145
|
+
|
|
146
|
+
## Usage
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npx supabase functions deploy <function-name>
|
|
150
|
+
npm run supabase:checked -- db push
|
|
151
|
+
|
|
152
|
+
# git wrapper
|
|
153
|
+
npx git push
|
|
154
|
+
npm run git:checked -- push
|
|
155
|
+
|
|
156
|
+
# generic shim (any CLI)
|
|
157
|
+
npm exec --package shimwrappercheck -- shim docker build .
|
|
158
|
+
npm exec --package shimwrappercheck -- shim --cli terraform -- plan
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Generic shim hooks:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
export SHIM_CLI_PRE_HOOKS="scripts/cli-pre-hook.sh"
|
|
165
|
+
export SHIM_CLI_POST_HOOKS="scripts/cli-post-hook.sh"
|
|
166
|
+
shim docker build .
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Tip: Use `--` to separate shim flags from CLI args when needed:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npm exec --package shimwrappercheck -- shim --cli docker -- build .
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
You can also run only checks:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
npx supabase --checks-only functions deploy server
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Wrapper-only flags
|
|
182
|
+
|
|
183
|
+
These flags are consumed by the shim and are not passed to the wrapped CLI:
|
|
184
|
+
|
|
185
|
+
- `--no-checks` Skip checks for this invocation.
|
|
186
|
+
- `--checks-only` Run checks and exit without running Supabase.
|
|
187
|
+
- `--no-hooks` Skip post-deploy hooks (health/logs).
|
|
188
|
+
- `--no-push` Skip auto git push.
|
|
189
|
+
- `--no-ai-review` Passed through to the checks script (template supports it).
|
|
190
|
+
- `--with-frontend` Force frontend checks even if no `src/` changes are detected.
|
|
191
|
+
- `--ai-review` Passed through to the checks script (template supports it).
|
|
192
|
+
- `--auto-push` Generic shim: enable git auto-push after command.
|
|
193
|
+
|
|
194
|
+
## Command filtering
|
|
195
|
+
|
|
196
|
+
You can control for which Supabase commands checks and hooks should run:
|
|
197
|
+
|
|
198
|
+
- `SHIM_ENFORCE_COMMANDS="functions,db,migration"` to run checks only for those commands
|
|
199
|
+
- `SHIM_HOOK_COMMANDS="functions,db,migration"` to run hooks only for those commands
|
|
200
|
+
- Use `all` or `none` to enable/disable completely
|
|
201
|
+
|
|
202
|
+
Commands are matched by token (e.g. `functions`, `db`, `migration`).
|
|
203
|
+
|
|
204
|
+
Note: If you want checks for `supabase push`, add `push` to `SHIM_ENFORCE_COMMANDS`.
|
|
205
|
+
|
|
206
|
+
For Git, use `SHIM_GIT_ENFORCE_COMMANDS` (default: `push`). You can include `commit,merge,rebase` etc.
|
|
207
|
+
|
|
208
|
+
## Environment variables
|
|
209
|
+
|
|
210
|
+
- `SHIM_PROJECT_ROOT` Override project root detection.
|
|
211
|
+
- `SHIM_CHECKS_SCRIPT` Path to your checks script (relative to project root or absolute).
|
|
212
|
+
- `SHIM_CHECKS_ARGS` Extra args passed to checks script.
|
|
213
|
+
- `SHIM_CONFIG_FILE` Custom path to config file (default: `.shimwrappercheckrc`).
|
|
214
|
+
- `SHIM_DISABLE_CHECKS=1` Disable checks (same as `--no-checks`).
|
|
215
|
+
- `SHIM_DISABLE_HOOKS=1` Disable hooks (same as `--no-hooks`).
|
|
216
|
+
- `SHIM_AUTO_PUSH=1|0` Enable/disable auto git push after success (default: on).
|
|
217
|
+
- `SHIM_DEFAULT_FUNCTION` Default function name for health/log hooks (default: `server`).
|
|
218
|
+
- `SHIM_ENFORCE_COMMANDS` Comma list for which CLI commands checks should run (`all`, `none`, or e.g. `functions,db,migration`).
|
|
219
|
+
- `SHIM_HOOK_COMMANDS` Comma list for which CLI commands hooks should run (same format).
|
|
220
|
+
- `SHIM_PING_SCRIPT` Override path to health ping script.
|
|
221
|
+
- `SHIM_LOG_SCRIPT` Override path to logs script.
|
|
222
|
+
- `SHIM_GIT_ENFORCE_COMMANDS` Comma list for which git commands checks should run (`push`, `all`, `none`).
|
|
223
|
+
- `SHIM_GIT_CHECKS_SCRIPT` Override checks script for git wrapper.
|
|
224
|
+
- `SHIM_GIT_CHECKS_ARGS` Extra args passed to checks script (git wrapper only).
|
|
225
|
+
- `SHIM_GIT_REAL_BIN` Absolute path to the real git binary (avoids recursion).
|
|
226
|
+
- `SHIM_CLI_ENFORCE_COMMANDS` Generic shim: comma list for which subcommands checks should run.
|
|
227
|
+
- `SHIM_CLI_CHECKS_SCRIPT` Generic shim: override checks script.
|
|
228
|
+
- `SHIM_CLI_CHECKS_ARGS` Generic shim: extra args passed to checks script.
|
|
229
|
+
- `SHIM_CLI_REAL_BIN` Generic shim: absolute path to real CLI binary (avoids recursion).
|
|
230
|
+
- `SHIM_CLI_AUTO_PUSH` Generic shim: enable git auto-push after command (0/1).
|
|
231
|
+
- `SHIM_CLI_PRE_HOOKS` Generic shim: comma list of pre-hook scripts to run.
|
|
232
|
+
- `SHIM_CLI_POST_HOOKS` Generic shim: comma list of post-hook scripts to run.
|
|
233
|
+
- `SHIM_CLI_HOOK_COMMANDS` Generic shim: comma list for which subcommands hooks should run.
|
|
234
|
+
|
|
235
|
+
Network retry (Supabase CLI):
|
|
236
|
+
|
|
237
|
+
- `SUPABASE_RETRY_MAX` Number of retries on network errors (default: 1).
|
|
238
|
+
- `SUPABASE_RETRY_BACKOFF_SECONDS` Comma-separated backoff seconds (default: `5,15`).
|
|
239
|
+
- `SUPABASE_RETRY_EXTRA_ARGS` Extra args added only on retry attempts.
|
|
240
|
+
|
|
241
|
+
Supabase CLI resolution:
|
|
242
|
+
|
|
243
|
+
- `SUPABASE_REAL_BIN` Absolute path to the real Supabase CLI.
|
|
244
|
+
- `SHIM_SUPABASE_BIN` Same as above (alias).
|
|
245
|
+
- `~/.supabase-real-bin` If present, read as real CLI path.
|
|
246
|
+
|
|
247
|
+
Post-deploy hooks:
|
|
248
|
+
|
|
249
|
+
- `SHIM_HEALTH_FUNCTIONS` Comma-separated function names to ping (fallback if not detected).
|
|
250
|
+
- `SHIM_LOG_FUNCTIONS` Comma-separated function names to fetch logs for.
|
|
251
|
+
- `SHIM_LOG_LIMIT` Log lines to fetch (default: 30).
|
|
252
|
+
- `SUPABASE_PROJECT_REF` Project ref for health ping (or `supabase/project-ref`).
|
|
253
|
+
- `SHIM_HEALTH_PATHS` Comma-separated URL paths with `{fn}` placeholder.
|
|
254
|
+
|
|
255
|
+
## Config file (optional)
|
|
256
|
+
|
|
257
|
+
Create `.shimwrappercheckrc` in your project root to persist settings:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
SHIM_ENFORCE_COMMANDS="functions,db,migration"
|
|
261
|
+
SHIM_HOOK_COMMANDS="functions,db,migration"
|
|
262
|
+
SHIM_DEFAULT_FUNCTION="server"
|
|
263
|
+
SHIM_AUTO_PUSH=1
|
|
264
|
+
SHIM_CHECKS_ARGS="--no-ai-review"
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Note: `.shimwrappercheckrc` is sourced as a shell file.
|
|
268
|
+
|
|
269
|
+
## Templates
|
|
270
|
+
|
|
271
|
+
- `templates/run-checks.sh` Minimal checks runner; customize for your repo.
|
|
272
|
+
- `templates/ai-code-review.sh` Optional AI review step (Codex default, Cursor fallback).
|
|
273
|
+
- `templates/husky-pre-push` Husky pre-push hook that runs checks.
|
|
274
|
+
- `templates/git-pre-push` Plain git hook version of the same.
|
|
275
|
+
|
|
276
|
+
## Notes
|
|
277
|
+
|
|
278
|
+
- If the shim is installed locally, it avoids recursion by resolving the real Supabase CLI.
|
|
279
|
+
- If no real CLI is found, it runs `npx --package supabase supabase ...`.
|
|
280
|
+
- The git wrapper should be invoked via `npx git` or `npm run git:checked` to avoid shadowing your system git.
|
|
281
|
+
- Hooks are resolved from your repo first (`scripts/ping-edge-health.sh`, `scripts/fetch-edge-logs.sh`) and fall back to the package scripts.
|
|
282
|
+
- Generic shim hooks default to `scripts/cli-pre-hook.sh` and `scripts/cli-post-hook.sh` if present.
|
|
283
|
+
|
|
284
|
+
## License
|
|
285
|
+
|
|
286
|
+
UNLICENSED (update if you want a public license).
|
package/bin/git
ADDED
package/bin/shim
ADDED
package/bin/supabase
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type": "commonjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"pages404":true,"caseSensitive":false,"basePath":"","redirects":[{"source":"/:path+/","destination":"/:path+","internal":true,"statusCode":308,"regex":"^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$"}],"headers":[],"dynamicRoutes":[],"staticRoutes":[{"page":"/","regex":"^/(?:/)?$","routeKeys":{},"namedRegex":"^/(?:/)?$"},{"page":"/_not-found","regex":"^/_not\\-found(?:/)?$","routeKeys":{},"namedRegex":"^/_not\\-found(?:/)?$"},{"page":"/agents","regex":"^/agents(?:/)?$","routeKeys":{},"namedRegex":"^/agents(?:/)?$"},{"page":"/config","regex":"^/config(?:/)?$","routeKeys":{},"namedRegex":"^/config(?:/)?$"}],"dataRoutes":[],"rsc":{"header":"RSC","varyHeader":"RSC, Next-Router-State-Tree, Next-Router-Prefetch","prefetchHeader":"Next-Router-Prefetch","didPostponeHeader":"x-nextjs-postponed","contentTypeHeader":"text/x-component","suffix":".rsc","prefetchSuffix":".prefetch.rsc"},"rewrites":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"name":"generate-buildid","duration":121,"timestamp":6948914020,"id":4,"parentId":1,"tags":{},"startTime":1770383569821,"traceId":"eb1231321911f71f"},{"name":"load-custom-routes","duration":109,"timestamp":6948914218,"id":5,"parentId":1,"tags":{},"startTime":1770383569821,"traceId":"eb1231321911f71f"},{"name":"create-pages-mapping","duration":77,"timestamp":6948958791,"id":6,"parentId":1,"tags":{},"startTime":1770383569866,"traceId":"eb1231321911f71f"},{"name":"collect-app-paths","duration":1657,"timestamp":6948958882,"id":7,"parentId":1,"tags":{},"startTime":1770383569866,"traceId":"eb1231321911f71f"},{"name":"create-app-mapping","duration":349,"timestamp":6948960570,"id":8,"parentId":1,"tags":{},"startTime":1770383569868,"traceId":"eb1231321911f71f"},{"name":"public-dir-conflict-check","duration":288,"timestamp":6948961063,"id":9,"parentId":1,"tags":{},"startTime":1770383569868,"traceId":"eb1231321911f71f"},{"name":"generate-routes-manifest","duration":879,"timestamp":6948961425,"id":10,"parentId":1,"tags":{},"startTime":1770383569869,"traceId":"eb1231321911f71f"},{"name":"create-dist-dir","duration":77,"timestamp":6948962563,"id":11,"parentId":1,"tags":{},"startTime":1770383569870,"traceId":"eb1231321911f71f"},{"name":"write-routes-manifest","duration":234,"timestamp":6948963636,"id":12,"parentId":1,"tags":{},"startTime":1770383569871,"traceId":"eb1231321911f71f"},{"name":"generate-required-server-files","duration":223,"timestamp":6948963900,"id":13,"parentId":1,"tags":{},"startTime":1770383569871,"traceId":"eb1231321911f71f"},{"name":"next-build","duration":944042,"timestamp":6948865225,"id":1,"tags":{"buildMode":"default","isTurboBuild":"false","version":"14.2.18","isTurbopack":false,"has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1770383569772,"traceId":"eb1231321911f71f"}]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# shimwrappercheck Dashboard
|
|
2
|
+
|
|
3
|
+
Next.js Web UI for shimwrappercheck: status, run checks, edit `.shimwrappercheckrc`, and edit **AGENTS.md**.
|
|
4
|
+
|
|
5
|
+
## Run locally
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Open http://localhost:3000.
|
|
13
|
+
|
|
14
|
+
## Deploy (e.g. Vercel)
|
|
15
|
+
|
|
16
|
+
- Set **Root Directory** to `dashboard` (or deploy from repo root and build from `dashboard`).
|
|
17
|
+
- Set env **SHIM_PROJECT_ROOT** to the absolute path of the repo where `.shimwrappercheckrc` and `AGENTS.md` live (required when dashboard runs in a different directory than the project).
|
|
18
|
+
|
|
19
|
+
## Pages
|
|
20
|
+
|
|
21
|
+
- **Dashboard**: Status (config, AGENTS.md, run-checks script, hooks), button "Nur Checks ausführen", links to Config and AGENTS.md.
|
|
22
|
+
- **Config**: Edit `.shimwrappercheckrc` (raw text).
|
|
23
|
+
- **AGENTS.md**: Edit agent instructions; used by Cursor/Codex. Editable by agents and humans via this UI.
|
|
24
|
+
|
|
25
|
+
## API
|
|
26
|
+
|
|
27
|
+
- `GET /api/status` – project status (paths, existence of config/AGENTS.md/scripts/hooks).
|
|
28
|
+
- `GET/POST /api/config` – read/write `.shimwrappercheckrc`.
|
|
29
|
+
- `GET/POST /api/agents-md` – read/write `AGENTS.md` (default content if missing).
|
|
30
|
+
- `POST /api/run-checks` – run `scripts/run-checks.sh`, return stdout/stderr/code.
|
|
31
|
+
|
|
32
|
+
All paths resolve from **project root** (parent of `dashboard/` when running locally, or `SHIM_PROJECT_ROOT` when set).
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AGENTS.md editor: edit agent instructions (used by Cursor/Codex agents).
|
|
3
|
+
* Location: app/agents/page.tsx
|
|
4
|
+
*/
|
|
5
|
+
"use client";
|
|
6
|
+
|
|
7
|
+
import { useEffect, useState } from "react";
|
|
8
|
+
|
|
9
|
+
export default function AgentsPage() {
|
|
10
|
+
const [raw, setRaw] = useState("");
|
|
11
|
+
const [loading, setLoading] = useState(true);
|
|
12
|
+
const [saving, setSaving] = useState(false);
|
|
13
|
+
const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
|
|
14
|
+
const [exists, setExists] = useState(false);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
fetch("/api/agents-md")
|
|
18
|
+
.then((r) => r.json())
|
|
19
|
+
.then((data) => {
|
|
20
|
+
setRaw(data.raw ?? "");
|
|
21
|
+
setExists(data.exists ?? false);
|
|
22
|
+
setLoading(false);
|
|
23
|
+
})
|
|
24
|
+
.catch(() => setLoading(false));
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
const save = () => {
|
|
28
|
+
setSaving(true);
|
|
29
|
+
setMessage(null);
|
|
30
|
+
fetch("/api/agents-md", {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers: { "Content-Type": "application/json" },
|
|
33
|
+
body: JSON.stringify({ raw }),
|
|
34
|
+
})
|
|
35
|
+
.then((r) => r.json())
|
|
36
|
+
.then((data) => {
|
|
37
|
+
setSaving(false);
|
|
38
|
+
if (data.error) setMessage({ type: "error", text: data.error });
|
|
39
|
+
else {
|
|
40
|
+
setMessage({ type: "success", text: "AGENTS.md gespeichert." });
|
|
41
|
+
setExists(true);
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
.catch(() => {
|
|
45
|
+
setSaving(false);
|
|
46
|
+
setMessage({ type: "error", text: "Speichern fehlgeschlagen." });
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
if (loading) {
|
|
51
|
+
return (
|
|
52
|
+
<div className="flex justify-center py-12">
|
|
53
|
+
<span className="loading loading-spinner loading-lg" />
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div className="space-y-6">
|
|
60
|
+
<h1 className="text-3xl font-bold">AGENTS.md</h1>
|
|
61
|
+
<p className="text-base-content/80">
|
|
62
|
+
Agent-Anweisungen für Cursor/Codex. Wird von Agents gelesen; hier bearbeitbar. Änderungen gelten sofort.
|
|
63
|
+
</p>
|
|
64
|
+
{!exists && (
|
|
65
|
+
<div className="alert alert-info">
|
|
66
|
+
<span>AGENTS.md existiert noch nicht. Beim Speichern wird sie im Projekt-Root angelegt.</span>
|
|
67
|
+
</div>
|
|
68
|
+
)}
|
|
69
|
+
<textarea
|
|
70
|
+
className="textarea textarea-bordered w-full font-mono text-sm min-h-[400px]"
|
|
71
|
+
value={raw}
|
|
72
|
+
onChange={(e) => setRaw(e.target.value)}
|
|
73
|
+
placeholder="# Agent instructions..."
|
|
74
|
+
spellCheck={false}
|
|
75
|
+
/>
|
|
76
|
+
<div className="flex gap-4 items-center">
|
|
77
|
+
<button type="button" className="btn btn-primary" onClick={save} disabled={saving}>
|
|
78
|
+
{saving ? "Speichern…" : "Speichern"}
|
|
79
|
+
</button>
|
|
80
|
+
{message && (
|
|
81
|
+
<span className={message.type === "success" ? "text-success" : "text-error"}>
|
|
82
|
+
{message.text}
|
|
83
|
+
</span>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GET/POST /api/agents-md – read/write AGENTS.md (agent instructions, editable by GUI).
|
|
3
|
+
* Vercel-compatible; uses SHIM_PROJECT_ROOT when deployed.
|
|
4
|
+
*/
|
|
5
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import { getProjectRoot } from "@/lib/projectRoot";
|
|
9
|
+
|
|
10
|
+
const agentsFileName = "AGENTS.md";
|
|
11
|
+
|
|
12
|
+
function getAgentsPath(): string {
|
|
13
|
+
return path.join(getProjectRoot(), agentsFileName);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const defaultAgentsContent = `# Agent instructions (shimwrappercheck)
|
|
17
|
+
|
|
18
|
+
This file is used by AI agents (Cursor, Codex, etc.) when working with this repo.
|
|
19
|
+
Edit it here or via the dashboard so agents know how to use the shim and this project.
|
|
20
|
+
|
|
21
|
+
## Shim usage
|
|
22
|
+
|
|
23
|
+
- Use \`npx supabase ...\` or \`npm run supabase:checked -- ...\` so checks run before deploy.
|
|
24
|
+
- Use \`npx git push\` or \`npm run git:checked -- push\` so checks run before push.
|
|
25
|
+
- Run \`npx shimwrappercheck init\` for setup; \`npx shimwrappercheck install\` for PATH shims.
|
|
26
|
+
|
|
27
|
+
## Project rules
|
|
28
|
+
|
|
29
|
+
- Keep checks fast; run lint/type/build in scripts/run-checks.sh.
|
|
30
|
+
- AGENTS.md can be edited via the dashboard (Config → AGENTS.md).
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export async function GET() {
|
|
34
|
+
try {
|
|
35
|
+
const p = getAgentsPath();
|
|
36
|
+
if (!fs.existsSync(p)) {
|
|
37
|
+
return NextResponse.json({ raw: defaultAgentsContent, exists: false });
|
|
38
|
+
}
|
|
39
|
+
const raw = fs.readFileSync(p, "utf8");
|
|
40
|
+
return NextResponse.json({ raw, exists: true });
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.error("agents-md get error:", err);
|
|
43
|
+
return NextResponse.json(
|
|
44
|
+
{ error: err instanceof Error ? err.message : "Unknown error" },
|
|
45
|
+
{ status: 500 }
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function POST(request: NextRequest) {
|
|
51
|
+
try {
|
|
52
|
+
const { raw } = (await request.json()) as { raw?: string };
|
|
53
|
+
if (typeof raw !== "string") {
|
|
54
|
+
return NextResponse.json({ error: "raw string required" }, { status: 400 });
|
|
55
|
+
}
|
|
56
|
+
const p = getAgentsPath();
|
|
57
|
+
const dir = path.dirname(p);
|
|
58
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
59
|
+
fs.writeFileSync(p, raw.endsWith("\n") ? raw : raw + "\n", "utf8");
|
|
60
|
+
return NextResponse.json({ ok: true });
|
|
61
|
+
} catch (err) {
|
|
62
|
+
console.error("agents-md post error:", err);
|
|
63
|
+
return NextResponse.json(
|
|
64
|
+
{ error: err instanceof Error ? err.message : "Unknown error" },
|
|
65
|
+
{ status: 500 }
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GET/POST /api/config – read/write .shimwrappercheckrc (key=value + comments).
|
|
3
|
+
* Vercel-compatible; uses SHIM_PROJECT_ROOT when deployed.
|
|
4
|
+
*/
|
|
5
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import { getProjectRoot } from "@/lib/projectRoot";
|
|
9
|
+
|
|
10
|
+
const rcFileName = ".shimwrappercheckrc";
|
|
11
|
+
|
|
12
|
+
function getRcPath(): string {
|
|
13
|
+
return path.join(getProjectRoot(), rcFileName);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function GET() {
|
|
17
|
+
try {
|
|
18
|
+
const p = getRcPath();
|
|
19
|
+
if (!fs.existsSync(p)) {
|
|
20
|
+
return NextResponse.json({ raw: "", exists: false });
|
|
21
|
+
}
|
|
22
|
+
const raw = fs.readFileSync(p, "utf8");
|
|
23
|
+
return NextResponse.json({ raw, exists: true });
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error("config get error:", err);
|
|
26
|
+
return NextResponse.json(
|
|
27
|
+
{ error: err instanceof Error ? err.message : "Unknown error" },
|
|
28
|
+
{ status: 500 }
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function POST(request: NextRequest) {
|
|
34
|
+
try {
|
|
35
|
+
const { raw } = (await request.json()) as { raw?: string };
|
|
36
|
+
if (typeof raw !== "string") {
|
|
37
|
+
return NextResponse.json({ error: "raw string required" }, { status: 400 });
|
|
38
|
+
}
|
|
39
|
+
const p = getRcPath();
|
|
40
|
+
const dir = path.dirname(p);
|
|
41
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
42
|
+
fs.writeFileSync(p, raw.endsWith("\n") ? raw : raw + "\n", "utf8");
|
|
43
|
+
return NextResponse.json({ ok: true });
|
|
44
|
+
} catch (err) {
|
|
45
|
+
console.error("config post error:", err);
|
|
46
|
+
return NextResponse.json(
|
|
47
|
+
{ error: err instanceof Error ? err.message : "Unknown error" },
|
|
48
|
+
{ status: 500 }
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /api/run-checks – run scripts/run-checks.sh and return stdout/stderr.
|
|
3
|
+
* Vercel-compatible; uses SHIM_PROJECT_ROOT. Runs in project root.
|
|
4
|
+
*/
|
|
5
|
+
import { NextResponse } from "next/server";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import { exec } from "child_process";
|
|
9
|
+
import { promisify } from "util";
|
|
10
|
+
import { getProjectRoot } from "@/lib/projectRoot";
|
|
11
|
+
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
|
|
14
|
+
type ExecResult = { stdout: string; stderr: string; code?: number };
|
|
15
|
+
|
|
16
|
+
export async function POST() {
|
|
17
|
+
try {
|
|
18
|
+
const root = getProjectRoot();
|
|
19
|
+
const scriptPath = path.join(root, "scripts", "run-checks.sh");
|
|
20
|
+
if (!fs.existsSync(scriptPath)) {
|
|
21
|
+
return NextResponse.json({
|
|
22
|
+
error: "scripts/run-checks.sh not found",
|
|
23
|
+
stdout: "",
|
|
24
|
+
stderr: "",
|
|
25
|
+
code: 1,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
const opts = { cwd: root, maxBuffer: 2 * 1024 * 1024, shell: "/bin/bash" };
|
|
29
|
+
let stdout = "";
|
|
30
|
+
let stderr = "";
|
|
31
|
+
let code = 0;
|
|
32
|
+
try {
|
|
33
|
+
const out = await execAsync(`bash "${scriptPath}"`, opts);
|
|
34
|
+
stdout = out.stdout ?? "";
|
|
35
|
+
stderr = out.stderr ?? "";
|
|
36
|
+
} catch (e: unknown) {
|
|
37
|
+
const err = e as { stdout?: string; stderr?: string; code?: number };
|
|
38
|
+
stdout = err.stdout ?? "";
|
|
39
|
+
stderr = err.stderr ?? (err instanceof Error ? err.message : String(e));
|
|
40
|
+
code = err.code ?? 1;
|
|
41
|
+
}
|
|
42
|
+
return NextResponse.json({ stdout, stderr, code });
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.error("run-checks error:", err);
|
|
45
|
+
return NextResponse.json(
|
|
46
|
+
{
|
|
47
|
+
stdout: "",
|
|
48
|
+
stderr: err instanceof Error ? err.message : String(err),
|
|
49
|
+
code: 1,
|
|
50
|
+
},
|
|
51
|
+
{ status: 200 }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|