spec-cat 0.1.13 → 0.1.14
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/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{CPqjerP3.js → C9YFwlVG.js} +1 -1
- package/.output/public/_nuxt/CkZELJoz.js +122 -0
- package/.output/public/_nuxt/CpSdCo6F.js +1 -0
- package/.output/public/_nuxt/{Djrn6aq0.js → CwGiOvuj.js} +2 -2
- package/.output/public/_nuxt/{dYG8t45S.js → Cy9osphj.js} +1 -1
- package/.output/public/_nuxt/D14Nt8oq.js +1 -0
- package/.output/public/_nuxt/DQ8x7AHg.js +1 -0
- package/.output/public/_nuxt/{ASOk6VwA.js → Do9K5d62.js} +1 -1
- package/.output/public/_nuxt/DqVSe5UI.js +1 -0
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/c4ed4e48-2de2-41d6-b09b-c785eac1d36d.json +1 -0
- package/.output/public/_nuxt/builds/meta/dev.json +1 -0
- package/.output/public/_nuxt/entry.CJqUIF8E.css +1 -0
- package/.output/public/_nuxt/{DqCsQSnP.js → vkftdPXk.js} +1 -1
- package/.output/server/chunks/_/aiProviderRegistry.mjs +36 -0
- package/.output/server/chunks/_/aiProviderRegistry.mjs.map +1 -0
- package/.output/server/chunks/_/aiProviderSelection.mjs +76 -0
- package/.output/server/chunks/_/aiProviderSelection.mjs.map +1 -0
- package/.output/server/chunks/_/chat.mjs.map +1 -1
- package/.output/server/chunks/_/claude.mjs +163 -0
- package/.output/server/chunks/_/claude.mjs.map +1 -0
- package/.output/server/chunks/_/claudeProvider.mjs +6 -6
- package/.output/server/chunks/_/claudeService.mjs +85 -0
- package/.output/server/chunks/_/claudeService.mjs.map +1 -0
- package/.output/server/chunks/_/codexProvider.mjs +1 -21
- package/.output/server/chunks/_/codexProvider.mjs.map +1 -1
- package/.output/server/chunks/_/git.mjs +1 -1
- package/.output/server/chunks/_/providerProcessError.mjs +1 -1
- package/.output/server/chunks/_/skillRegistry.mjs +249 -0
- package/.output/server/chunks/_/skillRegistry.mjs.map +1 -0
- package/.output/server/chunks/_/validateWorktree.mjs +27 -3
- package/.output/server/chunks/_/validateWorktree.mjs.map +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +704 -1869
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/_ws.mjs +4 -3
- package/.output/server/chunks/routes/_ws.mjs.map +1 -1
- package/.output/server/chunks/routes/api/ai/providers.get.mjs +3 -5
- package/.output/server/chunks/routes/api/ai/providers.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/compare.get.mjs +2 -5
- package/.output/server/chunks/routes/api/chat/compare.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/context.get.mjs +2 -5
- package/.output/server/chunks/routes/api/chat/context.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/finalize.post.mjs +3 -2
- package/.output/server/chunks/routes/api/chat/finalize.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/generate-commit-message.post.mjs +6 -3
- package/.output/server/chunks/routes/api/chat/generate-commit-message.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/preview-sync.post.mjs +2 -3
- package/.output/server/chunks/routes/api/chat/preview-sync.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/preview.delete.mjs +2 -3
- package/.output/server/chunks/routes/api/chat/preview.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/preview.post.mjs +2 -3
- package/.output/server/chunks/routes/api/chat/preview.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/rebase.post.mjs +2 -3
- package/.output/server/chunks/routes/api/chat/rebase.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/worktree-commit.post.mjs +4 -3
- package/.output/server/chunks/routes/api/chat/worktree-commit.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/worktree.delete.mjs +1 -2
- package/.output/server/chunks/routes/api/chat/worktree.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat/worktree.post.mjs +4 -8
- package/.output/server/chunks/routes/api/chat/worktree.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/chat.post.mjs +4 -5
- package/.output/server/chunks/routes/api/chat.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations/_conversationId/archive.post.mjs +1 -2
- package/.output/server/chunks/routes/api/conversations/_conversationId/archive.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations/archives/_archiveId/restore.post.mjs +2 -3
- package/.output/server/chunks/routes/api/conversations/archives/_archiveId/restore.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations/archives/_archiveId_.delete.mjs +2 -5
- package/.output/server/chunks/routes/api/conversations/archives/_archiveId_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations/archives.get.mjs +2 -5
- package/.output/server/chunks/routes/api/conversations/archives.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations/update.post.mjs +2 -5
- package/.output/server/chunks/routes/api/conversations/update.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations.get.mjs +2 -5
- package/.output/server/chunks/routes/api/conversations.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/conversations.post.mjs +2 -5
- package/.output/server/chunks/routes/api/conversations.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/cwd.get.mjs +2 -5
- package/.output/server/chunks/routes/api/cwd.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/branch-rename.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/branch-rename.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/branch.delete.mjs +2 -5
- package/.output/server/chunks/routes/api/git/branch.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/branches.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/branches.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/checkout.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/checkout.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/cherry-pick.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/cherry-pick.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/clean.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/clean.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/commit/_id_.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/commit/_id_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/commit.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/commit.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/diff.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/diff.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/fetch.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/fetch.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/file-diff.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/file-diff.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/graph.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/graph.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/log.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/log.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/merge-base.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/merge-base.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/merge.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/merge.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/pull.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/pull.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/push.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/push.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/rebase.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/rebase.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/remote.delete.mjs +2 -5
- package/.output/server/chunks/routes/api/git/remote.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/remote.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/remote.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/remote.put.mjs +2 -5
- package/.output/server/chunks/routes/api/git/remote.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/remotes.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/remotes.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/reset.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/reset.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/revert.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/revert.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/show.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/show.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/stage.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/stage.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/stash-apply.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/stash-apply.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/stash-branch.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/stash-branch.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/stash-drop.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/stash-drop.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/stash-pop.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/stash-pop.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/stash.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/stash.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/stash.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/stash.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/state.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/state.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/status.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/status.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/tag/_name_.get.mjs +2 -5
- package/.output/server/chunks/routes/api/git/tag/_name_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/tag-push.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/tag-push.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/tag.delete.mjs +2 -5
- package/.output/server/chunks/routes/api/git/tag.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/tag.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/tag.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/git/unstage.post.mjs +2 -5
- package/.output/server/chunks/routes/api/git/unstage.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +4 -5
- package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.get2.mjs +2 -3
- package/.output/server/chunks/routes/api/index.get2.mjs.map +1 -1
- package/.output/server/chunks/routes/api/index.post.mjs +2 -3
- package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/rebase/abort.post.mjs +2 -3
- package/.output/server/chunks/routes/api/rebase/abort.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/rebase/ai-resolve.post.mjs +7 -5
- package/.output/server/chunks/routes/api/rebase/ai-resolve.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/rebase/conflicts.get.mjs +1 -2
- package/.output/server/chunks/routes/api/rebase/conflicts.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/rebase/continue-sync.post.mjs +2 -3
- package/.output/server/chunks/routes/api/rebase/continue-sync.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/rebase/continue.post.mjs +1 -2
- package/.output/server/chunks/routes/api/rebase/continue.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/rebase/resolve.put.mjs +1 -2
- package/.output/server/chunks/routes/api/rebase/resolve.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/repository/status.get.mjs +2 -5
- package/.output/server/chunks/routes/api/repository/status.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/settings.get.mjs +4 -7
- package/.output/server/chunks/routes/api/settings.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/settings.post.mjs +4 -5
- package/.output/server/chunks/routes/api/settings.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/skills/_skillId/prompt.post.mjs +8 -6
- package/.output/server/chunks/routes/api/skills/_skillId/prompt.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.get.mjs +1 -4
- package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.put.mjs +1 -4
- package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.put.mjs.map +1 -1
- package/.output/server/chunks/routes/api/specs/features.get.mjs +1 -4
- package/.output/server/chunks/routes/api/specs/features.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/specs/reindex.post.mjs +2 -5
- package/.output/server/chunks/routes/api/specs/reindex.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/specs/search.get.mjs +2 -5
- package/.output/server/chunks/routes/api/specs/search.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/specs/status.get.mjs +2 -5
- package/.output/server/chunks/routes/api/specs/status.get.mjs.map +1 -1
- package/.output/server/chunks/routes/api/worktrees/_name/switch.post.mjs +2 -3
- package/.output/server/chunks/routes/api/worktrees/_name/switch.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/worktrees/_name_.delete.mjs +1 -2
- package/.output/server/chunks/routes/api/worktrees/_name_.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/git-watcher-ws.mjs +2 -5
- package/.output/server/chunks/routes/git-watcher-ws.mjs.map +1 -1
- package/.output/server/chunks/routes/renderer.mjs +2 -5
- package/.output/server/index.mjs +2 -5
- package/.output/server/index.mjs.map +1 -1
- package/.output/server/package.json +1 -1
- package/package.json +1 -1
- package/.output/public/_nuxt/B24bRLVA.js +0 -1
- package/.output/public/_nuxt/B3SzeM5g.js +0 -1
- package/.output/public/_nuxt/D3Ay6Tay.js +0 -126
- package/.output/public/_nuxt/DN_vgzh9.js +0 -1
- package/.output/public/_nuxt/afuUTAOf.js +0 -1
- package/.output/public/_nuxt/builds/meta/a94a9679-4171-4043-b507-a48b9a35f087.json +0 -1
- package/.output/public/_nuxt/entry.qjEvbHpP.css +0 -1
- package/.output/server/chunks/routes/api/auto-mode/status.get.mjs +0 -35
- package/.output/server/chunks/routes/api/auto-mode/status.get.mjs.map +0 -1
- package/.output/server/chunks/routes/api/auto-mode/toggle.post.mjs +0 -45
- package/.output/server/chunks/routes/api/auto-mode/toggle.post.mjs.map +0 -1
- package/.output/server/chunks/routes/auto-mode-ws.mjs +0 -65
- package/.output/server/chunks/routes/auto-mode-ws.mjs.map +0 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { parse } from 'yaml';
|
|
5
|
+
|
|
6
|
+
const REQUIRED_FIELDS = ["id", "name", "description", "icon", "prerequisites", "promptTemplate"];
|
|
7
|
+
const BUILTIN_SKILLS = {
|
|
8
|
+
"better-spec": {
|
|
9
|
+
id: "better-spec",
|
|
10
|
+
name: "Better Spec",
|
|
11
|
+
description: "Validates spec documents against What/How/Track separation principle",
|
|
12
|
+
icon: "DocumentCheckIcon",
|
|
13
|
+
prerequisites: ["spec.md"],
|
|
14
|
+
promptTemplate: `You are a document architect specializing in software specification quality and structure. Your task is to ensure that spec documents for feature **{{featureId}}** follow a clear role-separation principle.
|
|
15
|
+
|
|
16
|
+
## Feature Context
|
|
17
|
+
|
|
18
|
+
- **Feature ID**: {{featureId}}
|
|
19
|
+
- **Specs Directory**: {{specsDir}}
|
|
20
|
+
- **Available Documents**: {{availableDocuments}}
|
|
21
|
+
|
|
22
|
+
Read the available documents from the specs directory before proceeding with the analysis.
|
|
23
|
+
|
|
24
|
+
## Core Principle
|
|
25
|
+
|
|
26
|
+
Spec documents MUST be separated into **three clear roles**:
|
|
27
|
+
|
|
28
|
+
| Document | Role | Question | Includes | Excludes |
|
|
29
|
+
|----------|------|----------|----------|----------|
|
|
30
|
+
| **spec.md** | What | "What are we building?" | User stories, acceptance criteria, requirements, success metrics, entity definitions | Tech stack, implementation methods, file paths, code examples |
|
|
31
|
+
| **plan.md** | How | "How are we building it?" | Technical context, architecture decisions, file structure, implementation approach, design artifact references | Detailed implementation steps, checkboxes, progress tracking |
|
|
32
|
+
| **tasks.md** | Track | "What have we completed?" | Implementation task list, dependencies, checkboxes, progress, execution order | Requirements definitions, design decisions |
|
|
33
|
+
|
|
34
|
+
## Validation Process
|
|
35
|
+
|
|
36
|
+
### 1. spec.md Validation (What Document)
|
|
37
|
+
|
|
38
|
+
**Correct content:**
|
|
39
|
+
- User Stories (User Story N - Title)
|
|
40
|
+
- Acceptance Scenarios (Given/When/Then)
|
|
41
|
+
- Functional Requirements (FR-XXX)
|
|
42
|
+
- Key Entities (entity definitions)
|
|
43
|
+
- Success Criteria
|
|
44
|
+
- Edge Cases
|
|
45
|
+
- Assumptions
|
|
46
|
+
|
|
47
|
+
**Violations (should be in plan.md):**
|
|
48
|
+
- Technical Context (tech stack, versions)
|
|
49
|
+
- Project/Source Structure (file paths, directory structure)
|
|
50
|
+
- Implementation Approach
|
|
51
|
+
- Database schema details (column types, indexes)
|
|
52
|
+
- API endpoint path details (\`/api/v1/xxx\`)
|
|
53
|
+
- Code examples or snippets
|
|
54
|
+
|
|
55
|
+
### 2. plan.md Validation (How Document)
|
|
56
|
+
|
|
57
|
+
**Correct content:**
|
|
58
|
+
- Summary (feature overview)
|
|
59
|
+
- Technical Context (tech stack, dependencies, constraints)
|
|
60
|
+
- Constitution Check
|
|
61
|
+
- Project Structure (source code structure)
|
|
62
|
+
- Implementation Approach
|
|
63
|
+
- Key Design Decisions
|
|
64
|
+
- Generated Artifacts references (research.md, data-model.md, contracts/)
|
|
65
|
+
|
|
66
|
+
**Violations from spec.md (should reference, not copy):**
|
|
67
|
+
- Full User Story copies
|
|
68
|
+
- Acceptance Scenarios duplication
|
|
69
|
+
- Functional Requirements restatement
|
|
70
|
+
|
|
71
|
+
**Violations for tasks.md (should be in tasks.md):**
|
|
72
|
+
- \`- [ ]\` or \`- [x]\` checkboxes
|
|
73
|
+
- Detailed implementation steps (T001, T002...)
|
|
74
|
+
- Progress indicators
|
|
75
|
+
|
|
76
|
+
### 3. tasks.md Validation (Track Document)
|
|
77
|
+
|
|
78
|
+
**Correct content:**
|
|
79
|
+
- Task list (T001, T002...)
|
|
80
|
+
- Checkboxes (\`- [ ]\`, \`- [x]\`)
|
|
81
|
+
- Phase divisions (Phase 1: Setup, Phase 2: Implementation)
|
|
82
|
+
- Dependency markers ([P] = parallel, [US1] = User Story 1)
|
|
83
|
+
- File path mentions (files to modify)
|
|
84
|
+
- Checkpoints
|
|
85
|
+
- Summary tables
|
|
86
|
+
|
|
87
|
+
**Violations:**
|
|
88
|
+
- Detailed requirements (should reference spec.md)
|
|
89
|
+
- Design decision rationale (should reference plan.md)
|
|
90
|
+
- Constitution Check duplication
|
|
91
|
+
|
|
92
|
+
### 4. Cross-Document Consistency
|
|
93
|
+
|
|
94
|
+
**Reference integrity:**
|
|
95
|
+
- spec.md User Stories \u2192 tasks.md [US1], [US2] tags mapping
|
|
96
|
+
- spec.md FR-XXX \u2192 tasks.md corresponding implementation tasks
|
|
97
|
+
- plan.md file structure \u2192 tasks.md file paths match
|
|
98
|
+
|
|
99
|
+
## Exceptions
|
|
100
|
+
|
|
101
|
+
The following are NOT considered violations:
|
|
102
|
+
1. **spec.md Key Entities mentioning basic field types** \u2014 entity definitions are part of "What"
|
|
103
|
+
2. **plan.md Summary briefly referencing spec content** \u2014 minimal context summaries are allowed
|
|
104
|
+
3. **tasks.md mentioning file paths for implementation** \u2014 essential information for task execution
|
|
105
|
+
|
|
106
|
+
## Report Format
|
|
107
|
+
|
|
108
|
+
Produce a structured validation report with:
|
|
109
|
+
1. Summary (documents checked, issues found, severity)
|
|
110
|
+
2. Per-document validation (correct structure, violations with line references)
|
|
111
|
+
3. Cross-document consistency check
|
|
112
|
+
4. Aggressive remediation actions (what to move where, with exact replacement text)
|
|
113
|
+
5. Priority-ordered fix plan that resolves "critical" issues first
|
|
114
|
+
|
|
115
|
+
For each violation, include:
|
|
116
|
+
- The problematic section/line
|
|
117
|
+
- What the issue is
|
|
118
|
+
- Where the content should go
|
|
119
|
+
- Why the move is necessary
|
|
120
|
+
- Exact patch-ready replacement text (not only high-level suggestions)
|
|
121
|
+
|
|
122
|
+
## Enforcement Mode
|
|
123
|
+
|
|
124
|
+
- Prefer direct rewrites over passive recommendations.
|
|
125
|
+
- When a section violates role boundaries, provide concrete edited content for the target document.
|
|
126
|
+
- If multiple fixes are possible, choose the option with highest FR traceability and lowest ambiguity.
|
|
127
|
+
- Do not defer obvious fixes; produce immediately applicable edits.
|
|
128
|
+
|
|
129
|
+
## Completion Rules
|
|
130
|
+
|
|
131
|
+
- Never end by asking whether to proceed with fixes.
|
|
132
|
+
- Do not output "Would you like me to...?" style follow-up questions.
|
|
133
|
+
- If fixes are identifiable, apply them immediately with concrete patch-ready edits in the current run.
|
|
134
|
+
- Finish with "Applied Changes" and "Remaining Blockers" (if any), not a permission request.
|
|
135
|
+
|
|
136
|
+
**Goal**: Each document should be faithful to its role only, so anyone reading a document gets exactly the information they expect:
|
|
137
|
+
- Reading spec.md \u2192 understand **what** this feature is
|
|
138
|
+
- Reading plan.md \u2192 understand **how** this feature is built
|
|
139
|
+
- Reading tasks.md \u2192 understand **where** progress stands`
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
function parseSkillFile(content, filename) {
|
|
143
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
|
|
144
|
+
if (!match) {
|
|
145
|
+
console.warn(`[skills] Skipping ${filename}: missing YAML frontmatter`);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
let frontmatter;
|
|
149
|
+
try {
|
|
150
|
+
frontmatter = parse(match[1]);
|
|
151
|
+
} catch {
|
|
152
|
+
console.warn(`[skills] Skipping ${filename}: invalid YAML frontmatter`);
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
if (!frontmatter || typeof frontmatter !== "object") {
|
|
156
|
+
console.warn(`[skills] Skipping ${filename}: empty YAML frontmatter`);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
const promptTemplate = match[2].trim();
|
|
160
|
+
if (!promptTemplate) {
|
|
161
|
+
console.warn(`[skills] Skipping ${filename}: empty prompt template body`);
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
const skill = {
|
|
165
|
+
id: String(frontmatter.id || ""),
|
|
166
|
+
name: String(frontmatter.name || ""),
|
|
167
|
+
description: String(frontmatter.description || ""),
|
|
168
|
+
icon: String(frontmatter.icon || ""),
|
|
169
|
+
prerequisites: Array.isArray(frontmatter.prerequisites) ? frontmatter.prerequisites.map(String) : [],
|
|
170
|
+
promptTemplate
|
|
171
|
+
};
|
|
172
|
+
const missing = REQUIRED_FIELDS.filter((field) => {
|
|
173
|
+
if (field === "prerequisites") return false;
|
|
174
|
+
if (field === "promptTemplate") return false;
|
|
175
|
+
return !skill[field];
|
|
176
|
+
});
|
|
177
|
+
if (missing.length > 0) {
|
|
178
|
+
console.warn(`[skills] Skipping ${filename}: missing required fields: ${missing.join(", ")}`);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
return skill;
|
|
182
|
+
}
|
|
183
|
+
async function loadSkills(projectDir) {
|
|
184
|
+
const skillsDir = join(projectDir, "skills");
|
|
185
|
+
if (!existsSync(skillsDir)) {
|
|
186
|
+
return Object.values(BUILTIN_SKILLS);
|
|
187
|
+
}
|
|
188
|
+
let entries;
|
|
189
|
+
try {
|
|
190
|
+
entries = await readdir(skillsDir);
|
|
191
|
+
} catch {
|
|
192
|
+
console.warn("[skills] Failed to read skills directory");
|
|
193
|
+
return Object.values(BUILTIN_SKILLS);
|
|
194
|
+
}
|
|
195
|
+
const mdFiles = entries.filter((f) => f.endsWith(".md"));
|
|
196
|
+
const skills = [];
|
|
197
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
198
|
+
for (const filename of mdFiles) {
|
|
199
|
+
const filepath = join(skillsDir, filename);
|
|
200
|
+
let content;
|
|
201
|
+
try {
|
|
202
|
+
content = await readFile(filepath, "utf-8");
|
|
203
|
+
} catch {
|
|
204
|
+
console.warn(`[skills] Skipping ${filename}: failed to read file`);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (!content.trim()) {
|
|
208
|
+
console.warn(`[skills] Skipping ${filename}: empty file`);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
const skill = parseSkillFile(content, filename);
|
|
212
|
+
if (!skill) continue;
|
|
213
|
+
if (seenIds.has(skill.id)) {
|
|
214
|
+
console.warn(`[skills] Skipping ${filename}: duplicate skill ID "${skill.id}"`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
seenIds.add(skill.id);
|
|
218
|
+
skills.push(skill);
|
|
219
|
+
}
|
|
220
|
+
for (const [id, skill] of Object.entries(BUILTIN_SKILLS)) {
|
|
221
|
+
if (!seenIds.has(id)) {
|
|
222
|
+
skills.push(skill);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return skills;
|
|
226
|
+
}
|
|
227
|
+
async function loadSkill(projectDir, skillId) {
|
|
228
|
+
var _a, _b, _c, _d, _e;
|
|
229
|
+
const filepath = join(projectDir, "skills", `${skillId}.md`);
|
|
230
|
+
if (!existsSync(filepath)) {
|
|
231
|
+
return (_a = BUILTIN_SKILLS[skillId]) != null ? _a : null;
|
|
232
|
+
}
|
|
233
|
+
let content;
|
|
234
|
+
try {
|
|
235
|
+
content = await readFile(filepath, "utf-8");
|
|
236
|
+
} catch {
|
|
237
|
+
return (_b = BUILTIN_SKILLS[skillId]) != null ? _b : null;
|
|
238
|
+
}
|
|
239
|
+
if (!content.trim()) {
|
|
240
|
+
return (_c = BUILTIN_SKILLS[skillId]) != null ? _c : null;
|
|
241
|
+
}
|
|
242
|
+
return (_e = (_d = parseSkillFile(content, `${skillId}.md`)) != null ? _d : BUILTIN_SKILLS[skillId]) != null ? _e : null;
|
|
243
|
+
}
|
|
244
|
+
function renderPrompt(skill, context) {
|
|
245
|
+
return skill.promptTemplate.replace(/\{\{featureId\}\}/g, context.featureId).replace(/\{\{specsDir\}\}/g, resolve(context.specsDir)).replace(/\{\{availableDocuments\}\}/g, context.availableDocuments.join(", "));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export { loadSkills as a, loadSkill as l, renderPrompt as r };
|
|
249
|
+
//# sourceMappingURL=skillRegistry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillRegistry.mjs","sources":["../../../../server/utils/skillRegistry.ts"],"names":["parseYaml"],"mappings":";;;;;AAMA,MAAM,kBAAkB,CAAC,IAAA,EAAM,QAAQ,aAAA,EAAe,MAAA,EAAQ,iBAAiB,gBAAgB,CAAA;AAM/F,MAAM,cAAA,GAAkD;AAAA,EACtD,aAAA,EAAe;AAAA,IACb,EAAA,EAAI,aAAA;AAAA,IACJ,IAAA,EAAM,aAAA;AAAA,IACN,WAAA,EAAa,sEAAA;AAAA,IACb,IAAA,EAAM,mBAAA;AAAA,IACN,aAAA,EAAe,CAAC,SAAS,CAAA;AAAA,IACzB,cAAA,EAAgB,CAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,8DAAA;AAAA;AA+HpB,CAAA;AAMA,SAAS,cAAA,CAAe,SAAiB,QAAA,EAA0C;AACjF,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,4CAA4C,CAAA;AACxE,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kBAAA,EAAqB,QAAQ,CAAA,0BAAA,CAA4B,CAAA;AACtE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI;AACF,IAAA,WAAA,GAAcA,KAAA,CAAU,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EAClC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kBAAA,EAAqB,QAAQ,CAAA,0BAAA,CAA4B,CAAA;AACtE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,WAAA,IAAe,OAAO,WAAA,KAAgB,QAAA,EAAU;AACnD,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kBAAA,EAAqB,QAAQ,CAAA,wBAAA,CAA0B,CAAA;AACpE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAA,GAAiB,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AACrC,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kBAAA,EAAqB,QAAQ,CAAA,4BAAA,CAA8B,CAAA;AACxE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GAAyB;AAAA,IAC7B,EAAA,EAAI,MAAA,CAAO,WAAA,CAAY,EAAA,IAAM,EAAE,CAAA;AAAA,IAC/B,IAAA,EAAM,MAAA,CAAO,WAAA,CAAY,IAAA,IAAQ,EAAE,CAAA;AAAA,IACnC,WAAA,EAAa,MAAA,CAAO,WAAA,CAAY,WAAA,IAAe,EAAE,CAAA;AAAA,IACjD,IAAA,EAAM,MAAA,CAAO,WAAA,CAAY,IAAA,IAAQ,EAAE,CAAA;AAAA,IACnC,aAAA,EAAe,KAAA,CAAM,OAAA,CAAQ,WAAA,CAAY,aAAa,CAAA,GAClD,WAAA,CAAY,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA,GACpC,EAAC;AAAA,IACL;AAAA,GACF;AAEA,EAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,MAAA,CAAO,CAAC,KAAA,KAAU;AAChD,IAAA,IAAI,KAAA,KAAU,iBAAiB,OAAO,KAAA;AACtC,IAAA,IAAI,KAAA,KAAU,kBAAkB,OAAO,KAAA;AACvC,IAAA,OAAO,CAAC,MAAM,KAAK,CAAA;AAAA,EACrB,CAAC,CAAA;AAED,EAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,IAAA,OAAA,CAAQ,IAAA,CAAK,qBAAqB,QAAQ,CAAA,2BAAA,EAA8B,QAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAC5F,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,KAAA;AACT;AAOA,eAAsB,WAAW,UAAA,EAAgD;AAC/E,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,UAAA,EAAY,QAAQ,CAAA;AAE3C,EAAA,IAAI,CAAC,UAAA,CAAW,SAAS,CAAA,EAAG;AAC1B,IAAA,OAAO,MAAA,CAAO,OAAO,cAAc,CAAA;AAAA,EACrC;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,MAAM,QAAQ,SAAS,CAAA;AAAA,EACnC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAA,CAAQ,KAAK,0CAA0C,CAAA;AACvD,IAAA,OAAO,MAAA,CAAO,OAAO,cAAc,CAAA;AAAA,EACrC;AAEA,EAAA,MAAM,UAAU,OAAA,CAAQ,MAAA,CAAO,OAAK,CAAA,CAAE,QAAA,CAAS,KAAK,CAAC,CAAA;AACrD,EAAA,MAAM,SAA4B,EAAC;AACnC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,KAAA,MAAW,YAAY,OAAA,EAAS;AAC9B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,EAAW,QAAQ,CAAA;AACzC,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AACF,MAAA,OAAA,GAAU,MAAM,QAAA,CAAS,QAAA,EAAU,OAAO,CAAA;AAAA,IAC5C,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kBAAA,EAAqB,QAAQ,CAAA,qBAAA,CAAuB,CAAA;AACjE,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,EAAK,EAAG;AACnB,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kBAAA,EAAqB,QAAQ,CAAA,YAAA,CAAc,CAAA;AACxD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,OAAA,EAAS,QAAQ,CAAA;AAC9C,IAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,EAAG;AACzB,MAAA,OAAA,CAAQ,KAAK,CAAA,kBAAA,EAAqB,QAAQ,CAAA,sBAAA,EAAyB,KAAA,CAAM,EAAE,CAAA,CAAA,CAAG,CAAA;AAC9E,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,EAAE,CAAA;AACpB,IAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,EACnB;AAGA,EAAA,KAAA,MAAW,CAAC,EAAA,EAAI,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,cAAc,CAAA,EAAG;AACxD,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACpB,MAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,IACnB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMA,eAAsB,SAAA,CAAU,YAAoB,OAAA,EAAkD;AA5QtG,EAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA6QE,EAAA,MAAM,WAAW,IAAA,CAAK,UAAA,EAAY,QAAA,EAAU,CAAA,EAAG,OAAO,CAAA,GAAA,CAAK,CAAA;AAE3D,EAAA,IAAI,CAAC,UAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,IAAA,OAAA,CAAO,EAAA,GAAA,cAAA,CAAe,OAAO,CAAA,KAAtB,IAAA,GAAA,EAAA,GAA2B,IAAA;AAAA,EACpC;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,MAAM,QAAA,CAAS,QAAA,EAAU,OAAO,CAAA;AAAA,EAC5C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAA,CAAO,EAAA,GAAA,cAAA,CAAe,OAAO,CAAA,KAAtB,IAAA,GAAA,EAAA,GAA2B,IAAA;AAAA,EACpC;AAEA,EAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,EAAK,EAAG;AACnB,IAAA,OAAA,CAAO,EAAA,GAAA,cAAA,CAAe,OAAO,CAAA,KAAtB,IAAA,GAAA,EAAA,GAA2B,IAAA;AAAA,EACpC;AAEA,EAAA,OAAA,CAAO,EAAA,GAAA,CAAA,EAAA,GAAA,cAAA,CAAe,OAAA,EAAS,CAAA,EAAG,OAAO,CAAA,GAAA,CAAK,MAAvC,IAAA,GAAA,EAAA,GAA4C,cAAA,CAAe,OAAO,CAAA,KAAlE,IAAA,GAAA,EAAA,GAAuE,IAAA;AAChF;AAMO,SAAS,YAAA,CACd,OACA,OAAA,EACQ;AACR,EAAA,OAAO,KAAA,CAAM,eACV,OAAA,CAAQ,oBAAA,EAAsB,QAAQ,SAAS,CAAA,CAC/C,QAAQ,mBAAA,EAAqB,OAAA,CAAQ,QAAQ,QAAQ,CAAC,EACtD,OAAA,CAAQ,6BAAA,EAA+B,QAAQ,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAA;AACjF;;;;"}
|
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
import { c as createError } from '../nitro/nitro.mjs';
|
|
2
|
-
import { existsSync } from 'node:fs';
|
|
2
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { resolve, basename } from 'node:path';
|
|
3
4
|
|
|
5
|
+
const ALLOWED_ROOT_PREFIXES = ["/tmp/", "/private/tmp/"];
|
|
6
|
+
const ALLOWED_WORKTREE_NAME_PATTERNS = [
|
|
7
|
+
/^sc-[a-z0-9-]+$/,
|
|
8
|
+
// Chat worktrees: sc-<conversationId> or sc-<featureId>-<conversationId>
|
|
9
|
+
/^[a-z0-9][a-z0-9-]*-[a-z0-9]{8}$/
|
|
10
|
+
// Feature worktrees: <feature-or-branch-name>-<randomId>
|
|
11
|
+
];
|
|
12
|
+
function hasAllowedRootPrefix(path) {
|
|
13
|
+
return ALLOWED_ROOT_PREFIXES.some((prefix) => path.startsWith(prefix));
|
|
14
|
+
}
|
|
15
|
+
function hasAllowedWorktreeName(path) {
|
|
16
|
+
const dirName = basename(path);
|
|
17
|
+
return ALLOWED_WORKTREE_NAME_PATTERNS.some((pattern) => pattern.test(dirName));
|
|
18
|
+
}
|
|
4
19
|
function validateWorktreePath(worktreePath) {
|
|
5
|
-
|
|
20
|
+
const normalizedInputPath = resolve(worktreePath);
|
|
21
|
+
if (!hasAllowedRootPrefix(normalizedInputPath) || !hasAllowedWorktreeName(normalizedInputPath)) {
|
|
6
22
|
throw createError({ statusCode: 403, message: "Invalid worktree path" });
|
|
7
23
|
}
|
|
8
|
-
if (!existsSync(
|
|
24
|
+
if (!existsSync(normalizedInputPath)) {
|
|
9
25
|
throw createError({ statusCode: 404, message: "Worktree not found" });
|
|
10
26
|
}
|
|
27
|
+
let normalizedRealPath = normalizedInputPath;
|
|
28
|
+
try {
|
|
29
|
+
normalizedRealPath = realpathSync(normalizedInputPath);
|
|
30
|
+
} catch {
|
|
31
|
+
}
|
|
32
|
+
if (!hasAllowedRootPrefix(normalizedRealPath) || !hasAllowedWorktreeName(normalizedRealPath)) {
|
|
33
|
+
throw createError({ statusCode: 403, message: "Invalid worktree path" });
|
|
34
|
+
}
|
|
11
35
|
}
|
|
12
36
|
function validateFilePath(filePath) {
|
|
13
37
|
if (filePath.includes("..") || filePath.startsWith("/")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateWorktree.mjs","sources":["../../../../server/utils/validateWorktree.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validateWorktree.mjs","sources":["../../../../server/utils/validateWorktree.ts"],"names":[],"mappings":";;;;AAGA,MAAA,qBAAA,GAAA,CAAA,OAAA,EAAA,eAAA,CAAA;AACA,MAAA,8BAAA,GAAA;AAAA,EACA,iBAAA;AAAA;AAAA,EACA;AAAA;AACA,CAAA;AAEA,SAAA,qBAAA,IAAA,EAAA;AACA,EAAA,OAAA,sBAAA,IAAA,CAAA,CAAA,MAAA,KAAA,IAAA,CAAA,UAAA,CAAA,MAAA,CAAA,CAAA;AACA;AAEA,SAAA,uBAAA,IAAA,EAAA;AACA,EAAA,MAAA,OAAA,GAAA,SAAA,IAAA,CAAA;AACA,EAAA,OAAA,+BAAA,IAAA,CAAA,CAAA,OAAA,KAAA,OAAA,CAAA,IAAA,CAAA,OAAA,CAAA,CAAA;AACA;AAEA,SAAA,qBAAA,YAAA,EAAA;AACA,EAAA,MAAA,mBAAA,GAAA,QAAA,YAAA,CAAA;AACA,EAAA,IAAA,CAAA,oBAAA,CAAA,mBAAA,KAAA,CAAA,sBAAA,CAAA,mBAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,yBAAA,CAAA;AAAA,EACA;AAEA,EAAA,IAAA,CAAA,UAAA,CAAA,mBAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,sBAAA,CAAA;AAAA,EACA;AAGA,EAAA,IAAA,kBAAA,GAAA,mBAAA;AACA,EAAA,IAAA;AACA,IAAA,kBAAA,GAAA,aAAA,mBAAA,CAAA;AAAA,EACA,CAAA,CAAA,MAAA;AAAA,EAEA;AAEA,EAAA,IAAA,CAAA,oBAAA,CAAA,kBAAA,KAAA,CAAA,sBAAA,CAAA,kBAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,yBAAA,CAAA;AAAA,EACA;AACA;AAEA,SAAA,iBAAA,QAAA,EAAA;AACA,EAAA,IAAA,SAAA,QAAA,CAAA,IAAA,KAAA,QAAA,CAAA,UAAA,CAAA,GAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,qBAAA,CAAA;AAAA,EACA;AACA;;;;"}
|