@open-mercato/cli 0.6.5-develop.4629.1.3ef70cd6a4 → 0.6.5-develop.4639.1.0416d895fa
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/dist/agentic/shared/AGENTS.md.template +33 -33
- package/dist/agentic/shared/ai/skills/{auto-continue-pr → om-auto-continue-pr}/SKILL.md +19 -19
- package/dist/agentic/shared/ai/skills/{auto-create-pr → om-auto-continue-pr}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-continue-pr-loop → om-auto-continue-pr-loop}/SKILL.md +32 -32
- package/dist/agentic/shared/ai/skills/{auto-create-pr → om-auto-create-pr}/SKILL.md +24 -24
- package/dist/agentic/shared/ai/skills/{auto-fix-github → om-auto-create-pr}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-create-pr-loop → om-auto-create-pr-loop}/SKILL.md +40 -40
- package/dist/agentic/shared/ai/skills/{auto-fix-github → om-auto-fix-github}/SKILL.md +3 -3
- package/dist/agentic/shared/ai/skills/{auto-continue-pr → om-auto-fix-github}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-review-pr → om-auto-review-pr}/SKILL.md +5 -5
- package/dist/agentic/shared/ai/skills/{auto-review-pr → om-auto-review-pr}/STANDALONE.md +1 -1
- package/dist/agentic/shared/ai/skills/{auto-upgrade-0.4.10-to-0.5.0 → om-auto-upgrade-0.4.10-to-0.5.0}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{backend-ui-design → om-backend-ui-design}/SKILL.md +2 -2
- package/dist/agentic/shared/ai/skills/{code-review → om-code-review}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{data-model-design → om-data-model-design}/SKILL.md +2 -2
- package/dist/agentic/shared/ai/skills/{eject-and-customize → om-eject-and-customize}/SKILL.md +2 -2
- package/dist/agentic/shared/ai/skills/{implement-spec → om-implement-spec}/SKILL.md +6 -6
- package/dist/agentic/shared/ai/skills/{integration-builder → om-integration-builder}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{integration-tests → om-integration-tests}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{module-scaffold → om-module-scaffold}/SKILL.md +2 -2
- package/dist/agentic/shared/ai/skills/{spec-writing → om-spec-writing}/SKILL.md +6 -6
- package/dist/agentic/shared/ai/skills/{spec-writing → om-spec-writing}/references/spec-checklist.md +2 -2
- package/dist/agentic/shared/ai/skills/{system-extension → om-system-extension}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{trim-unused-modules → om-trim-unused-modules}/SKILL.md +1 -1
- package/dist/agentic/shared/ai/skills/{troubleshooter → om-troubleshooter}/SKILL.md +1 -1
- package/dist/lib/__integration__/TC-INT-008.spec.js +1 -1
- package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
- package/dist/lib/agentic-setup.js +51 -51
- package/dist/lib/agentic-setup.js.map +2 -2
- package/package.json +5 -5
- package/src/lib/__integration__/TC-INT-008.spec.ts +1 -1
- package/src/lib/agentic-setup.ts +51 -51
- /package/dist/agentic/shared/ai/skills/{backend-ui-design → om-backend-ui-design}/references/ui-components.md +0 -0
- /package/dist/agentic/shared/ai/skills/{code-review → om-code-review}/references/review-checklist.md +0 -0
- /package/dist/agentic/shared/ai/skills/{data-model-design → om-data-model-design}/references/mikro-orm-cheatsheet.md +0 -0
- /package/dist/agentic/shared/ai/skills/{integration-builder → om-integration-builder}/references/adapter-contracts.md +0 -0
- /package/dist/agentic/shared/ai/skills/{module-scaffold → om-module-scaffold}/references/naming-conventions.md +0 -0
- /package/dist/agentic/shared/ai/skills/{module-scaffold → om-module-scaffold}/references/navigation-patterns.md +0 -0
- /package/dist/agentic/shared/ai/skills/{spec-writing → om-spec-writing}/references/spec-template.md +0 -0
- /package/dist/agentic/shared/ai/skills/{system-extension → om-system-extension}/references/extension-contracts.md +0 -0
- /package/dist/agentic/shared/ai/skills/{troubleshooter → om-troubleshooter}/references/diagnostic-commands.md +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: implement-spec
|
|
2
|
+
name: om-implement-spec
|
|
3
3
|
description: Implement a specification (or specific phases of a spec) using coordinated subagents. Handles multi-phase spec implementation with unit tests, integration tests, documentation, and code-review compliance. Use when the user says "implement spec", "implement the spec", "implement phases", "build from spec", or "code the spec". Tracks progress by updating the spec with implementation status.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ Implements a specification (or selected phases) end-to-end using a team of coord
|
|
|
11
11
|
|
|
12
12
|
1. **Identify the spec**: Locate the target spec file in `.ai/specs/`.
|
|
13
13
|
2. **Load context**: Read spec fully. Match affected tasks to the **Task → Context Map** in `AGENTS.md` and read all listed files (guides and skills).
|
|
14
|
-
3. **Load code-review checklist**: Read `.ai/skills/code-review/references/review-checklist.md` — this is the acceptance gate for every phase.
|
|
14
|
+
3. **Load code-review checklist**: Read `.ai/skills/om-code-review/references/review-checklist.md` — this is the acceptance gate for every phase.
|
|
15
15
|
4. **Load lessons**: Read `.ai/lessons.md` for known pitfalls.
|
|
16
16
|
5. **Scope phases**: If the user specifies phases (e.g. "phases c-e"), filter to only those. Otherwise implement all phases sequentially.
|
|
17
17
|
|
|
@@ -44,9 +44,9 @@ For every piece of code, enforce these code-review rules inline:
|
|
|
44
44
|
| **CRUD APIs** | **Use `makeCrudRoute({ entity, entityId, operations, schema, indexer: { entityType } })` from `@open-mercato/shared/lib/crud/factory`. Custom write routes MUST call `validateCrudMutationGuard` before the mutation and `runCrudMutationGuardAfterSuccess` after success. See `AGENTS.md` → Mandatory Module Mechanisms.** |
|
|
45
45
|
| Entities | Standard columns, snake_case, UUID PKs, indexed `organization_id` + `tenant_id` |
|
|
46
46
|
| Security | `findWithDecryption`, tenant scoping, zod validation |
|
|
47
|
-
| **Encryption maps** | **For every PII / GDPR-relevant column the phase touches, declare in `<module>/encryption.ts` exporting `defaultEncryptionMaps` (type from `@open-mercato/shared/modules/encryption`). Reads via `findWithDecryption` / `findOneWithDecryption` (5-arg `(em, entity, where, options?, scope?)`). Equality-lookup columns declare a sibling `hashField`. NEVER hand-rolled AES/KMS, `crypto.subtle`, or "encrypt later" stubs. See `AGENTS.md` → CRITICAL Rule #11 (Encryption maps) + the "Encryption maps" row of the Mandatory Module Mechanisms table; `.ai/skills/data-model-design/SKILL.md` § Sensitive Data and Encryption Maps; `.ai/skills/module-scaffold/SKILL.md` § Encryption maps.** |
|
|
47
|
+
| **Encryption maps** | **For every PII / GDPR-relevant column the phase touches, declare in `<module>/encryption.ts` exporting `defaultEncryptionMaps` (type from `@open-mercato/shared/modules/encryption`). Reads via `findWithDecryption` / `findOneWithDecryption` (5-arg `(em, entity, where, options?, scope?)`). Equality-lookup columns declare a sibling `hashField`. NEVER hand-rolled AES/KMS, `crypto.subtle`, or "encrypt later" stubs. See `AGENTS.md` → CRITICAL Rule #11 (Encryption maps) + the "Encryption maps" row of the Mandatory Module Mechanisms table; `.ai/skills/om-data-model-design/SKILL.md` § Sensitive Data and Encryption Maps; `.ai/skills/om-module-scaffold/SKILL.md` § Encryption maps.** |
|
|
48
48
|
| UI | `<CrudForm>`/`<DataTable>` (with stable `entityId` + `extensionTableId`), `apiCall` (never raw `fetch`), `flash()`, `<LoadingMessage>`/`<ErrorMessage>` |
|
|
49
|
-
| **Design System** | **Semantic status tokens (no `text-red-*` / `bg-green-*`); Tailwind text scale (no `text-[13px]` / `text-[11px]`); shared primitives `StatusBadge` / `Alert` / `FormField` / `SectionHeader` / `CollapsibleSection` / `LoadingMessage` / `Spinner` / `DataLoader` / `EmptyState`; lucide-react icons in PAGE BODY (never inline `<svg>`); `aria-label` on every icon-only button; Boy Scout rule on touched lines. See `AGENTS.md` → CRITICAL Rule #10 (Strict Design System alignment) + `.ai/skills/backend-ui-design/SKILL.md`.** |
|
|
49
|
+
| **Design System** | **Semantic status tokens (no `text-red-*` / `bg-green-*`); Tailwind text scale (no `text-[13px]` / `text-[11px]`); shared primitives `StatusBadge` / `Alert` / `FormField` / `SectionHeader` / `CollapsibleSection` / `LoadingMessage` / `Spinner` / `DataLoader` / `EmptyState`; lucide-react icons in PAGE BODY (never inline `<svg>`); `aria-label` on every icon-only button; Boy Scout rule on touched lines. See `AGENTS.md` → CRITICAL Rule #10 (Strict Design System alignment) + `.ai/skills/om-backend-ui-design/SKILL.md`.** |
|
|
50
50
|
| **Cache** | **Resolve via DI (`container.resolve('cache')`); tag with `tenant:<id>` / `org:<id>`; declare invalidation per write path. NEVER `new Redis(...)` or raw SQLite.** |
|
|
51
51
|
| Events | `createModuleEvents()` with `as const`, subscribers export `metadata`; cross-module side effects via subscribers, never direct imports |
|
|
52
52
|
| i18n | `useT()` client, `resolveTranslations()` server, no hardcoded strings |
|
|
@@ -67,7 +67,7 @@ For every new feature/function implemented in the phase:
|
|
|
67
67
|
### Step 4 — Integration Tests
|
|
68
68
|
|
|
69
69
|
If the spec defines integration test scenarios (or the phase adds API endpoints / UI flows):
|
|
70
|
-
- Follow the `integration-tests` skill workflow (`.ai/skills/integration-tests/SKILL.md`)
|
|
70
|
+
- Follow the `om-integration-tests` skill workflow (`.ai/skills/om-integration-tests/SKILL.md`)
|
|
71
71
|
- Place tests in `src/modules/<module>/__integration__/TC-{CATEGORY}-{XXX}.spec.ts`
|
|
72
72
|
- Tests MUST be self-contained: create fixtures in setup, clean up in teardown
|
|
73
73
|
- Tests MUST NOT rely on seeded/demo data
|
|
@@ -85,7 +85,7 @@ For each new feature:
|
|
|
85
85
|
|
|
86
86
|
### Step 6 — Self-Review (Code-Review Gate)
|
|
87
87
|
|
|
88
|
-
Before marking a phase complete, run a self-review against the checklist (`.ai/skills/code-review/references/review-checklist.md`):
|
|
88
|
+
Before marking a phase complete, run a self-review against the checklist (`.ai/skills/om-code-review/references/review-checklist.md`):
|
|
89
89
|
|
|
90
90
|
1. **Architecture & Module Independence** (section 1)
|
|
91
91
|
2. **Security** (section 2)
|
package/dist/agentic/shared/ai/skills/{integration-builder → om-integration-builder}/SKILL.md
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: integration-builder
|
|
2
|
+
name: om-integration-builder
|
|
3
3
|
description: Build integration provider packages for the Open Mercato Integration Marketplace. Use when creating new external integrations (payment gateways, shipping carriers, data sync connectors, communication channels, storage providers, webhook endpoints). Handles npm package scaffolding, adapter implementation, credentials, widget injection, webhook processing, health checks, i18n, and tests. Triggers on "build integration", "create integration", "add provider", "new connector", "integrate with", "add stripe/paypal/dhl/sendgrid" etc.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: integration-tests
|
|
2
|
+
name: om-integration-tests
|
|
3
3
|
description: Run and create QA integration tests (Playwright TypeScript), including executing the full suite, converting optional markdown scenarios, and generating new tests from specs or feature descriptions. Use when the user says "run integration tests", "test this feature", "create test for", "convert test case", "run QA tests", or "integration test".
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: module-scaffold
|
|
2
|
+
name: om-module-scaffold
|
|
3
3
|
description: Scaffold a new module from scratch with all required files and conventions. Use when creating a new module, adding a new entity with CRUD, or bootstrapping module features (API routes, backend pages, DI, ACL, events, search). Triggers on "create module", "new module", "scaffold module", "add module", "bootstrap module", "generate module".
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -232,7 +232,7 @@ export const openApi = {
|
|
|
232
232
|
|
|
233
233
|
## 6. Create Backend Pages
|
|
234
234
|
|
|
235
|
-
Use `CrudForm` and `DataTable` from `@open-mercato/ui`. See the `backend-ui-design` skill for full component reference.
|
|
235
|
+
Use `CrudForm` and `DataTable` from `@open-mercato/ui`. See the `om-backend-ui-design` skill for full component reference.
|
|
236
236
|
|
|
237
237
|
> **Optimistic locking (default ON).** `CrudForm` in edit mode auto-derives the expected-version header from `initialValues.updatedAt` and applies it to **both** save and delete — so pass the loaded record's `updatedAt` into `initialValues`. For custom (non-`CrudForm`) list-row deletes or dialog mutations, wrap the call with `withScopedApiRequestHeaders(buildOptimisticLockHeader(record.updatedAt), () => deleteCrud(...))` and surface the 409 with `surfaceRecordConflict(err, t)` from `@open-mercato/ui/backend/conflicts`. Never leave a mutating edit/delete UI without a version header — concurrent edits would silently overwrite.
|
|
238
238
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: spec-writing
|
|
2
|
+
name: om-spec-writing
|
|
3
3
|
description: Guide for creating high-quality specifications for {{PROJECT_NAME}}. Use when starting a new SPEC or reviewing specs against architectural standards.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -61,8 +61,8 @@ Use the [Specification Template](references/spec-template.md). Adapt if needed,
|
|
|
61
61
|
4. **Undo Contract**: Is the "Undo" logic as detailed as the "Execute"?
|
|
62
62
|
5. **Module Isolation**: Using Event Bus for side effects or cheating with direct imports?
|
|
63
63
|
6. **Canonical Mechanisms**: Does the spec reach for the framework primitives (`makeCrudRoute`, `<CrudForm>`, `<DataTable>`, `apiCall` / `useGuardedMutation`, DI-resolved cache, `createModuleEvents`) or invent its own substitute? See `AGENTS.md` → **Mandatory Module Mechanisms** for the full canon and links. No raw `fetch`, no raw `<form>`, no `new Redis(...)`, no manual cross-module ORM joins.
|
|
64
|
-
7. **Sensitive Data**: For every PII / GDPR / address / contact / free-text-about-people / integration-credential column the spec proposes, does it declare an `encryption.ts` `defaultEncryptionMaps` entry and route reads through `findWithDecryption`? See `AGENTS.md` → CRITICAL Rule #11 (Encryption maps) + the "Encryption maps for sensitive data" row of the Mandatory Module Mechanisms table and `.ai/skills/data-model-design/SKILL.md` § Sensitive Data and Encryption Maps. No hand-rolled AES, no `crypto.subtle`, no "TODO encrypt later".
|
|
65
|
-
8. **Design System**: Does every UI mock / className snippet in the spec match the DS canon — semantic status tokens (no `text-red-*` / `bg-green-*`), Tailwind text scale (no `text-[11px]` / `text-[13px]`), shared primitives (`StatusBadge`, `Alert`, `FormField`, `SectionHeader`, `CollapsibleSection`, `LoadingMessage` / `Spinner` / `DataLoader`, `EmptyState`), lucide-react icons in page body (never inline `<svg>`), dialog `Cmd/Ctrl+Enter` submit + `Escape` cancel, `aria-label` on every icon-only button? See `AGENTS.md` → CRITICAL Rule #10 (Strict Design System alignment for every UI change) and `.ai/skills/backend-ui-design/SKILL.md`. Specs that touch existing pages MUST honour the Boy Scout rule.
|
|
64
|
+
7. **Sensitive Data**: For every PII / GDPR / address / contact / free-text-about-people / integration-credential column the spec proposes, does it declare an `encryption.ts` `defaultEncryptionMaps` entry and route reads through `findWithDecryption`? See `AGENTS.md` → CRITICAL Rule #11 (Encryption maps) + the "Encryption maps for sensitive data" row of the Mandatory Module Mechanisms table and `.ai/skills/om-data-model-design/SKILL.md` § Sensitive Data and Encryption Maps. No hand-rolled AES, no `crypto.subtle`, no "TODO encrypt later".
|
|
65
|
+
8. **Design System**: Does every UI mock / className snippet in the spec match the DS canon — semantic status tokens (no `text-red-*` / `bg-green-*`), Tailwind text scale (no `text-[11px]` / `text-[13px]`), shared primitives (`StatusBadge`, `Alert`, `FormField`, `SectionHeader`, `CollapsibleSection`, `LoadingMessage` / `Spinner` / `DataLoader`, `EmptyState`), lucide-react icons in page body (never inline `<svg>`), dialog `Cmd/Ctrl+Enter` submit + `Escape` cancel, `aria-label` on every icon-only button? See `AGENTS.md` → CRITICAL Rule #10 (Strict Design System alignment for every UI change) and `.ai/skills/om-backend-ui-design/SKILL.md`. Specs that touch existing pages MUST honour the Boy Scout rule.
|
|
66
66
|
|
|
67
67
|
## Quick Rule Reference
|
|
68
68
|
|
|
@@ -80,6 +80,6 @@ Use the [Specification Template](references/spec-template.md). Adapt if needed,
|
|
|
80
80
|
- [Spec Template](references/spec-template.md)
|
|
81
81
|
- [Spec Checklist](references/spec-checklist.md) — § 3 covers encryption maps; § 5 covers canonical mechanisms + DS
|
|
82
82
|
- [AGENTS.md](../../../AGENTS.md) — Mandatory Module Mechanisms table; CRITICAL Rule #10 (Design System); CRITICAL Rule #11 (Encryption maps)
|
|
83
|
-
- [`.ai/skills/data-model-design/SKILL.md`](../data-model-design/SKILL.md) → Sensitive Data and Encryption Maps
|
|
84
|
-
- [`.ai/skills/module-scaffold/SKILL.md`](../module-scaffold/SKILL.md) → Encryption maps
|
|
85
|
-
- [`.ai/skills/backend-ui-design/SKILL.md`](../backend-ui-design/SKILL.md) — DS-compliant pages
|
|
83
|
+
- [`.ai/skills/om-data-model-design/SKILL.md`](../om-data-model-design/SKILL.md) → Sensitive Data and Encryption Maps
|
|
84
|
+
- [`.ai/skills/om-module-scaffold/SKILL.md`](../om-module-scaffold/SKILL.md) → Encryption maps
|
|
85
|
+
- [`.ai/skills/om-backend-ui-design/SKILL.md`](../om-backend-ui-design/SKILL.md) — DS-compliant pages
|
package/dist/agentic/shared/ai/skills/{spec-writing → om-spec-writing}/references/spec-checklist.md
RENAMED
|
@@ -25,7 +25,7 @@ Every item must be answered in the spec or marked N/A with justification.
|
|
|
25
25
|
- [ ] All user input validated before business logic/persistence
|
|
26
26
|
- [ ] Auth guards declared per-method in `metadata` (`requireAuth`, `requireFeatures`) — never legacy top-level `export const requireAuth`
|
|
27
27
|
- [ ] Tenant isolation: every scoped query filters by `organization_id` (and `tenant_id` where applicable)
|
|
28
|
-
- [ ] **Encryption maps mechanism is used (no hand-rolled crypto).** For every PII / GDPR-relevant column the spec proposes — names, addresses, contacts, free-text notes about people, integration credentials, secrets, document numbers — the spec MUST declare them in a module-level `<module>/encryption.ts` exporting `defaultEncryptionMaps: ModuleEncryptionMap[]` (type from `@open-mercato/shared/modules/encryption`). Reads MUST go through `findWithDecryption` / `findOneWithDecryption` (5-arg `(em, entity, where, options?, scope?)`) from `@open-mercato/shared/lib/encryption/find`. Equality-lookup columns (e.g. login email) declare a sibling `hashField`. No `crypto.subtle`, no custom KMS calls, no "TODO encrypt later". See `AGENTS.md` → CRITICAL Rule #11 (Encryption maps) + the "Encryption maps for sensitive data" row of the Mandatory Module Mechanisms table; `.ai/skills/data-model-design/SKILL.md` § Sensitive Data and Encryption Maps.
|
|
28
|
+
- [ ] **Encryption maps mechanism is used (no hand-rolled crypto).** For every PII / GDPR-relevant column the spec proposes — names, addresses, contacts, free-text notes about people, integration credentials, secrets, document numbers — the spec MUST declare them in a module-level `<module>/encryption.ts` exporting `defaultEncryptionMaps: ModuleEncryptionMap[]` (type from `@open-mercato/shared/modules/encryption`). Reads MUST go through `findWithDecryption` / `findOneWithDecryption` (5-arg `(em, entity, where, options?, scope?)`) from `@open-mercato/shared/lib/encryption/find`. Equality-lookup columns (e.g. login email) declare a sibling `hashField`. No `crypto.subtle`, no custom KMS calls, no "TODO encrypt later". See `AGENTS.md` → CRITICAL Rule #11 (Encryption maps) + the "Encryption maps for sensitive data" row of the Mandatory Module Mechanisms table; `.ai/skills/om-data-model-design/SKILL.md` § Sensitive Data and Encryption Maps.
|
|
29
29
|
|
|
30
30
|
## 4. Commands, Events & Naming
|
|
31
31
|
|
|
@@ -46,7 +46,7 @@ Every item must be answered in the spec or marked N/A with justification.
|
|
|
46
46
|
- [ ] **HTTP clients** use `apiCall` / `apiCallOrThrow` / `readApiResultOrThrow` from `@open-mercato/ui/backend/utils/apiCall` — never raw `fetch`.
|
|
47
47
|
- [ ] **Non-`CrudForm` writes** are wrapped in `useGuardedMutation(...).runMutation(...)` and pass `retryLastMutation` in the injection context.
|
|
48
48
|
- [ ] **Cache** is resolved via DI (`container.resolve('cache')`) — never `new Redis(...)` or raw SQLite. Tags include `tenant:<id>` / `org:<id>`.
|
|
49
|
-
- [ ] **Design System compliance for every UI mock and className snippet in the spec.** See `AGENTS.md` → CRITICAL Rule #10 (Strict Design System alignment) and `.ai/skills/backend-ui-design/SKILL.md`.
|
|
49
|
+
- [ ] **Design System compliance for every UI mock and className snippet in the spec.** See `AGENTS.md` → CRITICAL Rule #10 (Strict Design System alignment) and `.ai/skills/om-backend-ui-design/SKILL.md`.
|
|
50
50
|
- [ ] Use semantic status tokens (`text-status-error-text`, `bg-status-success-bg`, `border-status-warning-border`, `text-status-info-icon`, `text-destructive`, `bg-destructive`) — NEVER hardcoded shades like `text-red-500`, `bg-green-100`, `text-amber-*`, `text-emerald-*`, `bg-blue-*`. Status tokens already cover dark mode; no `dark:` overrides.
|
|
51
51
|
- [ ] Use the Tailwind text scale (`text-xs` 12, `text-sm` 14, `text-base` 16, `text-lg` 18, `text-xl` 20, `text-2xl` 24) or `text-overline` for 11px uppercase labels — NEVER arbitrary sizes (`text-[11px]`, `text-[13px]`, `text-[15px]`, `p-[13px]`, `rounded-[24px]`, `z-[9999]`).
|
|
52
52
|
- [ ] Use shared primitives instead of raw HTML: `<Alert variant=...>` for inline status, `flash('msg', 'success|error|warning|info')` for toasts, `useConfirmDialog()` for destructive confirmations, `<StatusBadge>` for entity status, `<FormField label error>` to wrap form inputs, `<SectionHeader title count action>` for section headers, `<CollapsibleSection>` for collapsible regions, `<LoadingMessage>` / `<Spinner>` / `<DataLoader>` for async states, `<EmptyState>` (or DataTable `emptyState` prop) for empty lists.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: system-extension
|
|
2
|
+
name: om-system-extension
|
|
3
3
|
description: Extend core modules using the Universal Module Extension System (UMES). Use when adding columns/fields/filters to existing tables/forms, enriching API responses, intercepting API routes, blocking/validating mutations, replacing UI components, injecting menu items, or reacting to domain events. Triggers on "extend", "add column to", "add field to", "inject into", "intercept", "enrich", "hook into", "customize", "override component", "add menu item", "react to event", "block mutation", "validate before save".
|
|
4
4
|
---
|
|
5
5
|
|
package/dist/agentic/shared/ai/skills/{trim-unused-modules → om-trim-unused-modules}/SKILL.md
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: trim-unused-modules
|
|
2
|
+
name: om-trim-unused-modules
|
|
3
3
|
description: Propose disabling modules in src/modules.ts that the current standalone project does not actually use. Intended to be offered after the user adds a new custom module, because a fresh create-mercato-app scaffold enables every built-in module (classic mode) and that is rarely what the project actually needs in production.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: troubleshooter
|
|
2
|
+
name: om-troubleshooter
|
|
3
3
|
description: Diagnose and fix common issues in Open Mercato standalone apps. Use when encountering errors, unexpected behavior, modules not loading, widgets not appearing, migrations failing, build errors, or any "it doesn't work" situation. Triggers on "error", "not working", "broken", "fix", "debug", "why isn't", "can't", "fails", "crash", "missing", "404", "500", "module not found", "widget not showing".
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -192,7 +192,7 @@ test.describe("TC-INT-008: CLI agentic init mirrors standalone scaffolding asset
|
|
|
192
192
|
const cursorRulesSource = fs.readFileSync(path.join(appDir, ".cursor", "rules", "open-mercato.mdc"), "utf8");
|
|
193
193
|
expect(cursorRulesSource).toContain("sample-store");
|
|
194
194
|
const specWritingSkillSource = fs.readFileSync(
|
|
195
|
-
path.join(appDir, ".ai", "skills", "spec-writing", "SKILL.md"),
|
|
195
|
+
path.join(appDir, ".ai", "skills", "om-spec-writing", "SKILL.md"),
|
|
196
196
|
"utf8"
|
|
197
197
|
);
|
|
198
198
|
expect(specWritingSkillSource).toContain("sample-store");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/__integration__/TC-INT-008.spec.ts"],
|
|
4
|
-
"sourcesContent": ["import { expect, test } from '@playwright/test'\nimport { execFileSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst repoRoot = path.resolve(__dirname, '..', '..', '..', '..', '..')\nconst cliDir = path.join(repoRoot, 'packages', 'cli')\nconst cliBin = path.join(cliDir, 'dist', 'bin.js')\nconst cliBuildScript = path.join(cliDir, 'build.mjs')\nconst cliIntegrationRunnerPath = path.join(cliDir, 'src', 'lib', 'testing', 'integration.ts')\nconst standaloneTemplatePackageJsonPath = path.join(repoRoot, 'packages', 'create-app', 'template', 'package.json.template')\nconst agenticRoot = path.join(repoRoot, 'packages', 'create-app', 'agentic')\nconst packagesRoot = path.join(repoRoot, 'packages')\n\nfunction normalizePath(value: string): string {\n return value.split(path.sep).join('/')\n}\n\nfunction runCommand(command: string, args: string[], cwd: string): string {\n return execFileSync(command, args, {\n cwd,\n encoding: 'utf8',\n env: {\n ...process.env,\n FORCE_COLOR: '0',\n NODE_NO_WARNINGS: '1',\n },\n })\n}\n\nfunction runMercato(args: string[], cwd: string): string {\n return runCommand(process.execPath, [cliBin, ...args], cwd)\n}\n\nfunction writeFile(filePath: string, content: string): void {\n fs.mkdirSync(path.dirname(filePath), { recursive: true })\n fs.writeFileSync(filePath, content)\n}\n\nfunction ensureCliBuilt(): void {\n runCommand(process.execPath, [cliBuildScript], cliDir)\n}\n\nfunction createStandaloneFixture(rootDir: string): string {\n const appDir = path.join(rootDir, 'sample-store')\n writeFile(\n path.join(appDir, 'package.json'),\n JSON.stringify(\n {\n name: 'sample-store',\n private: true,\n },\n null,\n 2,\n ),\n )\n writeFile(path.join(appDir, 'src', 'modules.ts'), 'export const enabledModules = []\\n')\n return appDir\n}\n\nfunction listRelativeFiles(rootDir: string): string[] {\n if (!fs.existsSync(rootDir)) {\n return []\n }\n\n const collected: string[] = []\n for (const entry of fs.readdirSync(rootDir, { withFileTypes: true })) {\n const absolutePath = path.join(rootDir, entry.name)\n if (entry.isDirectory()) {\n for (const nestedPath of listRelativeFiles(absolutePath)) {\n collected.push(path.join(entry.name, nestedPath))\n }\n continue\n }\n if (entry.isFile()) {\n collected.push(entry.name)\n }\n }\n\n return collected.map(normalizePath).sort()\n}\n\nfunction mapSharedSourceToOutput(relativePath: string): string {\n if (relativePath === 'AGENTS.md.template') {\n return 'AGENTS.md'\n }\n\n if (!relativePath.startsWith('ai/')) {\n throw new Error(`Unexpected shared source path: ${relativePath}`)\n }\n\n return normalizePath(path.join('.ai', relativePath.slice('ai/'.length)))\n}\n\nfunction mapClaudeSourceToOutput(relativePath: string): string {\n if (relativePath === 'CLAUDE.md.template') {\n return 'CLAUDE.md'\n }\n if (relativePath === 'settings.json') {\n return '.claude/settings.json'\n }\n if (relativePath === 'mcp.json.example') {\n return '.mcp.json.example'\n }\n if (relativePath.startsWith('hooks/')) {\n return normalizePath(path.join('.claude', relativePath))\n }\n\n throw new Error(`Unexpected Claude source path: ${relativePath}`)\n}\n\nfunction mapCursorSourceToOutput(relativePath: string): string {\n if (relativePath === 'hooks.json') {\n return '.cursor/hooks.json'\n }\n if (relativePath === 'mcp.json.example') {\n return '.cursor/mcp.json.example'\n }\n if (relativePath.startsWith('hooks/') || relativePath.startsWith('rules/')) {\n return normalizePath(path.join('.cursor', relativePath))\n }\n\n throw new Error(`Unexpected Cursor source path: ${relativePath}`)\n}\n\nfunction mapCodexSourceToOutput(relativePath: string): string | null {\n if (relativePath === 'mcp.json.example') {\n return '.codex/mcp.json.example'\n }\n if (relativePath === 'enforcement-rules.md') {\n return null\n }\n\n throw new Error(`Unexpected Codex source path: ${relativePath}`)\n}\n\nfunction readPlaywrightConfigPathFromTemplate(): string {\n const packageTemplate = JSON.parse(fs.readFileSync(standaloneTemplatePackageJsonPath, 'utf8')) as {\n scripts?: Record<string, string>\n }\n const integrationScript = packageTemplate.scripts?.['test:integration']\n if (!integrationScript) {\n throw new Error('Standalone template is missing the test:integration script')\n }\n\n const configPathMatch = integrationScript.match(/--config\\s+([^\\s]+)/)\n if (!configPathMatch?.[1]) {\n throw new Error('Standalone template test:integration script is missing --config')\n }\n\n return normalizePath(configPathMatch[1])\n}\n\nfunction readPlaywrightConfigPathFromCliRunner(): string {\n const integrationRunnerSource = fs.readFileSync(cliIntegrationRunnerPath, 'utf8')\n const configPathMatch = integrationRunnerSource.match(/const PLAYWRIGHT_INTEGRATION_CONFIG_PATH = '([^']+)'/)\n if (!configPathMatch?.[1]) {\n throw new Error('CLI integration runner is missing PLAYWRIGHT_INTEGRATION_CONFIG_PATH')\n }\n\n return normalizePath(configPathMatch[1])\n}\n\nfunction expectedGuideOutputNames(): string[] {\n const collected = new Set<string>()\n\n for (const packageName of fs.readdirSync(packagesRoot)) {\n const packageGuide = path.join(packagesRoot, packageName, 'agentic', 'standalone-guide.md')\n if (fs.existsSync(packageGuide)) {\n collected.add(`${packageName}.md`)\n }\n\n const modulesRoot = path.join(packagesRoot, packageName, 'src', 'modules')\n if (!fs.existsSync(modulesRoot)) {\n continue\n }\n\n for (const moduleName of fs.readdirSync(modulesRoot)) {\n const moduleGuide = path.join(modulesRoot, moduleName, 'agentic', 'standalone-guide.md')\n if (fs.existsSync(moduleGuide)) {\n collected.add(`${packageName}.${moduleName}.md`)\n }\n }\n }\n\n return Array.from(collected).sort()\n}\n\nfunction assertPathsExist(appDir: string, relativePaths: string[]): void {\n const missingPaths = relativePaths.filter((relativePath) => !fs.existsSync(path.join(appDir, relativePath)))\n expect(missingPaths).toEqual([])\n}\n\ntest.describe('TC-INT-008: CLI agentic init mirrors standalone scaffolding assets', () => {\n test.beforeAll(() => {\n ensureCliBuilt()\n })\n\n test('should run bootstrap-free and generate the shared, guide, and tool-specific agentic files', () => {\n const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mercato-cli-agentic-'))\n\n try {\n const appDir = createStandaloneFixture(tempRoot)\n const standalonePlaywrightConfigPath = readPlaywrightConfigPathFromTemplate()\n const cliPlaywrightConfigPath = readPlaywrightConfigPathFromCliRunner()\n const commandOutput = runMercato(['agentic:init', '--tool=claude-code,codex,cursor'], appDir)\n\n expect(cliPlaywrightConfigPath).toBe(standalonePlaywrightConfigPath)\n expect(commandOutput).toContain('Agentic setup complete:')\n expect(fs.existsSync(path.join(appDir, '.mercato', 'generated'))).toBe(false)\n\n const sharedOutputs = listRelativeFiles(path.join(agenticRoot, 'shared')).map(mapSharedSourceToOutput)\n const claudeOutputs = listRelativeFiles(path.join(agenticRoot, 'claude-code')).map(mapClaudeSourceToOutput)\n const cursorOutputs = listRelativeFiles(path.join(agenticRoot, 'cursor')).map(mapCursorSourceToOutput)\n const codexOutputs = listRelativeFiles(path.join(agenticRoot, 'codex'))\n .map(mapCodexSourceToOutput)\n .filter((relativePath): relativePath is string => relativePath !== null)\n\n expect(sharedOutputs).toContain(standalonePlaywrightConfigPath)\n assertPathsExist(appDir, [...sharedOutputs, ...claudeOutputs, ...cursorOutputs, ...codexOutputs])\n expect(fs.existsSync(path.join(appDir, standalonePlaywrightConfigPath))).toBe(true)\n\n const generatedGuideNames = listRelativeFiles(path.join(appDir, '.ai', 'guides'))\n expect(generatedGuideNames).toEqual(expectedGuideOutputNames())\n\n const agentsSource = fs.readFileSync(path.join(appDir, 'AGENTS.md'), 'utf8')\n expect(agentsSource).toContain('<!-- CODEX_ENFORCEMENT_RULES_START -->')\n expect(agentsSource).toContain('.ai/guides/core.md')\n\n const specsReadmeSource = fs.readFileSync(path.join(appDir, '.ai', 'specs', 'README.md'), 'utf8')\n expect(specsReadmeSource).toContain('sample-store')\n\n const cursorRulesSource = fs.readFileSync(path.join(appDir, '.cursor', 'rules', 'open-mercato.mdc'), 'utf8')\n expect(cursorRulesSource).toContain('sample-store')\n\n const specWritingSkillSource = fs.readFileSync(\n path.join(appDir, '.ai', 'skills', 'spec-writing', 'SKILL.md'),\n 'utf8',\n )\n expect(specWritingSkillSource).toContain('sample-store')\n\n for (const toolDir of ['.claude', '.codex', '.cursor']) {\n const skillsLinkPath = path.join(appDir, toolDir, 'skills')\n expect(fs.lstatSync(skillsLinkPath).isSymbolicLink()).toBe(true)\n expect(normalizePath(fs.readlinkSync(skillsLinkPath))).toBe('../.ai/skills')\n }\n } finally {\n fs.rmSync(tempRoot, { recursive: true, force: true })\n }\n })\n})\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { expect, test } from '@playwright/test'\nimport { execFileSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst repoRoot = path.resolve(__dirname, '..', '..', '..', '..', '..')\nconst cliDir = path.join(repoRoot, 'packages', 'cli')\nconst cliBin = path.join(cliDir, 'dist', 'bin.js')\nconst cliBuildScript = path.join(cliDir, 'build.mjs')\nconst cliIntegrationRunnerPath = path.join(cliDir, 'src', 'lib', 'testing', 'integration.ts')\nconst standaloneTemplatePackageJsonPath = path.join(repoRoot, 'packages', 'create-app', 'template', 'package.json.template')\nconst agenticRoot = path.join(repoRoot, 'packages', 'create-app', 'agentic')\nconst packagesRoot = path.join(repoRoot, 'packages')\n\nfunction normalizePath(value: string): string {\n return value.split(path.sep).join('/')\n}\n\nfunction runCommand(command: string, args: string[], cwd: string): string {\n return execFileSync(command, args, {\n cwd,\n encoding: 'utf8',\n env: {\n ...process.env,\n FORCE_COLOR: '0',\n NODE_NO_WARNINGS: '1',\n },\n })\n}\n\nfunction runMercato(args: string[], cwd: string): string {\n return runCommand(process.execPath, [cliBin, ...args], cwd)\n}\n\nfunction writeFile(filePath: string, content: string): void {\n fs.mkdirSync(path.dirname(filePath), { recursive: true })\n fs.writeFileSync(filePath, content)\n}\n\nfunction ensureCliBuilt(): void {\n runCommand(process.execPath, [cliBuildScript], cliDir)\n}\n\nfunction createStandaloneFixture(rootDir: string): string {\n const appDir = path.join(rootDir, 'sample-store')\n writeFile(\n path.join(appDir, 'package.json'),\n JSON.stringify(\n {\n name: 'sample-store',\n private: true,\n },\n null,\n 2,\n ),\n )\n writeFile(path.join(appDir, 'src', 'modules.ts'), 'export const enabledModules = []\\n')\n return appDir\n}\n\nfunction listRelativeFiles(rootDir: string): string[] {\n if (!fs.existsSync(rootDir)) {\n return []\n }\n\n const collected: string[] = []\n for (const entry of fs.readdirSync(rootDir, { withFileTypes: true })) {\n const absolutePath = path.join(rootDir, entry.name)\n if (entry.isDirectory()) {\n for (const nestedPath of listRelativeFiles(absolutePath)) {\n collected.push(path.join(entry.name, nestedPath))\n }\n continue\n }\n if (entry.isFile()) {\n collected.push(entry.name)\n }\n }\n\n return collected.map(normalizePath).sort()\n}\n\nfunction mapSharedSourceToOutput(relativePath: string): string {\n if (relativePath === 'AGENTS.md.template') {\n return 'AGENTS.md'\n }\n\n if (!relativePath.startsWith('ai/')) {\n throw new Error(`Unexpected shared source path: ${relativePath}`)\n }\n\n return normalizePath(path.join('.ai', relativePath.slice('ai/'.length)))\n}\n\nfunction mapClaudeSourceToOutput(relativePath: string): string {\n if (relativePath === 'CLAUDE.md.template') {\n return 'CLAUDE.md'\n }\n if (relativePath === 'settings.json') {\n return '.claude/settings.json'\n }\n if (relativePath === 'mcp.json.example') {\n return '.mcp.json.example'\n }\n if (relativePath.startsWith('hooks/')) {\n return normalizePath(path.join('.claude', relativePath))\n }\n\n throw new Error(`Unexpected Claude source path: ${relativePath}`)\n}\n\nfunction mapCursorSourceToOutput(relativePath: string): string {\n if (relativePath === 'hooks.json') {\n return '.cursor/hooks.json'\n }\n if (relativePath === 'mcp.json.example') {\n return '.cursor/mcp.json.example'\n }\n if (relativePath.startsWith('hooks/') || relativePath.startsWith('rules/')) {\n return normalizePath(path.join('.cursor', relativePath))\n }\n\n throw new Error(`Unexpected Cursor source path: ${relativePath}`)\n}\n\nfunction mapCodexSourceToOutput(relativePath: string): string | null {\n if (relativePath === 'mcp.json.example') {\n return '.codex/mcp.json.example'\n }\n if (relativePath === 'enforcement-rules.md') {\n return null\n }\n\n throw new Error(`Unexpected Codex source path: ${relativePath}`)\n}\n\nfunction readPlaywrightConfigPathFromTemplate(): string {\n const packageTemplate = JSON.parse(fs.readFileSync(standaloneTemplatePackageJsonPath, 'utf8')) as {\n scripts?: Record<string, string>\n }\n const integrationScript = packageTemplate.scripts?.['test:integration']\n if (!integrationScript) {\n throw new Error('Standalone template is missing the test:integration script')\n }\n\n const configPathMatch = integrationScript.match(/--config\\s+([^\\s]+)/)\n if (!configPathMatch?.[1]) {\n throw new Error('Standalone template test:integration script is missing --config')\n }\n\n return normalizePath(configPathMatch[1])\n}\n\nfunction readPlaywrightConfigPathFromCliRunner(): string {\n const integrationRunnerSource = fs.readFileSync(cliIntegrationRunnerPath, 'utf8')\n const configPathMatch = integrationRunnerSource.match(/const PLAYWRIGHT_INTEGRATION_CONFIG_PATH = '([^']+)'/)\n if (!configPathMatch?.[1]) {\n throw new Error('CLI integration runner is missing PLAYWRIGHT_INTEGRATION_CONFIG_PATH')\n }\n\n return normalizePath(configPathMatch[1])\n}\n\nfunction expectedGuideOutputNames(): string[] {\n const collected = new Set<string>()\n\n for (const packageName of fs.readdirSync(packagesRoot)) {\n const packageGuide = path.join(packagesRoot, packageName, 'agentic', 'standalone-guide.md')\n if (fs.existsSync(packageGuide)) {\n collected.add(`${packageName}.md`)\n }\n\n const modulesRoot = path.join(packagesRoot, packageName, 'src', 'modules')\n if (!fs.existsSync(modulesRoot)) {\n continue\n }\n\n for (const moduleName of fs.readdirSync(modulesRoot)) {\n const moduleGuide = path.join(modulesRoot, moduleName, 'agentic', 'standalone-guide.md')\n if (fs.existsSync(moduleGuide)) {\n collected.add(`${packageName}.${moduleName}.md`)\n }\n }\n }\n\n return Array.from(collected).sort()\n}\n\nfunction assertPathsExist(appDir: string, relativePaths: string[]): void {\n const missingPaths = relativePaths.filter((relativePath) => !fs.existsSync(path.join(appDir, relativePath)))\n expect(missingPaths).toEqual([])\n}\n\ntest.describe('TC-INT-008: CLI agentic init mirrors standalone scaffolding assets', () => {\n test.beforeAll(() => {\n ensureCliBuilt()\n })\n\n test('should run bootstrap-free and generate the shared, guide, and tool-specific agentic files', () => {\n const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mercato-cli-agentic-'))\n\n try {\n const appDir = createStandaloneFixture(tempRoot)\n const standalonePlaywrightConfigPath = readPlaywrightConfigPathFromTemplate()\n const cliPlaywrightConfigPath = readPlaywrightConfigPathFromCliRunner()\n const commandOutput = runMercato(['agentic:init', '--tool=claude-code,codex,cursor'], appDir)\n\n expect(cliPlaywrightConfigPath).toBe(standalonePlaywrightConfigPath)\n expect(commandOutput).toContain('Agentic setup complete:')\n expect(fs.existsSync(path.join(appDir, '.mercato', 'generated'))).toBe(false)\n\n const sharedOutputs = listRelativeFiles(path.join(agenticRoot, 'shared')).map(mapSharedSourceToOutput)\n const claudeOutputs = listRelativeFiles(path.join(agenticRoot, 'claude-code')).map(mapClaudeSourceToOutput)\n const cursorOutputs = listRelativeFiles(path.join(agenticRoot, 'cursor')).map(mapCursorSourceToOutput)\n const codexOutputs = listRelativeFiles(path.join(agenticRoot, 'codex'))\n .map(mapCodexSourceToOutput)\n .filter((relativePath): relativePath is string => relativePath !== null)\n\n expect(sharedOutputs).toContain(standalonePlaywrightConfigPath)\n assertPathsExist(appDir, [...sharedOutputs, ...claudeOutputs, ...cursorOutputs, ...codexOutputs])\n expect(fs.existsSync(path.join(appDir, standalonePlaywrightConfigPath))).toBe(true)\n\n const generatedGuideNames = listRelativeFiles(path.join(appDir, '.ai', 'guides'))\n expect(generatedGuideNames).toEqual(expectedGuideOutputNames())\n\n const agentsSource = fs.readFileSync(path.join(appDir, 'AGENTS.md'), 'utf8')\n expect(agentsSource).toContain('<!-- CODEX_ENFORCEMENT_RULES_START -->')\n expect(agentsSource).toContain('.ai/guides/core.md')\n\n const specsReadmeSource = fs.readFileSync(path.join(appDir, '.ai', 'specs', 'README.md'), 'utf8')\n expect(specsReadmeSource).toContain('sample-store')\n\n const cursorRulesSource = fs.readFileSync(path.join(appDir, '.cursor', 'rules', 'open-mercato.mdc'), 'utf8')\n expect(cursorRulesSource).toContain('sample-store')\n\n const specWritingSkillSource = fs.readFileSync(\n path.join(appDir, '.ai', 'skills', 'om-spec-writing', 'SKILL.md'),\n 'utf8',\n )\n expect(specWritingSkillSource).toContain('sample-store')\n\n for (const toolDir of ['.claude', '.codex', '.cursor']) {\n const skillsLinkPath = path.join(appDir, toolDir, 'skills')\n expect(fs.lstatSync(skillsLinkPath).isSymbolicLink()).toBe(true)\n expect(normalizePath(fs.readlinkSync(skillsLinkPath))).toBe('../.ai/skills')\n }\n } finally {\n fs.rmSync(tempRoot, { recursive: true, force: true })\n }\n })\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,QAAQ,YAAY;AAC7B,SAAS,oBAAoB;AAC7B,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,MAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,MAAM,WAAW,KAAK,QAAQ,WAAW,MAAM,MAAM,MAAM,MAAM,IAAI;AACrE,MAAM,SAAS,KAAK,KAAK,UAAU,YAAY,KAAK;AACpD,MAAM,SAAS,KAAK,KAAK,QAAQ,QAAQ,QAAQ;AACjD,MAAM,iBAAiB,KAAK,KAAK,QAAQ,WAAW;AACpD,MAAM,2BAA2B,KAAK,KAAK,QAAQ,OAAO,OAAO,WAAW,gBAAgB;AAC5F,MAAM,oCAAoC,KAAK,KAAK,UAAU,YAAY,cAAc,YAAY,uBAAuB;AAC3H,MAAM,cAAc,KAAK,KAAK,UAAU,YAAY,cAAc,SAAS;AAC3E,MAAM,eAAe,KAAK,KAAK,UAAU,UAAU;AAEnD,SAAS,cAAc,OAAuB;AAC5C,SAAO,MAAM,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AACvC;AAEA,SAAS,WAAW,SAAiB,MAAgB,KAAqB;AACxE,SAAO,aAAa,SAAS,MAAM;AAAA,IACjC;AAAA,IACA,UAAU;AAAA,IACV,KAAK;AAAA,MACH,GAAG,QAAQ;AAAA,MACX,aAAa;AAAA,MACb,kBAAkB;AAAA,IACpB;AAAA,EACF,CAAC;AACH;AAEA,SAAS,WAAW,MAAgB,KAAqB;AACvD,SAAO,WAAW,QAAQ,UAAU,CAAC,QAAQ,GAAG,IAAI,GAAG,GAAG;AAC5D;AAEA,SAAS,UAAU,UAAkB,SAAuB;AAC1D,KAAG,UAAU,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD,KAAG,cAAc,UAAU,OAAO;AACpC;AAEA,SAAS,iBAAuB;AAC9B,aAAW,QAAQ,UAAU,CAAC,cAAc,GAAG,MAAM;AACvD;AAEA,SAAS,wBAAwB,SAAyB;AACxD,QAAM,SAAS,KAAK,KAAK,SAAS,cAAc;AAChD;AAAA,IACE,KAAK,KAAK,QAAQ,cAAc;AAAA,IAChC,KAAK;AAAA,MACH;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,YAAU,KAAK,KAAK,QAAQ,OAAO,YAAY,GAAG,oCAAoC;AACtF,SAAO;AACT;AAEA,SAAS,kBAAkB,SAA2B;AACpD,MAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAsB,CAAC;AAC7B,aAAW,SAAS,GAAG,YAAY,SAAS,EAAE,eAAe,KAAK,CAAC,GAAG;AACpE,UAAM,eAAe,KAAK,KAAK,SAAS,MAAM,IAAI;AAClD,QAAI,MAAM,YAAY,GAAG;AACvB,iBAAW,cAAc,kBAAkB,YAAY,GAAG;AACxD,kBAAU,KAAK,KAAK,KAAK,MAAM,MAAM,UAAU,CAAC;AAAA,MAClD;AACA;AAAA,IACF;AACA,QAAI,MAAM,OAAO,GAAG;AAClB,gBAAU,KAAK,MAAM,IAAI;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,UAAU,IAAI,aAAa,EAAE,KAAK;AAC3C;AAEA,SAAS,wBAAwB,cAA8B;AAC7D,MAAI,iBAAiB,sBAAsB;AACzC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,aAAa,WAAW,KAAK,GAAG;AACnC,UAAM,IAAI,MAAM,kCAAkC,YAAY,EAAE;AAAA,EAClE;AAEA,SAAO,cAAc,KAAK,KAAK,OAAO,aAAa,MAAM,MAAM,MAAM,CAAC,CAAC;AACzE;AAEA,SAAS,wBAAwB,cAA8B;AAC7D,MAAI,iBAAiB,sBAAsB;AACzC,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,iBAAiB;AACpC,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,oBAAoB;AACvC,WAAO;AAAA,EACT;AACA,MAAI,aAAa,WAAW,QAAQ,GAAG;AACrC,WAAO,cAAc,KAAK,KAAK,WAAW,YAAY,CAAC;AAAA,EACzD;AAEA,QAAM,IAAI,MAAM,kCAAkC,YAAY,EAAE;AAClE;AAEA,SAAS,wBAAwB,cAA8B;AAC7D,MAAI,iBAAiB,cAAc;AACjC,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,oBAAoB;AACvC,WAAO;AAAA,EACT;AACA,MAAI,aAAa,WAAW,QAAQ,KAAK,aAAa,WAAW,QAAQ,GAAG;AAC1E,WAAO,cAAc,KAAK,KAAK,WAAW,YAAY,CAAC;AAAA,EACzD;AAEA,QAAM,IAAI,MAAM,kCAAkC,YAAY,EAAE;AAClE;AAEA,SAAS,uBAAuB,cAAqC;AACnE,MAAI,iBAAiB,oBAAoB;AACvC,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,wBAAwB;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,iCAAiC,YAAY,EAAE;AACjE;AAEA,SAAS,uCAA+C;AACtD,QAAM,kBAAkB,KAAK,MAAM,GAAG,aAAa,mCAAmC,MAAM,CAAC;AAG7F,QAAM,oBAAoB,gBAAgB,UAAU,kBAAkB;AACtE,MAAI,CAAC,mBAAmB;AACtB,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAC9E;AAEA,QAAM,kBAAkB,kBAAkB,MAAM,qBAAqB;AACrE,MAAI,CAAC,kBAAkB,CAAC,GAAG;AACzB,UAAM,IAAI,MAAM,iEAAiE;AAAA,EACnF;AAEA,SAAO,cAAc,gBAAgB,CAAC,CAAC;AACzC;AAEA,SAAS,wCAAgD;AACvD,QAAM,0BAA0B,GAAG,aAAa,0BAA0B,MAAM;AAChF,QAAM,kBAAkB,wBAAwB,MAAM,sDAAsD;AAC5G,MAAI,CAAC,kBAAkB,CAAC,GAAG;AACzB,UAAM,IAAI,MAAM,sEAAsE;AAAA,EACxF;AAEA,SAAO,cAAc,gBAAgB,CAAC,CAAC;AACzC;AAEA,SAAS,2BAAqC;AAC5C,QAAM,YAAY,oBAAI,IAAY;AAElC,aAAW,eAAe,GAAG,YAAY,YAAY,GAAG;AACtD,UAAM,eAAe,KAAK,KAAK,cAAc,aAAa,WAAW,qBAAqB;AAC1F,QAAI,GAAG,WAAW,YAAY,GAAG;AAC/B,gBAAU,IAAI,GAAG,WAAW,KAAK;AAAA,IACnC;AAEA,UAAM,cAAc,KAAK,KAAK,cAAc,aAAa,OAAO,SAAS;AACzE,QAAI,CAAC,GAAG,WAAW,WAAW,GAAG;AAC/B;AAAA,IACF;AAEA,eAAW,cAAc,GAAG,YAAY,WAAW,GAAG;AACpD,YAAM,cAAc,KAAK,KAAK,aAAa,YAAY,WAAW,qBAAqB;AACvF,UAAI,GAAG,WAAW,WAAW,GAAG;AAC9B,kBAAU,IAAI,GAAG,WAAW,IAAI,UAAU,KAAK;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,SAAS,EAAE,KAAK;AACpC;AAEA,SAAS,iBAAiB,QAAgB,eAA+B;AACvE,QAAM,eAAe,cAAc,OAAO,CAAC,iBAAiB,CAAC,GAAG,WAAW,KAAK,KAAK,QAAQ,YAAY,CAAC,CAAC;AAC3G,SAAO,YAAY,EAAE,QAAQ,CAAC,CAAC;AACjC;AAEA,KAAK,SAAS,sEAAsE,MAAM;AACxF,OAAK,UAAU,MAAM;AACnB,mBAAe;AAAA,EACjB,CAAC;AAED,OAAK,6FAA6F,MAAM;AACtG,UAAM,WAAW,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,sBAAsB,CAAC;AAE9E,QAAI;AACF,YAAM,SAAS,wBAAwB,QAAQ;AAC/C,YAAM,iCAAiC,qCAAqC;AAC5E,YAAM,0BAA0B,sCAAsC;AACtE,YAAM,gBAAgB,WAAW,CAAC,gBAAgB,iCAAiC,GAAG,MAAM;AAE5F,aAAO,uBAAuB,EAAE,KAAK,8BAA8B;AACnE,aAAO,aAAa,EAAE,UAAU,yBAAyB;AACzD,aAAO,GAAG,WAAW,KAAK,KAAK,QAAQ,YAAY,WAAW,CAAC,CAAC,EAAE,KAAK,KAAK;AAE5E,YAAM,gBAAgB,kBAAkB,KAAK,KAAK,aAAa,QAAQ,CAAC,EAAE,IAAI,uBAAuB;AACrG,YAAM,gBAAgB,kBAAkB,KAAK,KAAK,aAAa,aAAa,CAAC,EAAE,IAAI,uBAAuB;AAC1G,YAAM,gBAAgB,kBAAkB,KAAK,KAAK,aAAa,QAAQ,CAAC,EAAE,IAAI,uBAAuB;AACrG,YAAM,eAAe,kBAAkB,KAAK,KAAK,aAAa,OAAO,CAAC,EACnE,IAAI,sBAAsB,EAC1B,OAAO,CAAC,iBAAyC,iBAAiB,IAAI;AAEzE,aAAO,aAAa,EAAE,UAAU,8BAA8B;AAC9D,uBAAiB,QAAQ,CAAC,GAAG,eAAe,GAAG,eAAe,GAAG,eAAe,GAAG,YAAY,CAAC;AAChG,aAAO,GAAG,WAAW,KAAK,KAAK,QAAQ,8BAA8B,CAAC,CAAC,EAAE,KAAK,IAAI;AAElF,YAAM,sBAAsB,kBAAkB,KAAK,KAAK,QAAQ,OAAO,QAAQ,CAAC;AAChF,aAAO,mBAAmB,EAAE,QAAQ,yBAAyB,CAAC;AAE9D,YAAM,eAAe,GAAG,aAAa,KAAK,KAAK,QAAQ,WAAW,GAAG,MAAM;AAC3E,aAAO,YAAY,EAAE,UAAU,wCAAwC;AACvE,aAAO,YAAY,EAAE,UAAU,oBAAoB;AAEnD,YAAM,oBAAoB,GAAG,aAAa,KAAK,KAAK,QAAQ,OAAO,SAAS,WAAW,GAAG,MAAM;AAChG,aAAO,iBAAiB,EAAE,UAAU,cAAc;AAElD,YAAM,oBAAoB,GAAG,aAAa,KAAK,KAAK,QAAQ,WAAW,SAAS,kBAAkB,GAAG,MAAM;AAC3G,aAAO,iBAAiB,EAAE,UAAU,cAAc;AAElD,YAAM,yBAAyB,GAAG;AAAA,QAChC,KAAK,KAAK,QAAQ,OAAO,UAAU,mBAAmB,UAAU;AAAA,QAChE;AAAA,MACF;AACA,aAAO,sBAAsB,EAAE,UAAU,cAAc;AAEvD,iBAAW,WAAW,CAAC,WAAW,UAAU,SAAS,GAAG;AACtD,cAAM,iBAAiB,KAAK,KAAK,QAAQ,SAAS,QAAQ;AAC1D,eAAO,GAAG,UAAU,cAAc,EAAE,eAAe,CAAC,EAAE,KAAK,IAAI;AAC/D,eAAO,cAAc,GAAG,aAAa,cAAc,CAAC,CAAC,EAAE,KAAK,eAAe;AAAA,MAC7E;AAAA,IACF,UAAE;AACA,SAAG,OAAO,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACtD;AAAA,EACF,CAAC;AACH,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -31,118 +31,118 @@ function generateShared(config) {
|
|
|
31
31
|
copyFile(srcDir, "ai/lessons.md", join(targetDir, ".ai", "lessons.md"));
|
|
32
32
|
writeTemplate(
|
|
33
33
|
srcDir,
|
|
34
|
-
"ai/skills/spec-writing/SKILL.md",
|
|
35
|
-
join(targetDir, ".ai", "skills", "spec-writing", "SKILL.md"),
|
|
34
|
+
"ai/skills/om-spec-writing/SKILL.md",
|
|
35
|
+
join(targetDir, ".ai", "skills", "om-spec-writing", "SKILL.md"),
|
|
36
36
|
config
|
|
37
37
|
);
|
|
38
38
|
copyFile(
|
|
39
39
|
srcDir,
|
|
40
|
-
"ai/skills/spec-writing/references/spec-template.md",
|
|
41
|
-
join(targetDir, ".ai", "skills", "spec-writing", "references", "spec-template.md")
|
|
40
|
+
"ai/skills/om-spec-writing/references/spec-template.md",
|
|
41
|
+
join(targetDir, ".ai", "skills", "om-spec-writing", "references", "spec-template.md")
|
|
42
42
|
);
|
|
43
43
|
copyFile(
|
|
44
44
|
srcDir,
|
|
45
|
-
"ai/skills/spec-writing/references/spec-checklist.md",
|
|
46
|
-
join(targetDir, ".ai", "skills", "spec-writing", "references", "spec-checklist.md")
|
|
45
|
+
"ai/skills/om-spec-writing/references/spec-checklist.md",
|
|
46
|
+
join(targetDir, ".ai", "skills", "om-spec-writing", "references", "spec-checklist.md")
|
|
47
47
|
);
|
|
48
48
|
copyFile(
|
|
49
49
|
srcDir,
|
|
50
|
-
"ai/skills/backend-ui-design/SKILL.md",
|
|
51
|
-
join(targetDir, ".ai", "skills", "backend-ui-design", "SKILL.md")
|
|
50
|
+
"ai/skills/om-backend-ui-design/SKILL.md",
|
|
51
|
+
join(targetDir, ".ai", "skills", "om-backend-ui-design", "SKILL.md")
|
|
52
52
|
);
|
|
53
53
|
copyFile(
|
|
54
54
|
srcDir,
|
|
55
|
-
"ai/skills/backend-ui-design/references/ui-components.md",
|
|
56
|
-
join(targetDir, ".ai", "skills", "backend-ui-design", "references", "ui-components.md")
|
|
55
|
+
"ai/skills/om-backend-ui-design/references/ui-components.md",
|
|
56
|
+
join(targetDir, ".ai", "skills", "om-backend-ui-design", "references", "ui-components.md")
|
|
57
57
|
);
|
|
58
58
|
copyFile(
|
|
59
59
|
srcDir,
|
|
60
|
-
"ai/skills/code-review/SKILL.md",
|
|
61
|
-
join(targetDir, ".ai", "skills", "code-review", "SKILL.md")
|
|
60
|
+
"ai/skills/om-code-review/SKILL.md",
|
|
61
|
+
join(targetDir, ".ai", "skills", "om-code-review", "SKILL.md")
|
|
62
62
|
);
|
|
63
63
|
copyFile(
|
|
64
64
|
srcDir,
|
|
65
|
-
"ai/skills/code-review/references/review-checklist.md",
|
|
66
|
-
join(targetDir, ".ai", "skills", "code-review", "references", "review-checklist.md")
|
|
65
|
+
"ai/skills/om-code-review/references/review-checklist.md",
|
|
66
|
+
join(targetDir, ".ai", "skills", "om-code-review", "references", "review-checklist.md")
|
|
67
67
|
);
|
|
68
|
-
copyFile(srcDir, "ai/skills/integration-builder/SKILL.md", join(targetDir, ".ai", "skills", "integration-builder", "SKILL.md"));
|
|
68
|
+
copyFile(srcDir, "ai/skills/om-integration-builder/SKILL.md", join(targetDir, ".ai", "skills", "om-integration-builder", "SKILL.md"));
|
|
69
69
|
copyFile(
|
|
70
70
|
srcDir,
|
|
71
|
-
"ai/skills/integration-builder/references/adapter-contracts.md",
|
|
72
|
-
join(targetDir, ".ai", "skills", "integration-builder", "references", "adapter-contracts.md")
|
|
71
|
+
"ai/skills/om-integration-builder/references/adapter-contracts.md",
|
|
72
|
+
join(targetDir, ".ai", "skills", "om-integration-builder", "references", "adapter-contracts.md")
|
|
73
73
|
);
|
|
74
74
|
copyFile(
|
|
75
75
|
srcDir,
|
|
76
|
-
"ai/skills/system-extension/SKILL.md",
|
|
77
|
-
join(targetDir, ".ai", "skills", "system-extension", "SKILL.md")
|
|
76
|
+
"ai/skills/om-system-extension/SKILL.md",
|
|
77
|
+
join(targetDir, ".ai", "skills", "om-system-extension", "SKILL.md")
|
|
78
78
|
);
|
|
79
79
|
copyFile(
|
|
80
80
|
srcDir,
|
|
81
|
-
"ai/skills/system-extension/references/extension-contracts.md",
|
|
82
|
-
join(targetDir, ".ai", "skills", "system-extension", "references", "extension-contracts.md")
|
|
81
|
+
"ai/skills/om-system-extension/references/extension-contracts.md",
|
|
82
|
+
join(targetDir, ".ai", "skills", "om-system-extension", "references", "extension-contracts.md")
|
|
83
83
|
);
|
|
84
84
|
copyFile(
|
|
85
85
|
srcDir,
|
|
86
|
-
"ai/skills/module-scaffold/SKILL.md",
|
|
87
|
-
join(targetDir, ".ai", "skills", "module-scaffold", "SKILL.md")
|
|
86
|
+
"ai/skills/om-module-scaffold/SKILL.md",
|
|
87
|
+
join(targetDir, ".ai", "skills", "om-module-scaffold", "SKILL.md")
|
|
88
88
|
);
|
|
89
89
|
copyFile(
|
|
90
90
|
srcDir,
|
|
91
|
-
"ai/skills/module-scaffold/references/naming-conventions.md",
|
|
92
|
-
join(targetDir, ".ai", "skills", "module-scaffold", "references", "naming-conventions.md")
|
|
91
|
+
"ai/skills/om-module-scaffold/references/naming-conventions.md",
|
|
92
|
+
join(targetDir, ".ai", "skills", "om-module-scaffold", "references", "naming-conventions.md")
|
|
93
93
|
);
|
|
94
94
|
copyFile(
|
|
95
95
|
srcDir,
|
|
96
|
-
"ai/skills/module-scaffold/references/navigation-patterns.md",
|
|
97
|
-
join(targetDir, ".ai", "skills", "module-scaffold", "references", "navigation-patterns.md")
|
|
96
|
+
"ai/skills/om-module-scaffold/references/navigation-patterns.md",
|
|
97
|
+
join(targetDir, ".ai", "skills", "om-module-scaffold", "references", "navigation-patterns.md")
|
|
98
98
|
);
|
|
99
99
|
copyFile(
|
|
100
100
|
srcDir,
|
|
101
|
-
"ai/skills/troubleshooter/SKILL.md",
|
|
102
|
-
join(targetDir, ".ai", "skills", "troubleshooter", "SKILL.md")
|
|
101
|
+
"ai/skills/om-troubleshooter/SKILL.md",
|
|
102
|
+
join(targetDir, ".ai", "skills", "om-troubleshooter", "SKILL.md")
|
|
103
103
|
);
|
|
104
104
|
copyFile(
|
|
105
105
|
srcDir,
|
|
106
|
-
"ai/skills/troubleshooter/references/diagnostic-commands.md",
|
|
107
|
-
join(targetDir, ".ai", "skills", "troubleshooter", "references", "diagnostic-commands.md")
|
|
106
|
+
"ai/skills/om-troubleshooter/references/diagnostic-commands.md",
|
|
107
|
+
join(targetDir, ".ai", "skills", "om-troubleshooter", "references", "diagnostic-commands.md")
|
|
108
108
|
);
|
|
109
109
|
copyFile(
|
|
110
110
|
srcDir,
|
|
111
|
-
"ai/skills/eject-and-customize/SKILL.md",
|
|
112
|
-
join(targetDir, ".ai", "skills", "eject-and-customize", "SKILL.md")
|
|
111
|
+
"ai/skills/om-eject-and-customize/SKILL.md",
|
|
112
|
+
join(targetDir, ".ai", "skills", "om-eject-and-customize", "SKILL.md")
|
|
113
113
|
);
|
|
114
114
|
copyFile(
|
|
115
115
|
srcDir,
|
|
116
|
-
"ai/skills/data-model-design/SKILL.md",
|
|
117
|
-
join(targetDir, ".ai", "skills", "data-model-design", "SKILL.md")
|
|
116
|
+
"ai/skills/om-data-model-design/SKILL.md",
|
|
117
|
+
join(targetDir, ".ai", "skills", "om-data-model-design", "SKILL.md")
|
|
118
118
|
);
|
|
119
119
|
copyFile(
|
|
120
120
|
srcDir,
|
|
121
|
-
"ai/skills/data-model-design/references/mikro-orm-cheatsheet.md",
|
|
122
|
-
join(targetDir, ".ai", "skills", "data-model-design", "references", "mikro-orm-cheatsheet.md")
|
|
121
|
+
"ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md",
|
|
122
|
+
join(targetDir, ".ai", "skills", "om-data-model-design", "references", "mikro-orm-cheatsheet.md")
|
|
123
123
|
);
|
|
124
124
|
copyFile(
|
|
125
125
|
srcDir,
|
|
126
|
-
"ai/skills/implement-spec/SKILL.md",
|
|
127
|
-
join(targetDir, ".ai", "skills", "implement-spec", "SKILL.md")
|
|
126
|
+
"ai/skills/om-implement-spec/SKILL.md",
|
|
127
|
+
join(targetDir, ".ai", "skills", "om-implement-spec", "SKILL.md")
|
|
128
128
|
);
|
|
129
129
|
copyFile(
|
|
130
130
|
srcDir,
|
|
131
|
-
"ai/skills/integration-tests/SKILL.md",
|
|
132
|
-
join(targetDir, ".ai", "skills", "integration-tests", "SKILL.md")
|
|
131
|
+
"ai/skills/om-integration-tests/SKILL.md",
|
|
132
|
+
join(targetDir, ".ai", "skills", "om-integration-tests", "SKILL.md")
|
|
133
133
|
);
|
|
134
134
|
copyFile(
|
|
135
135
|
srcDir,
|
|
136
|
-
"ai/skills/auto-upgrade-0.4.10-to-0.5.0/SKILL.md",
|
|
137
|
-
join(targetDir, ".ai", "skills", "auto-upgrade-0.4.10-to-0.5.0", "SKILL.md")
|
|
136
|
+
"ai/skills/om-auto-upgrade-0.4.10-to-0.5.0/SKILL.md",
|
|
137
|
+
join(targetDir, ".ai", "skills", "om-auto-upgrade-0.4.10-to-0.5.0", "SKILL.md")
|
|
138
138
|
);
|
|
139
139
|
for (const autoSkill of [
|
|
140
|
-
"auto-create-pr",
|
|
141
|
-
"auto-continue-pr",
|
|
142
|
-
"auto-create-pr-loop",
|
|
143
|
-
"auto-continue-pr-loop",
|
|
144
|
-
"auto-review-pr",
|
|
145
|
-
"auto-fix-github"
|
|
140
|
+
"om-auto-create-pr",
|
|
141
|
+
"om-auto-continue-pr",
|
|
142
|
+
"om-auto-create-pr-loop",
|
|
143
|
+
"om-auto-continue-pr-loop",
|
|
144
|
+
"om-auto-review-pr",
|
|
145
|
+
"om-auto-fix-github"
|
|
146
146
|
]) {
|
|
147
147
|
copyFile(
|
|
148
148
|
srcDir,
|
|
@@ -159,8 +159,8 @@ function generateShared(config) {
|
|
|
159
159
|
}
|
|
160
160
|
copyFile(
|
|
161
161
|
srcDir,
|
|
162
|
-
"ai/skills/trim-unused-modules/SKILL.md",
|
|
163
|
-
join(targetDir, ".ai", "skills", "trim-unused-modules", "SKILL.md")
|
|
162
|
+
"ai/skills/om-trim-unused-modules/SKILL.md",
|
|
163
|
+
join(targetDir, ".ai", "skills", "om-trim-unused-modules", "SKILL.md")
|
|
164
164
|
);
|
|
165
165
|
copyFile(srcDir, "ai/qa/tests/playwright.config.ts", join(targetDir, ".ai", "qa", "tests", "playwright.config.ts"));
|
|
166
166
|
if (existsSync(GUIDES_DIR)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/agentic-setup.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Agentic setup for the CLI `agentic:init` command.\n *\n * Source files live in packages/create-app/agentic/ and are copied\n * to packages/cli/dist/agentic/ during build (see build.mjs).\n * This module reads those files at runtime \u2014 no embedded string constants.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, symlinkSync, lstatSync, unlinkSync, readdirSync } from 'node:fs'\nimport { join, dirname, basename } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n// In the built output (dist/lib/agentic-setup.js), __dirname is dist/lib/.\n// agentic/ is copied to dist/agentic/ by build.mjs.\nconst AGENTIC_DIR = join(__dirname, '..', 'agentic')\nconst GUIDES_DIR = join(AGENTIC_DIR, 'guides')\n\ntype AskFn = (question: string) => Promise<string>\n\ninterface AgenticSetupOptions {\n tool?: string\n force?: boolean\n}\n\ninterface AgenticConfig {\n projectName: string\n targetDir: string\n}\n\n// \u2500\u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction resolvePlaceholders(content: string, config: AgenticConfig): string {\n return content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, config.projectName)\n}\n\nfunction ensureDir(filePath: string): void {\n const dir = dirname(filePath)\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true })\n}\n\nfunction writeTemplate(srcDir: string, srcRelative: string, destPath: string, config: AgenticConfig): void {\n const srcPath = join(srcDir, srcRelative)\n const content = readFileSync(srcPath, 'utf-8')\n ensureDir(destPath)\n writeFileSync(destPath, resolvePlaceholders(content, config))\n}\n\nfunction copyFile(srcDir: string, srcRelative: string, destPath: string): void {\n const srcPath = join(srcDir, srcRelative)\n ensureDir(destPath)\n copyFileSync(srcPath, destPath)\n}\n\n// \u2500\u2500\u2500 Generators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction generateShared(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'shared')\n\n // AGENTS.md\n writeTemplate(srcDir, 'AGENTS.md.template', join(targetDir, 'AGENTS.md'), config)\n\n // .ai/ structure\n writeTemplate(srcDir, 'ai/specs/README.md', join(targetDir, '.ai', 'specs', 'README.md'), config)\n copyFile(srcDir, 'ai/specs/SPEC-000-template.md', join(targetDir, '.ai', 'specs', 'SPEC-000-template.md'))\n copyFile(srcDir, 'ai/lessons.md', join(targetDir, '.ai', 'lessons.md'))\n\n // .ai/skills/\n writeTemplate(\n srcDir,\n 'ai/skills/spec-writing/SKILL.md',\n join(targetDir, '.ai', 'skills', 'spec-writing', 'SKILL.md'),\n config,\n )\n copyFile(\n srcDir,\n 'ai/skills/spec-writing/references/spec-template.md',\n join(targetDir, '.ai', 'skills', 'spec-writing', 'references', 'spec-template.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/spec-writing/references/spec-checklist.md',\n join(targetDir, '.ai', 'skills', 'spec-writing', 'references', 'spec-checklist.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/backend-ui-design/SKILL.md',\n join(targetDir, '.ai', 'skills', 'backend-ui-design', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/backend-ui-design/references/ui-components.md',\n join(targetDir, '.ai', 'skills', 'backend-ui-design', 'references', 'ui-components.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/code-review/SKILL.md',\n join(targetDir, '.ai', 'skills', 'code-review', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/code-review/references/review-checklist.md',\n join(targetDir, '.ai', 'skills', 'code-review', 'references', 'review-checklist.md'),\n )\n copyFile(srcDir, 'ai/skills/integration-builder/SKILL.md', join(targetDir, '.ai', 'skills', 'integration-builder', 'SKILL.md'))\n copyFile(\n srcDir,\n 'ai/skills/integration-builder/references/adapter-contracts.md',\n join(targetDir, '.ai', 'skills', 'integration-builder', 'references', 'adapter-contracts.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/system-extension/SKILL.md',\n join(targetDir, '.ai', 'skills', 'system-extension', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/system-extension/references/extension-contracts.md',\n join(targetDir, '.ai', 'skills', 'system-extension', 'references', 'extension-contracts.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/module-scaffold/SKILL.md',\n join(targetDir, '.ai', 'skills', 'module-scaffold', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/module-scaffold/references/naming-conventions.md',\n join(targetDir, '.ai', 'skills', 'module-scaffold', 'references', 'naming-conventions.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/module-scaffold/references/navigation-patterns.md',\n join(targetDir, '.ai', 'skills', 'module-scaffold', 'references', 'navigation-patterns.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/troubleshooter/SKILL.md',\n join(targetDir, '.ai', 'skills', 'troubleshooter', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/troubleshooter/references/diagnostic-commands.md',\n join(targetDir, '.ai', 'skills', 'troubleshooter', 'references', 'diagnostic-commands.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/eject-and-customize/SKILL.md',\n join(targetDir, '.ai', 'skills', 'eject-and-customize', 'SKILL.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/data-model-design/SKILL.md',\n join(targetDir, '.ai', 'skills', 'data-model-design', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/data-model-design/references/mikro-orm-cheatsheet.md',\n join(targetDir, '.ai', 'skills', 'data-model-design', 'references', 'mikro-orm-cheatsheet.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/implement-spec/SKILL.md',\n join(targetDir, '.ai', 'skills', 'implement-spec', 'SKILL.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/integration-tests/SKILL.md',\n join(targetDir, '.ai', 'skills', 'integration-tests', 'SKILL.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/auto-upgrade-0.4.10-to-0.5.0/SKILL.md',\n join(targetDir, '.ai', 'skills', 'auto-upgrade-0.4.10-to-0.5.0', 'SKILL.md'),\n )\n\n for (const autoSkill of [\n 'auto-create-pr',\n 'auto-continue-pr',\n 'auto-create-pr-loop',\n 'auto-continue-pr-loop',\n 'auto-review-pr',\n 'auto-fix-github',\n ]) {\n copyFile(\n srcDir,\n `ai/skills/${autoSkill}/SKILL.md`,\n join(targetDir, '.ai', 'skills', autoSkill, 'SKILL.md'),\n )\n if (existsSync(join(srcDir, 'ai', 'skills', autoSkill, 'STANDALONE.md'))) {\n copyFile(\n srcDir,\n `ai/skills/${autoSkill}/STANDALONE.md`,\n join(targetDir, '.ai', 'skills', autoSkill, 'STANDALONE.md'),\n )\n }\n }\n\n copyFile(\n srcDir,\n 'ai/skills/trim-unused-modules/SKILL.md',\n join(targetDir, '.ai', 'skills', 'trim-unused-modules', 'SKILL.md'),\n )\n\n copyFile(srcDir, 'ai/qa/tests/playwright.config.ts', join(targetDir, '.ai', 'qa', 'tests', 'playwright.config.ts'))\n\n if (existsSync(GUIDES_DIR)) {\n const guidesDestDir = join(targetDir, '.ai', 'guides')\n for (const file of readdirSync(GUIDES_DIR)) {\n if (!file.endsWith('.md')) continue\n const srcPath = join(GUIDES_DIR, file)\n const destPath = join(guidesDestDir, file)\n ensureDir(destPath)\n copyFileSync(srcPath, destPath)\n }\n }\n}\n\nfunction generateClaudeCode(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'claude-code')\n\n writeTemplate(srcDir, 'CLAUDE.md.template', join(targetDir, 'CLAUDE.md'), config)\n copyFile(srcDir, 'settings.json', join(targetDir, '.claude', 'settings.json'))\n copyFile(srcDir, 'hooks/entity-migration-check.ts', join(targetDir, '.claude', 'hooks', 'entity-migration-check.ts'))\n copyFile(srcDir, 'mcp.json.example', join(targetDir, '.mcp.json.example'))\n\n // Symlink .claude/skills \u2192 ../.ai/skills\n ensureSkillsLink(join(targetDir, '.claude', 'skills'), join('..', '.ai', 'skills'))\n}\n\nfunction generateCodex(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'codex')\n\n const agentsPath = join(targetDir, 'AGENTS.md')\n if (existsSync(agentsPath)) {\n const enforcement = readFileSync(join(srcDir, 'enforcement-rules.md'), 'utf-8')\n let agents = readFileSync(agentsPath, 'utf-8')\n const MARKER_START = '<!-- CODEX_ENFORCEMENT_RULES_START -->'\n const MARKER_END = '<!-- CODEX_ENFORCEMENT_RULES_END -->'\n\n if (agents.includes(MARKER_START)) {\n const startIdx = agents.indexOf(MARKER_START)\n const endIdx = agents.indexOf(MARKER_END)\n if (endIdx !== -1) {\n agents = agents.slice(0, startIdx) + enforcement + agents.slice(endIdx + MARKER_END.length)\n }\n } else {\n const firstNewline = agents.indexOf('\\n')\n if (firstNewline !== -1) {\n agents = agents.slice(0, firstNewline + 1) + '\\n' + enforcement + '\\n' + agents.slice(firstNewline + 1)\n } else {\n agents = agents + '\\n\\n' + enforcement\n }\n }\n writeFileSync(agentsPath, agents)\n }\n\n copyFile(srcDir, 'mcp.json.example', join(targetDir, '.codex', 'mcp.json.example'))\n\n // Symlink .codex/skills \u2192 ../.ai/skills\n ensureSkillsLink(join(targetDir, '.codex', 'skills'), join('..', '.ai', 'skills'))\n}\n\nfunction generateCursor(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'cursor')\n\n writeTemplate(srcDir, 'rules/open-mercato.mdc', join(targetDir, '.cursor', 'rules', 'open-mercato.mdc'), config)\n copyFile(srcDir, 'rules/entity-guard.mdc', join(targetDir, '.cursor', 'rules', 'entity-guard.mdc'))\n copyFile(srcDir, 'rules/generated-guard.mdc', join(targetDir, '.cursor', 'rules', 'generated-guard.mdc'))\n copyFile(srcDir, 'hooks.json', join(targetDir, '.cursor', 'hooks.json'))\n copyFile(srcDir, 'hooks/entity-migration-check.mjs', join(targetDir, '.cursor', 'hooks', 'entity-migration-check.mjs'))\n copyFile(srcDir, 'mcp.json.example', join(targetDir, '.cursor', 'mcp.json.example'))\n\n // Symlink .cursor/skills \u2192 ../.ai/skills\n ensureSkillsLink(join(targetDir, '.cursor', 'skills'), join('..', '.ai', 'skills'))\n}\n\nfunction ensureSkillsLink(linkPath: string, target: string): void {\n ensureDir(linkPath)\n if (existsSync(linkPath) && !lstatSync(linkPath).isSymbolicLink()) {\n return\n }\n if (lstatSync(linkPath, { throwIfNoEntry: false })?.isSymbolicLink()) {\n unlinkSync(linkPath)\n }\n symlinkSync(target, linkPath)\n}\n\n// \u2500\u2500\u2500 Wizard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TOOLS = [\n { key: '1', label: 'Claude Code (Anthropic)', id: 'claude-code' },\n { key: '2', label: 'Codex (OpenAI)', id: 'codex' },\n { key: '3', label: 'Cursor (Anysphere)', id: 'cursor' },\n { key: '4', label: 'Multiple tools (select individually)', id: 'multiple' },\n { key: '5', label: 'Skip \u2014 set up manually later', id: 'skip' },\n] as const\n\nconst SELECTABLE = TOOLS.filter((t) => t.id !== 'multiple' && t.id !== 'skip')\n\nasync function promptSelection(ask: AskFn): Promise<string[]> {\n console.log('')\n console.log('\uD83E\uDD16 Agentic workflow setup')\n console.log('')\n console.log(' Which AI coding tool will you use with this project?')\n console.log('')\n for (const tool of TOOLS) {\n console.log(` ${tool.key}. ${tool.label}`)\n }\n console.log('')\n\n const answer = (await ask(' Enter number(s) separated by comma [1]: ')).trim() || '1'\n\n if (answer === '5') return ['skip']\n\n if (answer === '4') {\n const selected: string[] = []\n for (const tool of SELECTABLE) {\n const yn = await ask(` Include ${tool.label}? [y/N]: `)\n if (yn.toLowerCase() === 'y' || yn.toLowerCase() === 'yes') {\n selected.push(tool.id)\n }\n }\n return selected.length > 0 ? selected : ['skip']\n }\n\n const keys = answer.split(',').map((s) => s.trim())\n const ids: string[] = []\n for (const key of keys) {\n const tool = TOOLS.find((t) => t.key === key)\n if (tool && tool.id !== 'multiple' && tool.id !== 'skip') {\n ids.push(tool.id)\n }\n }\n return ids.length > 0 ? ids : ['skip']\n}\n\nexport async function runAgenticSetup(\n targetDir: string,\n ask: AskFn,\n options?: AgenticSetupOptions,\n): Promise<void> {\n let selectedIds: string[]\n\n if (options?.tool) {\n selectedIds = options.tool.split(',').map((t) => t.trim())\n } else {\n selectedIds = await promptSelection(ask)\n }\n\n if (selectedIds.includes('skip')) {\n console.log('')\n console.log(' Skipped agentic setup.')\n console.log('')\n return\n }\n\n const config: AgenticConfig = {\n projectName: basename(targetDir),\n targetDir,\n }\n\n generateShared(config)\n if (selectedIds.includes('claude-code')) generateClaudeCode(config)\n if (selectedIds.includes('codex')) generateCodex(config)\n if (selectedIds.includes('cursor')) generateCursor(config)\n\n console.log('')\n console.log(' Agentic setup complete:')\n if (selectedIds.includes('claude-code')) {\n console.log(' \u2713 Claude Code \u2014 CLAUDE.md, .claude/hooks/, .mcp.json.example')\n }\n if (selectedIds.includes('codex')) {\n console.log(' \u2713 Codex \u2014 AGENTS.md enforcement rules, .codex/mcp.json.example')\n }\n if (selectedIds.includes('cursor')) {\n console.log(' \u2713 Cursor \u2014 .cursor/rules/, .cursor/hooks/, .cursor/mcp.json.example')\n }\n console.log('')\n}\n"],
|
|
5
|
-
"mappings": "AAQA,SAAS,YAAY,WAAW,cAAc,eAAe,cAAc,aAAa,WAAW,YAAY,mBAAmB;AAClI,SAAS,MAAM,SAAS,gBAAgB;AACxC,SAAS,qBAAqB;AAE9B,MAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AAGxD,MAAM,cAAc,KAAK,WAAW,MAAM,SAAS;AACnD,MAAM,aAAa,KAAK,aAAa,QAAQ;AAgB7C,SAAS,oBAAoB,SAAiB,QAA+B;AAC3E,SAAO,QAAQ,QAAQ,yBAAyB,OAAO,WAAW;AACpE;AAEA,SAAS,UAAU,UAAwB;AACzC,QAAM,MAAM,QAAQ,QAAQ;AAC5B,MAAI,CAAC,WAAW,GAAG,EAAG,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAC1D;AAEA,SAAS,cAAc,QAAgB,aAAqB,UAAkB,QAA6B;AACzG,QAAM,UAAU,KAAK,QAAQ,WAAW;AACxC,QAAM,UAAU,aAAa,SAAS,OAAO;AAC7C,YAAU,QAAQ;AAClB,gBAAc,UAAU,oBAAoB,SAAS,MAAM,CAAC;AAC9D;AAEA,SAAS,SAAS,QAAgB,aAAqB,UAAwB;AAC7E,QAAM,UAAU,KAAK,QAAQ,WAAW;AACxC,YAAU,QAAQ;AAClB,eAAa,SAAS,QAAQ;AAChC;AAIA,SAAS,eAAe,QAA6B;AACnD,QAAM,EAAE,UAAU,IAAI;AACtB,QAAM,SAAS,KAAK,aAAa,QAAQ;AAGzC,gBAAc,QAAQ,sBAAsB,KAAK,WAAW,WAAW,GAAG,MAAM;AAGhF,gBAAc,QAAQ,sBAAsB,KAAK,WAAW,OAAO,SAAS,WAAW,GAAG,MAAM;AAChG,WAAS,QAAQ,iCAAiC,KAAK,WAAW,OAAO,SAAS,sBAAsB,CAAC;AACzG,WAAS,QAAQ,iBAAiB,KAAK,WAAW,OAAO,YAAY,CAAC;AAGtE;AAAA,IACE;AAAA,IACA;AAAA,IACA,KAAK,WAAW,OAAO,UAAU,
|
|
4
|
+
"sourcesContent": ["/**\n * Agentic setup for the CLI `agentic:init` command.\n *\n * Source files live in packages/create-app/agentic/ and are copied\n * to packages/cli/dist/agentic/ during build (see build.mjs).\n * This module reads those files at runtime \u2014 no embedded string constants.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, symlinkSync, lstatSync, unlinkSync, readdirSync } from 'node:fs'\nimport { join, dirname, basename } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\n// In the built output (dist/lib/agentic-setup.js), __dirname is dist/lib/.\n// agentic/ is copied to dist/agentic/ by build.mjs.\nconst AGENTIC_DIR = join(__dirname, '..', 'agentic')\nconst GUIDES_DIR = join(AGENTIC_DIR, 'guides')\n\ntype AskFn = (question: string) => Promise<string>\n\ninterface AgenticSetupOptions {\n tool?: string\n force?: boolean\n}\n\ninterface AgenticConfig {\n projectName: string\n targetDir: string\n}\n\n// \u2500\u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction resolvePlaceholders(content: string, config: AgenticConfig): string {\n return content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, config.projectName)\n}\n\nfunction ensureDir(filePath: string): void {\n const dir = dirname(filePath)\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true })\n}\n\nfunction writeTemplate(srcDir: string, srcRelative: string, destPath: string, config: AgenticConfig): void {\n const srcPath = join(srcDir, srcRelative)\n const content = readFileSync(srcPath, 'utf-8')\n ensureDir(destPath)\n writeFileSync(destPath, resolvePlaceholders(content, config))\n}\n\nfunction copyFile(srcDir: string, srcRelative: string, destPath: string): void {\n const srcPath = join(srcDir, srcRelative)\n ensureDir(destPath)\n copyFileSync(srcPath, destPath)\n}\n\n// \u2500\u2500\u2500 Generators \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction generateShared(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'shared')\n\n // AGENTS.md\n writeTemplate(srcDir, 'AGENTS.md.template', join(targetDir, 'AGENTS.md'), config)\n\n // .ai/ structure\n writeTemplate(srcDir, 'ai/specs/README.md', join(targetDir, '.ai', 'specs', 'README.md'), config)\n copyFile(srcDir, 'ai/specs/SPEC-000-template.md', join(targetDir, '.ai', 'specs', 'SPEC-000-template.md'))\n copyFile(srcDir, 'ai/lessons.md', join(targetDir, '.ai', 'lessons.md'))\n\n // .ai/skills/\n writeTemplate(\n srcDir,\n 'ai/skills/om-spec-writing/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-spec-writing', 'SKILL.md'),\n config,\n )\n copyFile(\n srcDir,\n 'ai/skills/om-spec-writing/references/spec-template.md',\n join(targetDir, '.ai', 'skills', 'om-spec-writing', 'references', 'spec-template.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-spec-writing/references/spec-checklist.md',\n join(targetDir, '.ai', 'skills', 'om-spec-writing', 'references', 'spec-checklist.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-backend-ui-design/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-backend-ui-design', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-backend-ui-design/references/ui-components.md',\n join(targetDir, '.ai', 'skills', 'om-backend-ui-design', 'references', 'ui-components.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-code-review/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-code-review', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-code-review/references/review-checklist.md',\n join(targetDir, '.ai', 'skills', 'om-code-review', 'references', 'review-checklist.md'),\n )\n copyFile(srcDir, 'ai/skills/om-integration-builder/SKILL.md', join(targetDir, '.ai', 'skills', 'om-integration-builder', 'SKILL.md'))\n copyFile(\n srcDir,\n 'ai/skills/om-integration-builder/references/adapter-contracts.md',\n join(targetDir, '.ai', 'skills', 'om-integration-builder', 'references', 'adapter-contracts.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-system-extension/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-system-extension', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-system-extension/references/extension-contracts.md',\n join(targetDir, '.ai', 'skills', 'om-system-extension', 'references', 'extension-contracts.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-module-scaffold/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-module-scaffold', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-module-scaffold/references/naming-conventions.md',\n join(targetDir, '.ai', 'skills', 'om-module-scaffold', 'references', 'naming-conventions.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-module-scaffold/references/navigation-patterns.md',\n join(targetDir, '.ai', 'skills', 'om-module-scaffold', 'references', 'navigation-patterns.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-troubleshooter/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-troubleshooter', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-troubleshooter/references/diagnostic-commands.md',\n join(targetDir, '.ai', 'skills', 'om-troubleshooter', 'references', 'diagnostic-commands.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-eject-and-customize/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-eject-and-customize', 'SKILL.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-data-model-design/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-data-model-design', 'SKILL.md'),\n )\n copyFile(\n srcDir,\n 'ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md',\n join(targetDir, '.ai', 'skills', 'om-data-model-design', 'references', 'mikro-orm-cheatsheet.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-implement-spec/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-implement-spec', 'SKILL.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-integration-tests/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-integration-tests', 'SKILL.md'),\n )\n\n copyFile(\n srcDir,\n 'ai/skills/om-auto-upgrade-0.4.10-to-0.5.0/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-auto-upgrade-0.4.10-to-0.5.0', 'SKILL.md'),\n )\n\n for (const autoSkill of [\n 'om-auto-create-pr',\n 'om-auto-continue-pr',\n 'om-auto-create-pr-loop',\n 'om-auto-continue-pr-loop',\n 'om-auto-review-pr',\n 'om-auto-fix-github',\n ]) {\n copyFile(\n srcDir,\n `ai/skills/${autoSkill}/SKILL.md`,\n join(targetDir, '.ai', 'skills', autoSkill, 'SKILL.md'),\n )\n if (existsSync(join(srcDir, 'ai', 'skills', autoSkill, 'STANDALONE.md'))) {\n copyFile(\n srcDir,\n `ai/skills/${autoSkill}/STANDALONE.md`,\n join(targetDir, '.ai', 'skills', autoSkill, 'STANDALONE.md'),\n )\n }\n }\n\n copyFile(\n srcDir,\n 'ai/skills/om-trim-unused-modules/SKILL.md',\n join(targetDir, '.ai', 'skills', 'om-trim-unused-modules', 'SKILL.md'),\n )\n\n copyFile(srcDir, 'ai/qa/tests/playwright.config.ts', join(targetDir, '.ai', 'qa', 'tests', 'playwright.config.ts'))\n\n if (existsSync(GUIDES_DIR)) {\n const guidesDestDir = join(targetDir, '.ai', 'guides')\n for (const file of readdirSync(GUIDES_DIR)) {\n if (!file.endsWith('.md')) continue\n const srcPath = join(GUIDES_DIR, file)\n const destPath = join(guidesDestDir, file)\n ensureDir(destPath)\n copyFileSync(srcPath, destPath)\n }\n }\n}\n\nfunction generateClaudeCode(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'claude-code')\n\n writeTemplate(srcDir, 'CLAUDE.md.template', join(targetDir, 'CLAUDE.md'), config)\n copyFile(srcDir, 'settings.json', join(targetDir, '.claude', 'settings.json'))\n copyFile(srcDir, 'hooks/entity-migration-check.ts', join(targetDir, '.claude', 'hooks', 'entity-migration-check.ts'))\n copyFile(srcDir, 'mcp.json.example', join(targetDir, '.mcp.json.example'))\n\n // Symlink .claude/skills \u2192 ../.ai/skills\n ensureSkillsLink(join(targetDir, '.claude', 'skills'), join('..', '.ai', 'skills'))\n}\n\nfunction generateCodex(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'codex')\n\n const agentsPath = join(targetDir, 'AGENTS.md')\n if (existsSync(agentsPath)) {\n const enforcement = readFileSync(join(srcDir, 'enforcement-rules.md'), 'utf-8')\n let agents = readFileSync(agentsPath, 'utf-8')\n const MARKER_START = '<!-- CODEX_ENFORCEMENT_RULES_START -->'\n const MARKER_END = '<!-- CODEX_ENFORCEMENT_RULES_END -->'\n\n if (agents.includes(MARKER_START)) {\n const startIdx = agents.indexOf(MARKER_START)\n const endIdx = agents.indexOf(MARKER_END)\n if (endIdx !== -1) {\n agents = agents.slice(0, startIdx) + enforcement + agents.slice(endIdx + MARKER_END.length)\n }\n } else {\n const firstNewline = agents.indexOf('\\n')\n if (firstNewline !== -1) {\n agents = agents.slice(0, firstNewline + 1) + '\\n' + enforcement + '\\n' + agents.slice(firstNewline + 1)\n } else {\n agents = agents + '\\n\\n' + enforcement\n }\n }\n writeFileSync(agentsPath, agents)\n }\n\n copyFile(srcDir, 'mcp.json.example', join(targetDir, '.codex', 'mcp.json.example'))\n\n // Symlink .codex/skills \u2192 ../.ai/skills\n ensureSkillsLink(join(targetDir, '.codex', 'skills'), join('..', '.ai', 'skills'))\n}\n\nfunction generateCursor(config: AgenticConfig): void {\n const { targetDir } = config\n const srcDir = join(AGENTIC_DIR, 'cursor')\n\n writeTemplate(srcDir, 'rules/open-mercato.mdc', join(targetDir, '.cursor', 'rules', 'open-mercato.mdc'), config)\n copyFile(srcDir, 'rules/entity-guard.mdc', join(targetDir, '.cursor', 'rules', 'entity-guard.mdc'))\n copyFile(srcDir, 'rules/generated-guard.mdc', join(targetDir, '.cursor', 'rules', 'generated-guard.mdc'))\n copyFile(srcDir, 'hooks.json', join(targetDir, '.cursor', 'hooks.json'))\n copyFile(srcDir, 'hooks/entity-migration-check.mjs', join(targetDir, '.cursor', 'hooks', 'entity-migration-check.mjs'))\n copyFile(srcDir, 'mcp.json.example', join(targetDir, '.cursor', 'mcp.json.example'))\n\n // Symlink .cursor/skills \u2192 ../.ai/skills\n ensureSkillsLink(join(targetDir, '.cursor', 'skills'), join('..', '.ai', 'skills'))\n}\n\nfunction ensureSkillsLink(linkPath: string, target: string): void {\n ensureDir(linkPath)\n if (existsSync(linkPath) && !lstatSync(linkPath).isSymbolicLink()) {\n return\n }\n if (lstatSync(linkPath, { throwIfNoEntry: false })?.isSymbolicLink()) {\n unlinkSync(linkPath)\n }\n symlinkSync(target, linkPath)\n}\n\n// \u2500\u2500\u2500 Wizard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TOOLS = [\n { key: '1', label: 'Claude Code (Anthropic)', id: 'claude-code' },\n { key: '2', label: 'Codex (OpenAI)', id: 'codex' },\n { key: '3', label: 'Cursor (Anysphere)', id: 'cursor' },\n { key: '4', label: 'Multiple tools (select individually)', id: 'multiple' },\n { key: '5', label: 'Skip \u2014 set up manually later', id: 'skip' },\n] as const\n\nconst SELECTABLE = TOOLS.filter((t) => t.id !== 'multiple' && t.id !== 'skip')\n\nasync function promptSelection(ask: AskFn): Promise<string[]> {\n console.log('')\n console.log('\uD83E\uDD16 Agentic workflow setup')\n console.log('')\n console.log(' Which AI coding tool will you use with this project?')\n console.log('')\n for (const tool of TOOLS) {\n console.log(` ${tool.key}. ${tool.label}`)\n }\n console.log('')\n\n const answer = (await ask(' Enter number(s) separated by comma [1]: ')).trim() || '1'\n\n if (answer === '5') return ['skip']\n\n if (answer === '4') {\n const selected: string[] = []\n for (const tool of SELECTABLE) {\n const yn = await ask(` Include ${tool.label}? [y/N]: `)\n if (yn.toLowerCase() === 'y' || yn.toLowerCase() === 'yes') {\n selected.push(tool.id)\n }\n }\n return selected.length > 0 ? selected : ['skip']\n }\n\n const keys = answer.split(',').map((s) => s.trim())\n const ids: string[] = []\n for (const key of keys) {\n const tool = TOOLS.find((t) => t.key === key)\n if (tool && tool.id !== 'multiple' && tool.id !== 'skip') {\n ids.push(tool.id)\n }\n }\n return ids.length > 0 ? ids : ['skip']\n}\n\nexport async function runAgenticSetup(\n targetDir: string,\n ask: AskFn,\n options?: AgenticSetupOptions,\n): Promise<void> {\n let selectedIds: string[]\n\n if (options?.tool) {\n selectedIds = options.tool.split(',').map((t) => t.trim())\n } else {\n selectedIds = await promptSelection(ask)\n }\n\n if (selectedIds.includes('skip')) {\n console.log('')\n console.log(' Skipped agentic setup.')\n console.log('')\n return\n }\n\n const config: AgenticConfig = {\n projectName: basename(targetDir),\n targetDir,\n }\n\n generateShared(config)\n if (selectedIds.includes('claude-code')) generateClaudeCode(config)\n if (selectedIds.includes('codex')) generateCodex(config)\n if (selectedIds.includes('cursor')) generateCursor(config)\n\n console.log('')\n console.log(' Agentic setup complete:')\n if (selectedIds.includes('claude-code')) {\n console.log(' \u2713 Claude Code \u2014 CLAUDE.md, .claude/hooks/, .mcp.json.example')\n }\n if (selectedIds.includes('codex')) {\n console.log(' \u2713 Codex \u2014 AGENTS.md enforcement rules, .codex/mcp.json.example')\n }\n if (selectedIds.includes('cursor')) {\n console.log(' \u2713 Cursor \u2014 .cursor/rules/, .cursor/hooks/, .cursor/mcp.json.example')\n }\n console.log('')\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/cli",
|
|
3
|
-
"version": "0.6.5-develop.
|
|
3
|
+
"version": "0.6.5-develop.4639.1.0416d895fa",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"@mikro-orm/decorators": "^7.1.3",
|
|
60
60
|
"@mikro-orm/migrations": "^7.1.3",
|
|
61
61
|
"@mikro-orm/postgresql": "^7.1.3",
|
|
62
|
-
"@open-mercato/queue": "0.6.5-develop.
|
|
63
|
-
"@open-mercato/shared": "0.6.5-develop.
|
|
62
|
+
"@open-mercato/queue": "0.6.5-develop.4639.1.0416d895fa",
|
|
63
|
+
"@open-mercato/shared": "0.6.5-develop.4639.1.0416d895fa",
|
|
64
64
|
"cross-spawn": "^7.0.6",
|
|
65
65
|
"pg": "8.21.0",
|
|
66
66
|
"semver": "^7.8.1",
|
|
@@ -70,10 +70,10 @@
|
|
|
70
70
|
"typescript": "^6.0.3"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
|
-
"@open-mercato/shared": "0.6.5-develop.
|
|
73
|
+
"@open-mercato/shared": "0.6.5-develop.4639.1.0416d895fa"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@open-mercato/shared": "0.6.5-develop.
|
|
76
|
+
"@open-mercato/shared": "0.6.5-develop.4639.1.0416d895fa",
|
|
77
77
|
"@types/jest": "^30.0.0",
|
|
78
78
|
"jest": "^30.4.2",
|
|
79
79
|
"ts-jest": "^29.4.11"
|