Skip to content
Merged
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
57 changes: 57 additions & 0 deletions .github/skills/create-userscript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Create Userscript Skill

GitHub Copilot skill for creating new MusicBrainz userscripts from `scripts/_template`.

## What It Does

- Collects script metadata (`id`, `display`, `desc`, `match`, optional `ui`).
- Runs the existing TypeScript CLI tool at `scripts/create-script.mts` via `yarn create-script`.
- Scaffolds a ready-to-edit script package under `scripts/<id>/`.

## Command

```bash
yarn create-script --id=<id> --display="<display>" --desc="<description>" --match="<pattern1>,<pattern2>" --ui=<true|false>
```

## Required Inputs

- `id`: kebab-case and unique (for example `my-script`).
- `display`: human-readable name.
- `desc`: short description.
- `match`: one or more comma-separated userscript match patterns.

## Optional Inputs

- `ui=true`: adds Solid/Kobalte UI dependencies.
- `version`, `runAt`, `baseUrl`.

## Generated Structure

```text
scripts/<id>/
├── src/index.ts
├── tests/basic.spec.ts
├── assets/
├── package.json
├── tsconfig.json
├── vite.config.ts
├── playwright.config.ts
├── README.md
└── CHANGELOG.md
```

## Next Steps

```bash
yarn workspace @dvirtz/<id> build
yarn workspace @dvirtz/<id> lint
yarn workspace @dvirtz/<id> test
```

## Notes

- For implementation patterns, inspect:
- `scripts/acum-work-import/`
- `scripts/setlistfm-musicbrainz-import/`
- `scripts/single-language-tracklist/`
241 changes: 241 additions & 0 deletions .github/skills/create-userscript/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
---
name: create-userscript
description: Creates a new MusicBrainz userscript from the monorepo template. Use this skill when the user asks to create a new userscript for MusicBrainz or a similar task involving userscript generation.
license: MIT
---

# Creating a New MusicBrainz Userscript

This skill guides you through creating a new userscript from the template in the musicbrainz-scripts monorepo.

## When to Use This Skill

Activate this skill when:

- The user explicitly asks to "create a new userscript"
- The user wants to "add a new script" to the repository
- The user describes building a new MusicBrainz enhancement tool

## Template System Overview

The monorepo uses a token-based template system:

**Template Location:** `scripts/_template/`

**Token Placeholders (replaced during creation):**

