Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# TinyEngine — Repository Instructions for Coding Agents

## Purpose and Scope

This file is the canonical source of truth for repo-wide agent instructions.

- Applies to the whole repository unless a closer `AGENTS.md` overrides it for a subtree.
- `CLAUDE.md` is a compatibility entrypoint that imports this file. Do not maintain a second independent copy of the same rules.
- Keep this file limited to repo-wide guidance. Package-specific implementation details belong in package-level instruction files.

## Repository Snapshot

- Monorepo: pnpm workspaces + lerna (independent versioning)
- Primary stack: Vue 3, Vite, JavaScript/TypeScript
- Package manager: `pnpm` only for interactive work in this repo
- Designer app: `designer-demo/`
- Local mock backend: `mockServer/`

## Working Model

- Inspect the affected package, its `package.json`, and the nearest instruction file before editing.
- Keep changes scoped. Do not normalize unrelated files or rename fixtures just for consistency.
- Prefer targeted package-level validation over whole-repo commands when possible.
- Treat `pnpm lint` and `pnpm format` as mutating commands, not read-only verification.
- Do not invoke `npm` or `yarn` directly for normal repo work. Existing package scripts may still shell out internally; leave that alone unless the task is specifically about package scripts.

## Common Commands

### Read-mostly commands

```sh
pnpm install
pnpm dev
pnpm build:plugin
pnpm build:alpha
pnpm --filter @opentiny/tiny-engine-dsl-vue test:unit
```

### Mutating commands

```sh
pnpm lint # ESLint with --fix
pnpm format # Prettier --write
```

Canonical script definitions live in:

- `package.json`
- `packages/*/package.json`
- `.github/workflows/push-check.yml`
- `.github/workflows/Release.yml`

## Verification Matrix

Run the smallest sufficient verification for the change surface, then expand if the change is broad or risky.

1. Docs-only changes:
No code verification required unless the docs change commands or workflow descriptions that should be checked against source files.
2. `packages/vue-generator/**`:
Run the affected testcase or `pnpm --filter @opentiny/tiny-engine-dsl-vue test:unit`.
If generator behavior changes, run the full `test:unit` suite before handoff and inspect any changed `expected/*.vue` files.
3. Published library packages under `packages/**`:
Run the package-local `test` script if one exists.
Run `pnpm build:plugin` when build output or published package behavior may be affected.
4. `designer-demo/**` or shared packages consumed by the demo:
Run `pnpm build:alpha`.
5. Cross-package build or release-facing changes:
Run `pnpm build:plugin` and `pnpm build:alpha`.
6. Config, workspace, CI, or release script changes:
Verify the directly affected command(s) after approval.

## Approval Boundaries

### Always OK

- Read any source file
- Run targeted tests and builds
- Edit implementation files inside existing packages
- Add or update tests that match the scope of the change
- Update docs that reflect current repo behavior

### Ask First

- Changing workspace, lerna, pnpm, ESLint, Prettier, or TypeScript configuration
- Modifying CI workflows, release scripts, or publish flows
- Upgrading major dependencies or changing pinned overrides
- Reordering or adding/removing default vue-generator attribute hooks
- Large-scale edits to generated mappings or vendored patches

When asking first, include:

- what you want to change
- why the current rules or implementation are insufficient
- what verification you would run after approval

### Never

- Use `npm` or `yarn` directly for routine repo commands
- Skip hooks with `--no-verify`
- Hardcode versions for workspace packages
- Edit `patches/` without understanding the upstream issue and the patch purpose
- Rewrite generated expectations or snapshots without validating the new output first

## Task-Specific Expectations

- Bug fix:
Add or update a regression test when behavior changes.
- Refactor:
Preserve behavior and prove it with targeted verification.
- Snapshot or generated output change:
Explain why the output changed and list the affected fixture directories.
- Commit or PR work:
Only do it if asked. Use Conventional Commits and target `develop` unless the user specifies otherwise.

## Gotchas

- `pnpm install` is enforced by `preinstall`; npm and yarn are rejected for direct repo usage.
- `pnpm lint` writes fixes. Use it deliberately.
- CI relies on `build:plugin` and `build:alpha`, not only lint or unit tests.
- Test directories such as `test/`, `expected/`, and `output/` are not always linted; do not treat lint success as fixture validation.
7 changes: 7 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# TinyEngine — Claude Code Entry

This file is intentionally thin. The canonical repo-wide instructions live in `AGENTS.md`.

@./AGENTS.md

When working inside a subtree that has its own `CLAUDE.md`, follow the closer file as an extension of these repo-wide rules.
126 changes: 126 additions & 0 deletions packages/vue-generator/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# TinyEngine vue-generator — Package Instructions

## Scope

This file applies to `packages/vue-generator/**`.

- These rules extend the repo-wide rules in the root `AGENTS.md`.
- Keep package-specific generator details here instead of growing the root file.

## Package Goal

`@opentiny/tiny-engine-dsl-vue` converts TinyEngine DSL schema JSON plus components map JSON into Vue single-file components.

