skillgendev 0.1.0__py3-none-any.whl
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.
- skillgen/__init__.py +7 -0
- skillgen/_data/claude/agents/route-analyzer.md +26 -0
- skillgen/_data/claude/commands/command.md +23 -0
- skillgen/_data/claude/skills/driver/SKILL.md +76 -0
- skillgen/_data/hintpacks/README.md +85 -0
- skillgen/_data/hintpacks/folders/astro-pages.yml +13 -0
- skillgen/_data/hintpacks/folders/nextjs-app.yml +13 -0
- skillgen/_data/hintpacks/folders/nextjs-pages.yml +13 -0
- skillgen/_data/hintpacks/folders/nuxt-pages.yml +13 -0
- skillgen/_data/hintpacks/folders/sveltekit-routes.yml +13 -0
- skillgen/_data/hintpacks/routers/aspnet-attributes.yml +16 -0
- skillgen/_data/hintpacks/routers/django.yml +12 -0
- skillgen/_data/hintpacks/routers/express.yml +9 -0
- skillgen/_data/hintpacks/routers/flask.yml +21 -0
- skillgen/_data/hintpacks/routers/laravel.yml +12 -0
- skillgen/_data/hintpacks/routers/phoenix.yml +13 -0
- skillgen/_data/hintpacks/routers/rails.yml +14 -0
- skillgen/_data/hintpacks/routers/react-router-jsx.yml +13 -0
- skillgen/_data/hintpacks/routers/route-objects-js.yml +21 -0
- skillgen/_data/hintpacks/routers/route-objects.yml +21 -0
- skillgen/_data/hintpacks/routers/spring.yml +13 -0
- skillgen/analyze/__init__.py +1 -0
- skillgen/analyze/prompt.py +189 -0
- skillgen/analyze/runner.py +457 -0
- skillgen/assets.py +69 -0
- skillgen/cli.py +1678 -0
- skillgen/compile/__init__.py +1 -0
- skillgen/compile/assess.py +175 -0
- skillgen/compile/fields.py +320 -0
- skillgen/compile/layout.py +87 -0
- skillgen/compile/merge.py +560 -0
- skillgen/compile/unopened.py +114 -0
- skillgen/config.py +165 -0
- skillgen/drift/__init__.py +1 -0
- skillgen/drift/check.py +113 -0
- skillgen/drift/diff.py +120 -0
- skillgen/errors.py +114 -0
- skillgen/export.py +417 -0
- skillgen/generate/__init__.py +1 -0
- skillgen/generate/bundle.py +251 -0
- skillgen/generate/evals.py +144 -0
- skillgen/generate/examples.py +167 -0
- skillgen/generate/fill_engine.js +202 -0
- skillgen/generate/fill_script.py +253 -0
- skillgen/generate/folder.py +115 -0
- skillgen/generate/index_page.py +218 -0
- skillgen/generate/index_template.html +86 -0
- skillgen/generate/inline_setter.py +725 -0
- skillgen/generate/layout_reference.py +72 -0
- skillgen/generate/locators.py +270 -0
- skillgen/generate/manual_steps.py +165 -0
- skillgen/generate/skill_md.py +872 -0
- skillgen/generate/user_rules.py +129 -0
- skillgen/graph/__init__.py +1 -0
- skillgen/graph/codegraph.py +527 -0
- skillgen/graph/connections.py +335 -0
- skillgen/graph/hubs.py +84 -0
- skillgen/graph/slice.py +241 -0
- skillgen/handoff.py +217 -0
- skillgen/logs.py +121 -0
- skillgen/model/__init__.py +1 -0
- skillgen/model/confidence.py +83 -0
- skillgen/model/facts.py +66 -0
- skillgen/model/page.py +489 -0
- skillgen/model/probe.py +117 -0
- skillgen/model/route.py +183 -0
- skillgen/model/serialize.py +592 -0
- skillgen/pipeline.py +1551 -0
- skillgen/probe/__init__.py +1 -0
- skillgen/probe/capture.py +153 -0
- skillgen/probe/classify.py +136 -0
- skillgen/probe/extract.js +164 -0
- skillgen/probe/journal.py +281 -0
- skillgen/probe/measure.js +24 -0
- skillgen/probe/runner.py +1066 -0
- skillgen/py.typed +0 -0
- skillgen/routes/__init__.py +1 -0
- skillgen/routes/astgrep.py +415 -0
- skillgen/routes/folders.py +131 -0
- skillgen/routes/hintpacks.py +227 -0
- skillgen/routes/merge.py +208 -0
- skillgen/routes/naming.py +202 -0
- skillgen/routes/paths.py +150 -0
- skillgen/schema/__init__.py +97 -0
- skillgen/schema/cli/add-rule.schema.json +49 -0
- skillgen/schema/cli/answer.schema.json +43 -0
- skillgen/schema/cli/check.schema.json +61 -0
- skillgen/schema/cli/doctor.schema.json +65 -0
- skillgen/schema/cli/export-chatgpt.schema.json +52 -0
- skillgen/schema/cli/export.schema.json +53 -0
- skillgen/schema/cli/generate.schema.json +169 -0
- skillgen/schema/cli/index.schema.json +48 -0
- skillgen/schema/cli/init.schema.json +49 -0
- skillgen/schema/cli/install.schema.json +47 -0
- skillgen/schema/cli/login.schema.json +40 -0
- skillgen/schema/cli/logs.schema.json +49 -0
- skillgen/schema/cli/prepare.schema.json +68 -0
- skillgen/schema/cli/probe.schema.json +63 -0
- skillgen/schema/cli/questions.schema.json +74 -0
- skillgen/schema/cli/routes.schema.json +85 -0
- skillgen/schema/cli/validate.schema.json +66 -0
- skillgen/schema/page-analysis.schema.json +523 -0
- skillgen/schema/page.schema.json +561 -0
- skillgen/schema/route-listing.schema.json +22 -0
- skillgen/validate/__init__.py +1 -0
- skillgen/validate/model_checks.py +127 -0
- skillgen/validate/scan.py +119 -0
- skillgen/validate/spec.py +191 -0
- skillgen/workspace.py +301 -0
- skillgendev-0.1.0.dist-info/METADATA +796 -0
- skillgendev-0.1.0.dist-info/RECORD +114 -0
- skillgendev-0.1.0.dist-info/WHEEL +4 -0
- skillgendev-0.1.0.dist-info/entry_points.txt +2 -0
- skillgendev-0.1.0.dist-info/licenses/LICENSE +201 -0
skillgen/__init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""Compile an app's code into one Agent Skills folder per page."""
|
|
2
|
+
|
|
3
|
+
# The public name (PyPI package, command, workspace folder) lives here only; everything
|
|
4
|
+
# else derives from it. The import package stays `skillgen` (src/skillgen/).
|
|
5
|
+
TOOL_NAME = "skillgendev"
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{tool}}-route-analyzer
|
|
3
|
+
description: Analyses one route of a web app for {{tool}}, reading its code read-only and writing the page-analysis JSON. Use one per route when generating several page skills.
|
|
4
|
+
tools: Read, Grep, Glob, Write
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You analyse one page of a web application so {{tool}} can write a skill that fills its form.
|
|
8
|
+
|
|
9
|
+
You receive a route, the path of a prompt file and the path where the analysis must be
|
|
10
|
+
written. Read the prompt file and follow it exactly. Read code only; never edit source
|
|
11
|
+
files. The only file you write is the analysis JSON at the path you were given.
|
|
12
|
+
|
|
13
|
+
The JSON must match `page-analysis.schema.json` (its path is in the prompt instructions
|
|
14
|
+
you received). Use the app's own words for labels and meanings. Mark every attribute you
|
|
15
|
+
deduced rather than read literally in `inferred`. Never copy real names, emails, numbers
|
|
16
|
+
or IDs from seeds, fixtures or tests.
|
|
17
|
+
|
|
18
|
+
Find every part of the form that is hidden until something is clicked: wizard steps behind
|
|
19
|
+
Next, tabs, accordion panels, dialogs opened by a button. Follow the state that shows each
|
|
20
|
+
part (a step counter, an active tab, an open flag) to the control that changes it, using
|
|
21
|
+
the imports the prompt's files point to. Describe each part as a view, in the order a
|
|
22
|
+
person fills them, with the click that reaches it from the part before. A field shown
|
|
23
|
+
because another field has a value is `visible_if`, not a view. You describe what to click;
|
|
24
|
+
{{tool}} does the clicking and checks it in a browser.
|
|
25
|
+
|
|
26
|
+
When done, reply with one line: the route, the number of fields, and any questions.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate Agent Skills that fill this app's forms, one per route. Usage: /{{tool}} /some/route, /{{tool}} all, or /{{tool}} all --name acme
|
|
3
|
+
argument-hint: "/route | all [--name prefix]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Generate page skills with {{tool}} for: $ARGUMENTS
|
|
7
|
+
|
|
8
|
+
Follow the `{{tool}}` skill. In short:
|
|
9
|
+
|
|
10
|
+
1. If `.{{tool}}/config.json` does not exist, run `{{tool}} init` (ask the user for the app's
|
|
11
|
+
display name and, if they have one, a dev URL).
|
|
12
|
+
2. For `all`: run `{{tool}} routes --all --json`, show the routes, and let the user drop or
|
|
13
|
+
rename any before generating. For one route, use it as given.
|
|
14
|
+
3. Run `{{tool}} generate --route <route> --json` (or `--all`), passing `--name` through
|
|
15
|
+
and `--xy` when the user wants x/y.
|
|
16
|
+
4. Follow each result's `next`, as the `{{tool}}` skill says, until nothing is left:
|
|
17
|
+
`analyse` means you read the prompt and write the analysis yourself (one
|
|
18
|
+
`{{tool}}-route-analyzer` subagent per route for several); `ask` means you ask the user
|
|
19
|
+
its question in chat, run `run` on a yes, then run `then`. A result with status
|
|
20
|
+
`exists` asks before a skill is recreated.
|
|
21
|
+
5. Report each skill folder and any open questions. Ask the user the open questions from
|
|
22
|
+
`{{tool}} questions --json`, record answers with `{{tool}} answer <id> "<answer>"`, then
|
|
23
|
+
generate again with `--overwrite`: the user is updating a skill they just made.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: {{tool}}
|
|
3
|
+
description: "Drives the {{tool}} compiler, which turns a web app's code into one Agent Skill per page so Claude can fill that page's form. Use when the user asks to generate, update, check or export page or form skills for their app."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# {{tool}}: generate page skills from an app's code
|
|
7
|
+
|
|
8
|
+
{{tool}} reads an app's code route by route and writes one skill folder per page
|
|
9
|
+
(`SKILL.md` + `scripts/fill.js`). Anyone can then fill that page in Claude or Cowork with
|
|
10
|
+
the built-in browser, with few tokens. It works for any framework and any app.
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
- `{{tool}} init [--app-name "Acme"] [--url http://localhost:3000] [--name acme]`
|
|
14
|
+
- `{{tool}} routes --all [--include "admin/*"] [--route /extra] --json`
|
|
15
|
+
- `{{tool}} generate --route /x [--name my-skill] [--overwrite] [--xy [--open STEP]] --json`
|
|
16
|
+
- `{{tool}} generate --all [--name acme] [--overwrite] [--xy] --json`
|
|
17
|
+
- `{{tool}} prepare --route /x --json` → writes the analysis prompt only, without generating.
|
|
18
|
+
- `{{tool}} questions --json`, `{{tool}} answer <id> "<answer>"`
|
|
19
|
+
- `{{tool}} login --url <page>` → opens a browser window; the user signs in and closes it.
|
|
20
|
+
- `{{tool}} add-rule <skill> "<rule>" [--check "key ^A"]`, or `--global`
|
|
21
|
+
- `{{tool}} validate`, `{{tool}} doctor [--fix]`
|
|
22
|
+
- `{{tool}} export [--zip] [--plugin]` → for Claude, Cowork or Claude Code;
|
|
23
|
+
`{{tool}} export-chatgpt [--zip] [--name acme]` → one ChatGPT plugin.
|
|
24
|
+
|
|
25
|
+
## Naming
|
|
26
|
+
The user chooses skill names. With one route, `--name` is the exact skill name. With
|
|
27
|
+
`--all`, `--name` is the prefix for every skill (`acme` → `acme-signup`). Names must be
|
|
28
|
+
lowercase letters, digits and single hyphens, at most 64 characters.
|
|
29
|
+
|
|
30
|
+
## Run, then follow `next` until nothing is left
|
|
31
|
+
{{tool}} never asks on its own; it has no terminal to ask from. When a route cannot
|
|
32
|
+
finish, its result has status `needs` (or `exists`) and a `next` object, and the exit
|
|
33
|
+
code is 3. Do what `next` says, then run its `then` command. Repeat until no result has
|
|
34
|
+
a `next`, or the user says no.
|
|
35
|
+
|
|
36
|
+
- `"action": "analyse"`: {{tool}} could not run the analysis itself (for example Claude
|
|
37
|
+
Code is not signed in). Do it yourself: read `prompt` and the files it lists, read-only,
|
|
38
|
+
following the imports they point to. Write one JSON object matching the schema in the
|
|
39
|
+
prompt to `write`. Then run `then`; {{tool}} uses your analysis while the code is
|
|
40
|
+
unchanged. For several routes, use one `{{tool}}-route-analyzer` subagent per route.
|
|
41
|
+
- `"action": "ask"`: only the user can decide or do this. Ask them `ask` in chat, as a
|
|
42
|
+
question, in your own words if that is clearer.
|
|
43
|
+
- On yes, run `run` when it is not empty, then run `then`.
|
|
44
|
+
- `need` `limit`: the AI's own limit is reached and `ask` says when it resets. Tell
|
|
45
|
+
the user, and stop. Do not read the code and write the analysis yourself: that
|
|
46
|
+
spends far more of the same limit. Run `then` once the limit has reset; the
|
|
47
|
+
analysis already done is reused.
|
|
48
|
+
- `need` `url`: their answer is the address; put it in place of `<url>` in `then`.
|
|
49
|
+
- `need` `login`: `run` opens a browser window and waits until the user signs in and
|
|
50
|
+
closes it, so give it a long timeout. Never type their password yourself.
|
|
51
|
+
- `need` `overwrite`: the skill exists; `then` recreates it. Notes in its user section
|
|
52
|
+
are kept.
|
|
53
|
+
- `need` `open`: the form's fields are hidden behind a click. Their answer is the
|
|
54
|
+
text of the button, tab or link; put it in place of `<label>` in `then`.
|
|
55
|
+
- `need` `server` or `probe`: the user starts their dev server or reinstalls; wait
|
|
56
|
+
until they say it is done, then run `then`.
|
|
57
|
+
- On no, stop that route and say what was left undone.
|
|
58
|
+
|
|
59
|
+
Answering open questions and generating again is the user updating a skill they made,
|
|
60
|
+
so pass `--overwrite` then.
|
|
61
|
+
|
|
62
|
+
## Rules
|
|
63
|
+
- Never edit the app's source while analysing.
|
|
64
|
+
- Never copy real personal data or secrets into an analysis or a skill.
|
|
65
|
+
- Facts you deduce go in `inferred`; {{tool}} keeps uncertain facts out of skills until the
|
|
66
|
+
developer confirms them.
|
|
67
|
+
- When you analyse a page yourself, describe every part hidden until a click (wizard
|
|
68
|
+
steps, tabs, accordion panels, dialogs) as `views`, in fill order, each with the click
|
|
69
|
+
that reaches it from the part before; the prompt says how. You never write click code:
|
|
70
|
+
{{tool}} walks the views in Chromium with `--xy`, measures every field, and the skill
|
|
71
|
+
walks them the same way when it fills the page.
|
|
72
|
+
- A running app is optional. A normal `generate` reads code only. Add `--xy` to also
|
|
73
|
+
measure where each field sits (x/y) on the dev copy; it only adds and never removes a
|
|
74
|
+
field. If the form appears only after a click, add `--route … --open STEP` (a CSS
|
|
75
|
+
selector or `text:Label`); it is saved, and the skill makes the same click. Dev or
|
|
76
|
+
staging only; submits are intercepted.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Hint packs
|
|
2
|
+
|
|
3
|
+
Hint packs are the only place framework knowledge lives. They are YAML data, read by
|
|
4
|
+
generic code; deleting this folder leaves a working tool that finds routes through the
|
|
5
|
+
other sources (your `--route`, the runtime crawl, Claude Code).
|
|
6
|
+
|
|
7
|
+
Every pack has an `id`, a `kind` and a short `about`. Three kinds exist.
|
|
8
|
+
|
|
9
|
+
## `kind: folder` — folder-based routing
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
id: nextjs-app
|
|
13
|
+
kind: folder
|
|
14
|
+
about: Next.js app router (app/**/page.tsx)
|
|
15
|
+
roots: [app, src/app] # folders to scan, relative to each project root
|
|
16
|
+
requires_any: [next.config.js, package.json] # files that mark a project root
|
|
17
|
+
page_files: ["page.{tsx,jsx,ts,js,mdx}"] # file names that make a folder a page
|
|
18
|
+
route_from: folder # folder: route is the folder path; file: route is the file path
|
|
19
|
+
index_names: [index] # with route_from: file, these names map to their folder
|
|
20
|
+
skip_segments: ["^\\(.*\\)$", "^@"] # path parts dropped from the route (groups, slots)
|
|
21
|
+
skip_files: ["^_", "^api$"] # path parts that make the whole file not a page
|
|
22
|
+
params: # how parameter segments are written → :name
|
|
23
|
+
- "^\\[\\[?\\.\\.\\.(?P<name>\\w+)\\]?\\]$"
|
|
24
|
+
- "^\\[(?P<name>\\w+)\\]$"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`requires_any` lets one repository hold several apps. Every folder that holds one
|
|
28
|
+
of these files, at any depth, is a project root, and `roots` is looked for inside
|
|
29
|
+
each. In a monorepo with `admin/next.config.js` and `site/package.json`, both
|
|
30
|
+
`admin/src/app` and `site/app` are scanned. Dependency and build folders
|
|
31
|
+
(`node_modules`, `dist`, hidden folders) are never searched. Without `requires_any`
|
|
32
|
+
the pack applies at the repository root only.
|
|
33
|
+
|
|
34
|
+
## `kind: router` — route declarations found with ast-grep
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
id: react-router-jsx
|
|
38
|
+
kind: router
|
|
39
|
+
about: <Route path="/x" element={<Page />} />
|
|
40
|
+
language: tsx
|
|
41
|
+
globs: ["**/*.tsx", "**/*.jsx"]
|
|
42
|
+
rule: # any ast-grep rule
|
|
43
|
+
pattern: <Route path=$PATH element={<$COMPONENT $$$ />} $$$ />
|
|
44
|
+
captures:
|
|
45
|
+
path: PATH # metavariable holding the route path (a string literal)
|
|
46
|
+
component: COMPONENT # optional: metavariable naming the page component
|
|
47
|
+
prefix_from: none # reserved for nested routers
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The component name is resolved to a file through the code graph, so packs never
|
|
51
|
+
describe import syntax. When the captured text is not a plain name (Rails writes
|
|
52
|
+
`"registrations#new"`), two optional keys reshape it:
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
component_match: "^[\"']?(?P<name>[\\w/]+)#" # regex with a `name` group
|
|
56
|
+
component_format: "{pascal}Controller" # {name} or {pascal}: registrations → RegistrationsController
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Shipped router packs: React Router, route objects, Express, Flask, Django, Laravel,
|
|
60
|
+
Rails, Spring MVC, ASP.NET Core attributes and Phoenix. Each has a tiny sample app under
|
|
61
|
+
`tests/fixtures/hintpacks/<id>/` or `tests/fixtures/<app>/`.
|
|
62
|
+
|
|
63
|
+
When no pack matches, skillgendev asks Claude Code to read the code graph's likely router
|
|
64
|
+
files (`skillgendev routes --all --ask-claude`), so a missing pack never blocks anyone.
|
|
65
|
+
|
|
66
|
+
## `kind: validator` — field constraints found with ast-grep
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
id: zod-string-min
|
|
70
|
+
kind: validator
|
|
71
|
+
about: z.string().min(n) inside an object schema
|
|
72
|
+
language: typescript
|
|
73
|
+
rule: { pattern: "$FIELD: z.string().min($MIN)" }
|
|
74
|
+
captures: { field: FIELD, min_length: MIN }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Validator packs only add `EXTRACTED` facts that Claude Code would otherwise read
|
|
78
|
+
itself; they make analysis cheaper, never required.
|
|
79
|
+
|
|
80
|
+
## Adding a pack
|
|
81
|
+
|
|
82
|
+
1. Add the YAML file here.
|
|
83
|
+
2. Add a tiny example under `tests/fixtures/hintpacks/<id>/` and a case in
|
|
84
|
+
`tests/test_hintpacks.py`.
|
|
85
|
+
3. Run `uv run pytest tests/test_hintpacks.py`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: astro-pages
|
|
2
|
+
kind: folder
|
|
3
|
+
about: "Astro src/pages/**/*.astro"
|
|
4
|
+
roots: [src/pages]
|
|
5
|
+
page_files: ["*.astro"]
|
|
6
|
+
route_from: file
|
|
7
|
+
index_names: [index]
|
|
8
|
+
skip_segments: []
|
|
9
|
+
skip_files: ["^_"]
|
|
10
|
+
params:
|
|
11
|
+
- "^\\[\\.\\.\\.(?P<name>\\w+)\\]$"
|
|
12
|
+
- "^\\[(?P<name>\\w+)\\]$"
|
|
13
|
+
requires_any: ["astro.config.mjs", "astro.config.ts", "astro.config.js"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: nextjs-app
|
|
2
|
+
kind: folder
|
|
3
|
+
about: "Next.js app router (app/**/page.tsx)"
|
|
4
|
+
roots: [app, src/app]
|
|
5
|
+
# Where a Next.js project starts, so an app inside a monorepo is found too.
|
|
6
|
+
requires_any: ["next.config.js", "next.config.mjs", "next.config.ts", "package.json"]
|
|
7
|
+
page_files: ["page.tsx", "page.jsx", "page.ts", "page.js", "page.mdx"]
|
|
8
|
+
route_from: folder
|
|
9
|
+
skip_segments: ["^\\(.*\\)$", "^@"]
|
|
10
|
+
skip_files: ["^_", "^api$"]
|
|
11
|
+
params:
|
|
12
|
+
- "^\\[\\[?\\.\\.\\.(?P<name>\\w+)\\]?\\]$"
|
|
13
|
+
- "^\\[(?P<name>\\w+)\\]$"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: nextjs-pages
|
|
2
|
+
kind: folder
|
|
3
|
+
about: "Next.js pages router (pages/**/*.tsx)"
|
|
4
|
+
roots: [pages, src/pages]
|
|
5
|
+
page_files: ["*.tsx", "*.jsx", "*.ts", "*.js", "*.mdx"]
|
|
6
|
+
route_from: file
|
|
7
|
+
index_names: [index]
|
|
8
|
+
skip_segments: []
|
|
9
|
+
skip_files: ["^_", "^api$"]
|
|
10
|
+
params:
|
|
11
|
+
- "^\\[\\[?\\.\\.\\.(?P<name>\\w+)\\]?\\]$"
|
|
12
|
+
- "^\\[(?P<name>\\w+)\\]$"
|
|
13
|
+
requires_any: ["next.config.js", "next.config.mjs", "next.config.ts"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: nuxt-pages
|
|
2
|
+
kind: folder
|
|
3
|
+
about: "Nuxt pages/ directory (pages/**/*.vue)"
|
|
4
|
+
roots: [pages, app/pages, src/pages]
|
|
5
|
+
page_files: ["*.vue"]
|
|
6
|
+
route_from: file
|
|
7
|
+
index_names: [index]
|
|
8
|
+
skip_segments: ["^\\(.*\\)$"]
|
|
9
|
+
skip_files: ["^_"]
|
|
10
|
+
params:
|
|
11
|
+
- "^\\[\\.\\.\\.(?P<name>\\w+)\\]$"
|
|
12
|
+
- "^\\[\\[?(?P<name>\\w+)\\]?\\]$"
|
|
13
|
+
requires_any: ["nuxt.config.ts", "nuxt.config.js"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: sveltekit-routes
|
|
2
|
+
kind: folder
|
|
3
|
+
about: "SvelteKit src/routes/**/+page.svelte"
|
|
4
|
+
roots: [src/routes]
|
|
5
|
+
# Where a SvelteKit project starts, so an app inside a monorepo is found too.
|
|
6
|
+
requires_any: ["svelte.config.js", "svelte.config.ts", "package.json"]
|
|
7
|
+
page_files: ["+page.svelte"]
|
|
8
|
+
route_from: folder
|
|
9
|
+
skip_segments: ["^\\(.*\\)$"]
|
|
10
|
+
skip_files: []
|
|
11
|
+
params:
|
|
12
|
+
- "^\\[\\[?\\.\\.\\.(?P<name>\\w+)\\]?\\]$"
|
|
13
|
+
- "^\\[\\[?(?P<name>\\w+)(=\\w+)?\\]?\\]$"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
id: aspnet-attributes
|
|
2
|
+
kind: router
|
|
3
|
+
about: "ASP.NET Core [Route(\"…\")] and [HttpGet(\"…\")] attributes (conventional routes are left to Claude; Razor @page routes come from Graphify)"
|
|
4
|
+
language: csharp
|
|
5
|
+
globs: ["**/*.cs"]
|
|
6
|
+
rule:
|
|
7
|
+
kind: attribute
|
|
8
|
+
all:
|
|
9
|
+
- has: { field: name, regex: "^(HttpGet|Route)$" }
|
|
10
|
+
- has:
|
|
11
|
+
kind: attribute_argument_list
|
|
12
|
+
has:
|
|
13
|
+
kind: attribute_argument
|
|
14
|
+
has: { kind: string_literal, pattern: $PATH }
|
|
15
|
+
captures:
|
|
16
|
+
path: PATH
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
id: flask
|
|
2
|
+
kind: router
|
|
3
|
+
about: "Flask-style @app.route('/x') and @blueprint.route('/x') decorators"
|
|
4
|
+
language: python
|
|
5
|
+
globs: ["**/*.py"]
|
|
6
|
+
rule:
|
|
7
|
+
kind: decorated_definition
|
|
8
|
+
has:
|
|
9
|
+
kind: decorator
|
|
10
|
+
has:
|
|
11
|
+
any:
|
|
12
|
+
- pattern: $APP.route($PATH)
|
|
13
|
+
- pattern: $APP.route($PATH, $$$ARGS)
|
|
14
|
+
- pattern: $APP.get($PATH)
|
|
15
|
+
all:
|
|
16
|
+
- has:
|
|
17
|
+
field: definition
|
|
18
|
+
has: { field: name, pattern: $COMPONENT }
|
|
19
|
+
captures:
|
|
20
|
+
path: PATH
|
|
21
|
+
component: COMPONENT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
id: laravel
|
|
2
|
+
kind: router
|
|
3
|
+
about: "Laravel Route::get('/x', [Controller::class, 'action']) and Route::get('/x', ...) declarations"
|
|
4
|
+
language: php
|
|
5
|
+
globs: ["routes/**/*.php"]
|
|
6
|
+
rule:
|
|
7
|
+
any:
|
|
8
|
+
- pattern: "Route::get($PATH, [$COMPONENT::class, $ACTION])"
|
|
9
|
+
- pattern: "Route::get($PATH, $$$REST)"
|
|
10
|
+
captures:
|
|
11
|
+
path: PATH
|
|
12
|
+
component: COMPONENT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: phoenix
|
|
2
|
+
kind: router
|
|
3
|
+
about: "Phoenix router: get \"/signup\", SignupController, :new and live \"/contact\", ContactLive"
|
|
4
|
+
language: elixir
|
|
5
|
+
globs: ["**/router.ex", "**/*_router.ex"]
|
|
6
|
+
rule:
|
|
7
|
+
any:
|
|
8
|
+
- pattern: "get $PATH, $COMPONENT, $ACTION"
|
|
9
|
+
- pattern: "live $PATH, $COMPONENT"
|
|
10
|
+
- pattern: "live $PATH, $COMPONENT, $ACTION"
|
|
11
|
+
captures:
|
|
12
|
+
path: PATH
|
|
13
|
+
component: COMPONENT
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
id: rails
|
|
2
|
+
kind: router
|
|
3
|
+
about: "Rails routes.rb: get \"/signup\", to: \"registrations#new\" (resources blocks are left to Claude)"
|
|
4
|
+
language: ruby
|
|
5
|
+
globs: ["config/routes.rb", "config/routes/**/*.rb"]
|
|
6
|
+
rule:
|
|
7
|
+
any:
|
|
8
|
+
- pattern: "get $PATH, to: $COMPONENT"
|
|
9
|
+
- pattern: "get $PATH, to: $COMPONENT, $$$REST"
|
|
10
|
+
captures:
|
|
11
|
+
path: PATH
|
|
12
|
+
component: COMPONENT
|
|
13
|
+
component_match: "^[\"']?(?P<name>[\\w/]+)#"
|
|
14
|
+
component_format: "{pascal}Controller"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: react-router-jsx
|
|
2
|
+
kind: router
|
|
3
|
+
about: "React Router JSX routes, <Route path=\"/x\" element={<Page />} />"
|
|
4
|
+
language: tsx
|
|
5
|
+
globs: ["**/*.tsx", "**/*.jsx"]
|
|
6
|
+
rule:
|
|
7
|
+
pattern: <Route path="$PATH" $$$ATTRIBUTES />
|
|
8
|
+
has:
|
|
9
|
+
pattern: <$COMPONENT $$$PROPS />
|
|
10
|
+
stopBy: end
|
|
11
|
+
captures:
|
|
12
|
+
path: PATH
|
|
13
|
+
component: COMPONENT
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
id: route-objects-js
|
|
2
|
+
kind: router
|
|
3
|
+
about: "Route objects in JavaScript files, such as { path: '/x', component: Page } (Vue Router, React Router data routers)"
|
|
4
|
+
language: javascript
|
|
5
|
+
globs: ["**/*.js", "**/*.mjs", "**/*.cjs"]
|
|
6
|
+
rule:
|
|
7
|
+
kind: object
|
|
8
|
+
all:
|
|
9
|
+
- has:
|
|
10
|
+
kind: pair
|
|
11
|
+
all:
|
|
12
|
+
- has: { field: key, regex: "^path$" }
|
|
13
|
+
- has: { field: value, pattern: $PATH }
|
|
14
|
+
- has:
|
|
15
|
+
kind: pair
|
|
16
|
+
all:
|
|
17
|
+
- has: { field: key, regex: "^(component|element)$" }
|
|
18
|
+
- has: { field: value, pattern: $COMPONENT }
|
|
19
|
+
captures:
|
|
20
|
+
path: PATH
|
|
21
|
+
component: COMPONENT
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
id: route-objects
|
|
2
|
+
kind: router
|
|
3
|
+
about: "Route objects such as { path: '/x', component: Page } (Vue Router, Angular, React Router data routers)"
|
|
4
|
+
language: typescript
|
|
5
|
+
globs: ["**/*.ts", "**/*.mts", "**/*.cts"]
|
|
6
|
+
rule:
|
|
7
|
+
kind: object
|
|
8
|
+
all:
|
|
9
|
+
- has:
|
|
10
|
+
kind: pair
|
|
11
|
+
all:
|
|
12
|
+
- has: { field: key, regex: "^path$" }
|
|
13
|
+
- has: { field: value, pattern: $PATH }
|
|
14
|
+
- has:
|
|
15
|
+
kind: pair
|
|
16
|
+
all:
|
|
17
|
+
- has: { field: key, regex: "^(component|element)$" }
|
|
18
|
+
- has: { field: value, pattern: $COMPONENT }
|
|
19
|
+
captures:
|
|
20
|
+
path: PATH
|
|
21
|
+
component: COMPONENT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
id: spring
|
|
2
|
+
kind: router
|
|
3
|
+
about: "Spring MVC @GetMapping(\"/signup\") and @RequestMapping(\"/signup\") on controller methods"
|
|
4
|
+
language: java
|
|
5
|
+
globs: ["**/*.java", "**/*.kt"]
|
|
6
|
+
rule:
|
|
7
|
+
any:
|
|
8
|
+
- pattern: "@GetMapping($PATH)"
|
|
9
|
+
- pattern: "@GetMapping(value = $PATH)"
|
|
10
|
+
- pattern: "@GetMapping(path = $PATH)"
|
|
11
|
+
- pattern: "@RequestMapping($PATH)"
|
|
12
|
+
captures:
|
|
13
|
+
path: PATH
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""The analysis step: prompts, the page-analysis schema, and runners."""
|