- `__ID__` → kebab-case script identifier (e.g., `acum-work-import`)
- `__DISPLAY_NAME__` → User-friendly display name
- `__DESCRIPTION__` → Script description
- `__VERSION__` → Initial version (defaults to 1.0.0)
- `__MATCH_ARRAY__` → Array of URL patterns the script matches
- `__BASE_URL__` → Base URL for tests (defaults to <https://test.musicbrainz.org>)
- `__RUN_AT__` → Tampermonkey run-at timing (defaults to document-end)
- `__ICON_LINE__` → Icon URL line (optional, omitted if not provided)

## Step-by-Step Instructions

## Mandatory Interaction Rule

Do not scaffold immediately from only a script name.

- If any required input is missing, ask follow-up questions first.
- Do not invent defaults for required fields without explicit user confirmation.
- Allowed auto-fill only when explicitly confirmed by the user (for example: “use defaults”).
- Before running `yarn create-script`, echo the final values and ask for a short confirmation.

Required inputs that must be explicitly provided or confirmed:

- `id`
- `display`
- `desc`
- `match`

### 1. Collect Required Information

Ask the user for the following details (if not already provided):

1. **Script ID** (kebab-case, e.g., `my-awesome-script`)
- Validation: Must be lowercase with hyphens only, no spaces or underscores
- Used in npm package name: `@dvirtz/{script-id}`
- Must be unique (not already exist in `scripts/` directory)

2. **Display Name** (friendly name, e.g., "My Awesome Script")
- Used in package.json and documentation

3. **Description** (what the script does)
- Used in package.json and README

4. **URL Patterns** (which websites the script should run on)
- Examples: `*://*.musicbrainz.org/*`, `*://example.com/specific-path/*`
- Should be provided as an array of patterns
- Required for Tampermonkey to know when to execute the script

5. **Needs UI** (optional, defaults to false)
- Ask if unclear; do not silently assume
- If yes, inform user that `@kobalte/core`, `solid-js`, and `@repo/common-ui` will be added as dependencies

If the user prompt is minimal (for example only `create userscript <name>`), ask this compact checklist before any scaffolding:

1. Display name
2. Description
3. Match pattern(s)
4. Include UI (`true`/`false`)

If the user says “use defaults,” use:

- `display`: title-cased `id`
- `desc`: same as display in sentence case
- `match`: `*://*.musicbrainz.org/*`
- `ui`: `false`

Then still show the final resolved values and request confirmation.

### 2. Validate Inputs

Before proceeding, verify:

- Script ID is in kebab-case (lowercase, hyphens only)
- Script ID doesn't already exist in the `scripts/` directory
- Display name is non-empty
- At least one URL pattern is provided
- URL patterns are in valid Tampermonkey format

### 3. Generate the Script

Only run this step after collecting/confirming all required inputs.

Use Copilot's terminal execution to run the existing TypeScript CLI tool:

```bash
yarn create-script --id=<script-id> --display="<display-name>" --desc="<description>" --match="<pattern1>,<pattern2>" --ui=<true|false>
```

**Example:**

```bash
yarn create-script --id=my-awesome-script --display="My Awesome Script" --desc="Adds cool features to MusicBrainz" --match="*://*.musicbrainz.org/*" --ui=false
```

**Parameters:**

- `--id` (required): kebab-case script identifier
- `--display` (required): Display name (user-friendly)
- `--desc` (required): Script description
- `--match` (required): Comma-separated URL match patterns
- Single pattern: `"*://*.musicbrainz.org/*"`
- Multiple patterns: `"*://*.musicbrainz.org/*,*://musicbrainz.org/*"`
- `--ui` (optional): `true` or `false`, defaults to `false` (adds Solid.js + Kobalte UI dependencies)
- `--baseUrl` (optional): Base URL for Playwright tests, defaults to `https://test.musicbrainz.org`
- `--version` (optional): Initial version, defaults to `1.0.0`
- `--runAt` (optional): Tampermonkey run-at timing, defaults to `document-end`

**Important Notes:**

- No spaces around `=` in arguments
- Match patterns are comma-separated strings, not JSON arrays
- The tool is defined in `scripts/create-script.mts`
- Command must be run from the repository root directory
- The tool automatically validates inputs and runs ESLint fixes

### 4. Report Results

After successful creation, provide the user with:

1. **Generated Files Location:** `scripts/{script-id}/`

2. **Directory Structure:**

```text
scripts/{script-id}/
├── src/
│ └── index.ts ← Main script file (user will customize)
├── tests/
│ └── basic.spec.ts ← E2E tests using Playwright
├── assets/ ← For screenshots/resources
├── package.json ← Workspace package
├── tsconfig.json ← TypeScript config
├── vite.config.ts ← Build configuration
├── playwright.config.ts ← Test configuration
├── README.md ← Documentation
└── CHANGELOG.md ← Version history
```

3. **Next Steps:**
- Edit `scripts/{script-id}/src/index.ts` with script logic
- Update `README.md` with detailed feature documentation
- Add tests in `scripts/{script-id}/tests/`
- Run `yarn workspace @dvirtz/{script-id} build` to compile
- Run `yarn workspace @dvirtz/{script-id} test` to run tests
- Run `yarn workspace @dvirtz/{script-id} lint` to check code style

4. **Key Shared Libraries Available:**
- `@repo/common` → Utility functions (array operations, etc.)
- `@repo/common-ui` → UI components for forms/settings
- `@repo/fetch` → Fetch wrapper with error handling
- `@repo/musicbrainz-ext` → MusicBrainz API extensions
- `@repo/rxjs-ext` → RxJS helper functions

5. **Building and Distribution:**
- Built output: `scripts/{script-id}/dist/{script-id}.user.js`
- Install via Tampermonkey: Add the dist file URL to script manager
- All scripts use Vite for bundling and support hot reload during development

### 5. Error Handling

If the script creation fails:

- Check if script ID already exists
- Validate that all required parameters are provided
- Ensure script ID follows kebab-case format
- Look at the helper script output for specific errors
- Suggest re-running with corrected parameters

## Workspace Context

**Monorepo Structure:**

- Root: `musicbrainz-scripts/`
- Scripts: `scripts/`
- Shared libraries: `lib/`
- Template: `scripts/_template/`

**Build System:**

- Uses Turbo for task orchestration
- Uses Yarn workspaces for monorepo management
- Uses Vite for bundling individual scripts
- Uses Playwright for E2E testing

**Package Naming Convention:**

- Scope: `@dvirtz`
- Package: `@dvirtz/{script-id}`
- Entry point: `src/index.ts`
- Built output: `dist/{script-id}.user.js`

## Reference Examples

Existing scripts to reference:

- `scripts/acum-work-import/` → Complex script with UI components
- `scripts/setlistfm-musicbrainz-import/` → Multi-file script with imports logic
- `scripts/single-language-tracklist/` → Simpler script without UI

Check these for patterns on:

- How to structure multi-file scripts
- How to import and use shared libraries
- How to implement UI components
- Test patterns using Playwright

## Success Criteria

The skill has succeeded when:

1. Script directory created at `scripts/{script-id}/`
2. All template files copied and token-replaced
3. `package.json` reflects correct metadata
4. User can run `yarn workspace @dvirtz/{script-id} build` without errors
5. User can run `yarn workspace @dvirtz/{script-id} lint` without errors
6. User can edit `src/index.ts` and see changes when running build
26 changes: 26 additions & 0 deletions .github/skills/userscript-implementation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Userscript Implementation Skill

Guidance for implementing MusicBrainz userscripts with consistent structure, tests, and reuse across the monorepo.

## What It Enforces

- Test driven development.
- Minimal `index.ts` files with UI in `.tsx` modules.
- Single responsibility, modular design.
- Reuse of shared components and libraries.
- Extraction of shared logic to common libraries when applicable.
- Mount UI using the toolbox module to keep a common appearance.
- Mimic the website UI when adding new UI elements.
- Lint-clean code.

## When To Apply

Use this skill for any new userscript feature work or refactors of existing userscripts.

## Related Libraries

- `@repo/common`
- `@repo/common-ui`
- `@repo/fetch`
- `@repo/musicbrainz-ext`
- `@repo/rxjs-ext`
32 changes: 32 additions & 0 deletions .github/skills/userscript-implementation/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: userscript-implementation
description: Guidance for implementing MusicBrainz userscripts with consistent structure, testing, and reuse across the monorepo.
license: MIT
---

# Userscript Implementation Rules

Apply this skill when implementing or modifying userscripts in this repository.

## Core Rules

- Use test driven development.
- Keep `index.ts` minimal. Put UI code in separate `.tsx` files.
- Use CSS modules for script-specific styling (`*.module.css`) instead of inline styles.
- Write modular code following the single responsibility principle.
- Reuse common components from repo libraries or third party packages when possible.
- When implementing new functionality, check if another project already includes similar logic. If so, extract the functionality to an appropriate common library.
- Mount UI using the toolbox module to keep a common appearance.
- Mimic the website UI when adding new UI elements.
- When running Playwright tests, use a non-HTML reporter so no browser report window opens (for example, `--reporter=line`).
- Ensure code passes linting by running `yarn lint` from the repo root.

## Suggested Workflow

1. Find similar behavior in existing scripts.
2. Write tests that capture the desired behavior.
3. Implement minimal `index.ts` orchestration.
4. Place UI components in dedicated `.tsx` files and use `*.module.css` for component styling.
5. Refactor shared logic into `lib/` packages when appropriate.
6. Run tests with a non-HTML reporter (for example, `yarn workspace @dvirtz/<script-name> test --reporter=line`).
7. Run `yarn lint` from the repo root and fix any issues.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: yarn release
- name: Reset beta to main
if: github.ref == 'refs/heads/main'
run: git push origin HEAD:refs/heads/beta --force
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ test-results/
playwright-report/
blob-report/
playwright/.cache/
.playwright-mcp/
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Agent Guidance

- Keep Markdown files compliant with `.markdownlint-cli2.jsonc`.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ Keeps one language of a double language tracklist (like often seen in Discogs).

See the script [README](scripts/single-language-tracklist/README.md) for more information.

### Scaffold festival days

[![install][badge-install]](https://github.com/dvirtz/musicbrainz-scripts/releases/latest/download/scaffold-festival-days.user.js) [![beta][badge-beta]](https://github.com/dvirtz/musicbrainz-scripts/releases/download/beta-latest/scaffold-festival-days.user.js)
[![source][badge-source]](scripts/scaffold-festival-days/src/index.ts)

Scaffolds day, venue, and single-day place sub-events for festival event hierarchies.

![toolbox](scripts/scaffold-festival-days/assets/toolbox.png)

See the script [README](scripts/scaffold-festival-days/README.md) for more information.

## Development

This is a TypeScript monorepo using Yarn workspaces and Turbo for build orchestration.
Expand Down
Loading
Loading