This package is responsible for code generation output. Runtime behavior, designer-side execution, and app-level integration fixes should stay in their owning packages unless the generated SFC output is wrong.

## Key Paths

- `src/generator/vue/sfc/genSetupSFC.js`
- `src/generator/vue/sfc/generateAttribute.js`
- `src/generator/vue/sfc/generateTemplate.js`
- `src/generator/vue/sfc/generateScript.js`
- `src/generator/vue/sfc/generateStyle.js`
- `src/utils/formatCode.js`
- `test/testcases/sfc/`
- `test/testcases/element-plus-case/`
- `test/testcases/generator/`

## Architecture Rules

### Core pipeline

1. Input: schema JSON plus components map JSON
2. `CodeGenerator` hook pipeline: `transformStart` -> `transform` -> `transformEnd`
3. `genSetupSFC` orchestrates template, attribute, script, and style generation
4. Output: a complete `.vue` SFC

### Default attribute hook order

The default hook chain registered in `genSetupSFC.js` executes in this order:

1. `handleSlotParams`
2. `handleJsxModelValueUpdate`
3. `handleConditionAttrHook`
4. `handleLoopAttrHook`
5. `handleSlotBindAttrHook`
6. `handleAttrKeyHook`
7. `handlePrimitiveAttributeHook`
8. `handleExpressionAttrHook`
9. `handleJSFunctionAttrHook`
10. `handleI18nAttrHook`
11. `handleTinyIconPropsHook`
12. `handleObjBindAttrHook`
13. `handleEventAttrHook`

`handleBindUtilsHooks` still exists in `generateAttribute.js`, but it is not part of the default hook chain.

Do not reorder or change the default hook chain without approval.

### Global hooks

`genSetupSFC.js` exposes shared `globalHooks` helpers:

- `addState(key, value)`
- `addImport(fromPath, config)`
- `addMethods(key, value)`
- `addStatement(statement)`
- `setScriptConfig(config)`

These helpers mutate shared script-generation state. When debugging generated `<script>` output, imports, methods, or script config, inspect `genSetupSFC.js` and the downstream script generation path before adding new hooks.

### Quote-handling rules

- Primitive string attributes containing `"` may be emitted as `&quot;` or as a `v-bind` string literal, depending on whether the content also contains `'`.
- JSX slot mode is a separate path; do not assume primitive attribute escaping rules apply there unchanged.
- Quote behavior is sensitive to Prettier reformatting. Validate final formatted output, not only intermediate strings.
- When debugging quote output, inspect `generateAttribute.js` first and verify the formatted `.vue` result rather than raw intermediate strings.

## Fixture and Snapshot Workflow

- SFC cases live under `test/testcases/sfc/<caseName>/`.
- Follow the nearest existing fixture style. Valid schema names include `schema.json`, `page.schema.json`, `block.schema.json`, and `blocks.schema.json`.
- Components maps may be `components-map.json` or `componentsMap.json`.
- Expected outputs live in `expected/*.vue` and are compared with `toMatchFileSnapshot()` after `formatCode(res, 'vue')`.
- Test entry files typically follow `test/testcases/sfc/<caseName>/<caseName>.test.js`.

When generator output intentionally changes:

1. Update or add the smallest focused testcase that exposes the behavior.
2. Keep new fixtures minimal and isolate a single behavior whenever possible.
3. Regenerate or inspect the formatted output for that testcase.
4. Update only the affected `expected/*.vue` files.
5. Rerun the targeted testcase and then the full `test:unit` suite.

Do not bulk-rename fixture files just to normalize naming.

## Verification

Use the narrowest command that proves the change, then broaden as needed.

- Single testcase:
`pnpm --filter @opentiny/tiny-engine-dsl-vue test:unit -- --run test/testcases/sfc/<case>/<case>.test.js`
- Full unit suite:
`pnpm --filter @opentiny/tiny-engine-dsl-vue test:unit`
- Full coverage harness:
`pnpm --filter @opentiny/tiny-engine-dsl-vue test`
- Build plus integration-style check:
`pnpm --filter @opentiny/tiny-engine-dsl-vue test:latest`

Run the full `test:unit` suite before handoff if a change touches shared attribute generation, hook registration, script/style/template generation, or output formatting.

Use `test` or `test:latest` when the change affects broad generator behavior, package build output, or integration between generation and package build steps.

## Ask First

- Changing the default hook chain in `genSetupSFC.js`
- Editing `src/constant/index.js`
- Changing package build tooling or package scripts
- Changing shared quote-generation behavior across multiple attribute paths
- Changing quote-generation behavior before adding a focused testcase that proves the intended output

## Never

- Update `expected/*.vue` without validating the formatted generator output first
- Bypass `formatCode(res, 'vue')` when comparing expected SFC output
- Assume one fixture naming convention is canonical across the whole package
- Treat a snapshot diff by itself as proof that generated behavior is correct
5 changes: 5 additions & 0 deletions packages/vue-generator/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# TinyEngine vue-generator — Claude Code Entry

This file is intentionally thin. The canonical package-specific instructions live in `AGENTS.md`.

@./AGENTS.md
Loading