@smartsoft001/pro-claude-plugins 0.2.0
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/.claude-plugin/marketplace.json +26 -0
- package/README.md +56 -0
- package/package.json +14 -0
- package/plugins/flow/.claude-plugin/README.md +91 -0
- package/plugins/flow/.claude-plugin/merge-permissions.js +115 -0
- package/plugins/flow/.claude-plugin/plugin.json +5 -0
- package/plugins/flow/.claude-plugin/settings.template.json +86 -0
- package/plugins/flow/agents/angular-component-scaffolder.md +176 -0
- package/plugins/flow/agents/angular-directive-builder.md +154 -0
- package/plugins/flow/agents/angular-guard-builder.md +244 -0
- package/plugins/flow/agents/angular-jest-test-writer.md +475 -0
- package/plugins/flow/agents/angular-pipe-builder.md +170 -0
- package/plugins/flow/agents/angular-resolver-builder.md +287 -0
- package/plugins/flow/agents/angular-service-builder.md +162 -0
- package/plugins/flow/agents/angular-signal-state-builder.md +340 -0
- package/plugins/flow/agents/angular-test-diagnostician.md +279 -0
- package/plugins/flow/agents/angular-testbed-configurator.md +315 -0
- package/plugins/flow/agents/arch-scaffolder.md +278 -0
- package/plugins/flow/agents/e2e-data-testid-injector.md +195 -0
- package/plugins/flow/agents/e2e-project-scaffolder.md +194 -0
- package/plugins/flow/agents/e2e-test-writer.md +357 -0
- package/plugins/flow/agents/shared-agent-evolver.md +294 -0
- package/plugins/flow/agents/shared-build-verifier.md +160 -0
- package/plugins/flow/agents/shared-config-updater.md +310 -0
- package/plugins/flow/agents/shared-coverage-enforcer.md +184 -0
- package/plugins/flow/agents/shared-error-handler.md +217 -0
- package/plugins/flow/agents/shared-file-creator.md +344 -0
- package/plugins/flow/agents/shared-impl-orchestrator.md +312 -0
- package/plugins/flow/agents/shared-impl-reporter.md +368 -0
- package/plugins/flow/agents/shared-impl-teammate.md +201 -0
- package/plugins/flow/agents/shared-linear-subtask-iterator.md +337 -0
- package/plugins/flow/agents/shared-logic-implementer.md +244 -0
- package/plugins/flow/agents/shared-maia-api.md +26 -0
- package/plugins/flow/agents/shared-parallelization-analyzer.md +343 -0
- package/plugins/flow/agents/shared-performance-validator.md +168 -0
- package/plugins/flow/agents/shared-plan-perspective.md +271 -0
- package/plugins/flow/agents/shared-project-standardizer.md +205 -0
- package/plugins/flow/agents/shared-report-synthesizer.md +188 -0
- package/plugins/flow/agents/shared-review-teammate.md +189 -0
- package/plugins/flow/agents/shared-security-scanner.md +186 -0
- package/plugins/flow/agents/shared-style-enforcer.md +230 -0
- package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +189 -0
- package/plugins/flow/agents/shared-tdd-developer.md +350 -0
- package/plugins/flow/agents/shared-team-coordinator.md +192 -0
- package/plugins/flow/agents/shared-test-fixer.md +186 -0
- package/plugins/flow/agents/shared-test-runner.md +191 -0
- package/plugins/flow/agents/shared-ui-classifier.md +263 -0
- package/plugins/flow/agents/shared-verification-orchestrator.md +194 -0
- package/plugins/flow/agents/shared-verification-runner.md +140 -0
- package/plugins/flow/agents/ui-a11y-validator.md +305 -0
- package/plugins/flow/agents/ui-screenshot-reporter.md +329 -0
- package/plugins/flow/agents/ui-web-designer.md +214 -0
- package/plugins/flow/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow/skills/angular-patterns/SKILL.md +191 -0
- package/plugins/flow/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow/skills/commit/SKILL.md +259 -0
- package/plugins/flow/skills/debug-helper/SKILL.md +375 -0
- package/plugins/flow/skills/impl/SKILL.md +992 -0
- package/plugins/flow/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow/skills/nx-conventions/SKILL.md +326 -0
- package/plugins/flow/skills/plan/SKILL.md +1033 -0
- package/plugins/flow/skills/push/SKILL.md +759 -0
- package/plugins/flow/skills/review/SKILL.md +443 -0
- package/plugins/flow/skills/test-e2e/SKILL.md +164 -0
- package/plugins/flow/skills/test-unit/SKILL.md +456 -0
- package/plugins/flow-external/.claude-plugin/README.md +146 -0
- package/plugins/flow-external/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-external/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-external/.claude-plugin/settings.template.json +78 -0
- package/plugins/flow-external/agents/angular-component-scaffolder.md +271 -0
- package/plugins/flow-external/agents/angular-directive-builder.md +134 -0
- package/plugins/flow-external/agents/angular-guard-builder.md +73 -0
- package/plugins/flow-external/agents/angular-pipe-builder.md +90 -0
- package/plugins/flow-external/agents/angular-resolver-builder.md +79 -0
- package/plugins/flow-external/agents/angular-service-builder.md +168 -0
- package/plugins/flow-external/agents/angular-state-builder.md +263 -0
- package/plugins/flow-external/agents/shared-build-verifier.md +67 -0
- package/plugins/flow-external/agents/shared-impl-orchestrator.md +90 -0
- package/plugins/flow-external/agents/shared-impl-reporter.md +135 -0
- package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +70 -0
- package/plugins/flow-external/agents/shared-ui-classifier.md +38 -0
- package/plugins/flow-external/agents/ui-web-designer.md +203 -0
- package/plugins/flow-external/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-external/skills/a11y-audit/SKILL.md +97 -0
- package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +268 -0
- package/plugins/flow-external/skills/angular-patterns/SKILL.md +182 -0
- package/plugins/flow-external/skills/browser-capture/SKILL.md +74 -0
- package/plugins/flow-external/skills/commit/SKILL.md +114 -0
- package/plugins/flow-external/skills/debug-helper/SKILL.md +135 -0
- package/plugins/flow-external/skills/impl/SKILL.md +218 -0
- package/plugins/flow-external/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-external/skills/linear-suggestion/SKILL.md +62 -0
- package/plugins/flow-external/skills/maia-files-delete/SKILL.md +34 -0
- package/plugins/flow-external/skills/maia-files-upload/SKILL.md +41 -0
- package/plugins/flow-external/skills/plan/SKILL.md +334 -0
- package/plugins/flow-external/skills/push/SKILL.md +232 -0
- package/plugins/flow-legacy/.claude-plugin/README.md +143 -0
- package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-legacy/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-legacy/.claude-plugin/settings.template.json +79 -0
- package/plugins/flow-legacy/agents/angular-component-scaffolder.md +327 -0
- package/plugins/flow-legacy/agents/angular-directive-builder.md +253 -0
- package/plugins/flow-legacy/agents/angular-guard-builder.md +326 -0
- package/plugins/flow-legacy/agents/angular-pipe-builder.md +238 -0
- package/plugins/flow-legacy/agents/angular-resolver-builder.md +339 -0
- package/plugins/flow-legacy/agents/angular-service-builder.md +271 -0
- package/plugins/flow-legacy/agents/angular-state-builder.md +480 -0
- package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +174 -0
- package/plugins/flow-legacy/agents/shared-impl-reporter.md +232 -0
- package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +198 -0
- package/plugins/flow-legacy/agents/shared-tdd-developer.md +307 -0
- package/plugins/flow-legacy/agents/shared-test-runner.md +133 -0
- package/plugins/flow-legacy/agents/shared-ui-classifier.md +145 -0
- package/plugins/flow-legacy/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +346 -0
- package/plugins/flow-legacy/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow-legacy/skills/commit/SKILL.md +215 -0
- package/plugins/flow-legacy/skills/debug-helper/SKILL.md +395 -0
- package/plugins/flow-legacy/skills/impl/SKILL.md +710 -0
- package/plugins/flow-legacy/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +368 -0
- package/plugins/flow-legacy/skills/plan/SKILL.md +742 -0
- package/plugins/flow-legacy/skills/push/SKILL.md +645 -0
- package/plugins/flow-legacy/skills/test-unit/SKILL.md +500 -0
- package/plugins/smart-pro/.claude-plugin/README.md +115 -0
- package/plugins/smart-pro/.claude-plugin/merge-permissions.js +129 -0
- package/plugins/smart-pro/.claude-plugin/plugin.json +5 -0
- package/plugins/smart-pro/.claude-plugin/settings.template.json +94 -0
- package/plugins/smart-pro/agents/angular-components/AGENT.md +214 -0
- package/plugins/smart-pro/hooks/CONFIG.md +198 -0
- package/plugins/smart-pro/hooks/README.md +139 -0
- package/plugins/smart-pro/hooks/audit_logger.py +107 -0
- package/plugins/smart-pro/hooks/auto_format.sh +11 -0
- package/plugins/smart-pro/hooks/hooks.json +79 -0
- package/plugins/smart-pro/hooks/safety_validator.py +129 -0
- package/plugins/smart-pro/hooks/sensitive_file_blocker.py +58 -0
- package/plugins/smart-pro/hooks/skill_validator.py +220 -0
- package/plugins/smart-pro/skills/angular-components-action-panel/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-avatar/SKILL.md +142 -0
- package/plugins/smart-pro/skills/angular-components-badge/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-breadcrumbs/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-button/SKILL.md +146 -0
- package/plugins/smart-pro/skills/angular-components-button-group/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-calendar/SKILL.md +78 -0
- package/plugins/smart-pro/skills/angular-components-card/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-card-heading/SKILL.md +105 -0
- package/plugins/smart-pro/skills/angular-components-command-palette/SKILL.md +168 -0
- package/plugins/smart-pro/skills/angular-components-container/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-description-list/SKILL.md +102 -0
- package/plugins/smart-pro/skills/angular-components-details/SKILL.md +70 -0
- package/plugins/smart-pro/skills/angular-components-divider/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-drawer/SKILL.md +136 -0
- package/plugins/smart-pro/skills/angular-components-dropdown/SKILL.md +131 -0
- package/plugins/smart-pro/skills/angular-components-empty-state/SKILL.md +103 -0
- package/plugins/smart-pro/skills/angular-components-feed/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-form/SKILL.md +77 -0
- package/plugins/smart-pro/skills/angular-components-grid-list/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-input/SKILL.md +118 -0
- package/plugins/smart-pro/skills/angular-components-list/SKILL.md +75 -0
- package/plugins/smart-pro/skills/angular-components-list-container/SKILL.md +106 -0
- package/plugins/smart-pro/skills/angular-components-media-object/SKILL.md +133 -0
- package/plugins/smart-pro/skills/angular-components-modal/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-multi-column-layout/SKILL.md +84 -0
- package/plugins/smart-pro/skills/angular-components-navbar/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-notification/SKILL.md +147 -0
- package/plugins/smart-pro/skills/angular-components-page/SKILL.md +162 -0
- package/plugins/smart-pro/skills/angular-components-page-heading/SKILL.md +96 -0
- package/plugins/smart-pro/skills/angular-components-paging/SKILL.md +86 -0
- package/plugins/smart-pro/skills/angular-components-progress-bars/SKILL.md +94 -0
- package/plugins/smart-pro/skills/angular-components-searchbar/SKILL.md +113 -0
- package/plugins/smart-pro/skills/angular-components-section-heading/SKILL.md +156 -0
- package/plugins/smart-pro/skills/angular-components-select-menu/SKILL.md +101 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-layout/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-navigation/SKILL.md +80 -0
- package/plugins/smart-pro/skills/angular-components-sign-in-form/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-stacked-layout/SKILL.md +114 -0
- package/plugins/smart-pro/skills/angular-components-stacked-list/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-stats/SKILL.md +87 -0
- package/plugins/smart-pro/skills/angular-components-table/SKILL.md +98 -0
- package/plugins/smart-pro/skills/angular-components-tabs/SKILL.md +99 -0
- package/plugins/smart-pro/skills/angular-components-textarea/SKILL.md +111 -0
- package/plugins/smart-pro/skills/angular-components-toggle/SKILL.md +109 -0
- package/plugins/smart-pro/skills/angular-components-vertical-navigation/SKILL.md +139 -0
- package/plugins/smart-pro/skills/audit-log/SKILL.md +82 -0
- package/plugins/smart-pro/skills/format-code/SKILL.md +46 -0
- package/plugins/smart-pro/skills/project-conventions/SKILL.md +90 -0
- package/plugins/smart-pro/skills/safety-check/SKILL.md +0 -0
- package/src/index.d.ts +6 -0
- package/src/index.js +7 -0
- package/src/index.js.map +1 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Sensitive File Blocker Hook for Claude Code
|
|
4
|
+
=============================================
|
|
5
|
+
|
|
6
|
+
Blocks Read/Edit/Write access to sensitive files such as .env, secrets,
|
|
7
|
+
and credentials. Files ending with .example are allowed.
|
|
8
|
+
|
|
9
|
+
Exit Codes:
|
|
10
|
+
0 - File access permitted
|
|
11
|
+
2 - File access blocked (sensitive file detected)
|
|
12
|
+
|
|
13
|
+
Integration:
|
|
14
|
+
Configured as PreToolUse hook in hooks/hooks.json
|
|
15
|
+
Receives tool call JSON via stdin from Claude Code
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import re
|
|
20
|
+
import sys
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
SENSITIVE_PATTERNS = [
|
|
24
|
+
r"\.env(?:\.|$)",
|
|
25
|
+
r"secrets",
|
|
26
|
+
r"credentials",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def main() -> None:
|
|
31
|
+
try:
|
|
32
|
+
data = json.load(sys.stdin)
|
|
33
|
+
except json.JSONDecodeError:
|
|
34
|
+
sys.exit(0)
|
|
35
|
+
|
|
36
|
+
tool_input = data.get("tool_input", {})
|
|
37
|
+
file_path = tool_input.get("file_path", "")
|
|
38
|
+
|
|
39
|
+
if not file_path:
|
|
40
|
+
sys.exit(0)
|
|
41
|
+
|
|
42
|
+
# Allow .example files (safe templates without secrets)
|
|
43
|
+
if file_path.endswith(".example"):
|
|
44
|
+
sys.exit(0)
|
|
45
|
+
|
|
46
|
+
for pattern in SENSITIVE_PATTERNS:
|
|
47
|
+
if re.search(pattern, file_path, re.IGNORECASE):
|
|
48
|
+
print(
|
|
49
|
+
f"BLOCKED: Access denied to sensitive file: {file_path}",
|
|
50
|
+
file=sys.stderr,
|
|
51
|
+
)
|
|
52
|
+
sys.exit(2)
|
|
53
|
+
|
|
54
|
+
sys.exit(0)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
main()
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Skill Validator Hook for Claude Code
|
|
4
|
+
=====================================
|
|
5
|
+
|
|
6
|
+
Validates skill-related operations and provides warnings (not blocks).
|
|
7
|
+
Implements soft enforcement per requirements.
|
|
8
|
+
|
|
9
|
+
Exit Codes:
|
|
10
|
+
0 - Always (warnings only, never blocks)
|
|
11
|
+
|
|
12
|
+
Output:
|
|
13
|
+
Warnings to stderr when potential issues detected.
|
|
14
|
+
|
|
15
|
+
Checks:
|
|
16
|
+
- SKILL.md exceeds 500 lines
|
|
17
|
+
- Missing required sections in SKILL.md
|
|
18
|
+
- Invalid frontmatter format
|
|
19
|
+
- skill-rules.json syntax errors
|
|
20
|
+
- Missing trigger configuration
|
|
21
|
+
|
|
22
|
+
Integration:
|
|
23
|
+
Configured as PreToolUse hook in .claude/settings.json
|
|
24
|
+
|
|
25
|
+
Performance Target:
|
|
26
|
+
< 200ms execution time
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
import json
|
|
30
|
+
import re
|
|
31
|
+
import sys
|
|
32
|
+
from typing import Any
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def warn(message: str) -> None:
|
|
36
|
+
"""Output warning to stderr (does not block)."""
|
|
37
|
+
print(f"[Skill Warning] {message}", file=sys.stderr)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def check_skill_file_length(file_path: str, content: str) -> None:
|
|
41
|
+
"""Warn if SKILL.md exceeds 500 lines."""
|
|
42
|
+
if not file_path.endswith("SKILL.md"):
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
line_count = content.count("\n") + 1
|
|
46
|
+
|
|
47
|
+
if line_count > 500:
|
|
48
|
+
warn(
|
|
49
|
+
f"SKILL.md has {line_count} lines (exceeds 500-line guideline). "
|
|
50
|
+
"Consider moving detailed content to resource files."
|
|
51
|
+
)
|
|
52
|
+
elif line_count > 400:
|
|
53
|
+
warn(
|
|
54
|
+
f"SKILL.md has {line_count} lines (approaching 500-line limit). "
|
|
55
|
+
"Plan for resource files if adding more content."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def check_required_sections(file_path: str, content: str) -> None:
|
|
60
|
+
"""Warn if SKILL.md missing required sections."""
|
|
61
|
+
if not file_path.endswith("SKILL.md"):
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
required_sections = [
|
|
65
|
+
("## Purpose", "Purpose"),
|
|
66
|
+
("## When to Use", "When to Use This Skill"),
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
missing = []
|
|
70
|
+
for marker, name in required_sections:
|
|
71
|
+
if marker not in content:
|
|
72
|
+
missing.append(name)
|
|
73
|
+
|
|
74
|
+
if missing:
|
|
75
|
+
warn(f"SKILL.md missing recommended sections: {', '.join(missing)}")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def check_frontmatter(file_path: str, content: str) -> None:
|
|
79
|
+
"""Warn if SKILL.md has invalid frontmatter."""
|
|
80
|
+
if not file_path.endswith("SKILL.md"):
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
# Check for frontmatter presence
|
|
84
|
+
if not content.startswith("---"):
|
|
85
|
+
warn("SKILL.md should start with YAML frontmatter (---)")
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
# Check for closing frontmatter
|
|
89
|
+
if content.count("---") < 2:
|
|
90
|
+
warn("SKILL.md frontmatter not properly closed (needs two ---)")
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
# Extract and check frontmatter content
|
|
94
|
+
frontmatter_match = re.search(
|
|
95
|
+
r"^---\s*\n(.*?)\n---",
|
|
96
|
+
content,
|
|
97
|
+
re.DOTALL
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if frontmatter_match:
|
|
101
|
+
frontmatter = frontmatter_match.group(1)
|
|
102
|
+
|
|
103
|
+
if "name:" not in frontmatter:
|
|
104
|
+
warn("SKILL.md frontmatter missing 'name' field")
|
|
105
|
+
|
|
106
|
+
if "description:" not in frontmatter:
|
|
107
|
+
warn("SKILL.md frontmatter missing 'description' field")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def check_skill_rules_syntax(file_path: str, content: str) -> None:
|
|
111
|
+
"""Warn if skill-rules.json has syntax or structure issues."""
|
|
112
|
+
if not file_path.endswith("skill-rules.json"):
|
|
113
|
+
return
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
rules = json.loads(content)
|
|
117
|
+
except json.JSONDecodeError as e:
|
|
118
|
+
warn(f"skill-rules.json has invalid JSON: {e}")
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
if not isinstance(rules, dict):
|
|
122
|
+
warn("skill-rules.json should be an object with skill names as keys")
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
for skill_name, config in rules.items():
|
|
126
|
+
if not isinstance(config, dict):
|
|
127
|
+
warn(f"Skill '{skill_name}' should be an object")
|
|
128
|
+
continue
|
|
129
|
+
|
|
130
|
+
# Check required fields
|
|
131
|
+
if "type" not in config:
|
|
132
|
+
warn(
|
|
133
|
+
f"Skill '{skill_name}' missing 'type' field "
|
|
134
|
+
"(should be 'domain', 'guardrail', or 'workflow')"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Check for triggers
|
|
138
|
+
has_prompt_triggers = bool(config.get("promptTriggers"))
|
|
139
|
+
has_file_triggers = bool(config.get("fileTriggers"))
|
|
140
|
+
|
|
141
|
+
if not has_prompt_triggers and not has_file_triggers:
|
|
142
|
+
warn(
|
|
143
|
+
f"Skill '{skill_name}' has no triggers defined - "
|
|
144
|
+
"will never auto-activate"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# Check enforcement for guardrails
|
|
148
|
+
if config.get("type") == "guardrail":
|
|
149
|
+
enforcement = config.get("enforcement")
|
|
150
|
+
if enforcement == "block" and "blockMessage" not in config:
|
|
151
|
+
warn(
|
|
152
|
+
f"Guardrail '{skill_name}' uses 'block' enforcement "
|
|
153
|
+
"but has no 'blockMessage'"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def check_resource_file_naming(file_path: str, content: str) -> None:
|
|
158
|
+
"""Warn if resource file doesn't follow naming convention."""
|
|
159
|
+
if "/resources/" not in file_path:
|
|
160
|
+
return
|
|
161
|
+
|
|
162
|
+
if not file_path.endswith(".md"):
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
# Get filename without path and extension
|
|
166
|
+
filename = file_path.split("/")[-1]
|
|
167
|
+
name_without_ext = filename.replace(".md", "")
|
|
168
|
+
|
|
169
|
+
# Check if UPPERCASE_SNAKE_CASE
|
|
170
|
+
if not re.match(r"^[A-Z][A-Z0-9_]*$", name_without_ext):
|
|
171
|
+
warn(
|
|
172
|
+
f"Resource file '{filename}' should use UPPERCASE_SNAKE_CASE "
|
|
173
|
+
"(e.g., BEST_PRACTICES.md)"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def main() -> None:
|
|
178
|
+
"""Main entry point."""
|
|
179
|
+
try:
|
|
180
|
+
data: dict[str, Any] = json.load(sys.stdin)
|
|
181
|
+
except json.JSONDecodeError:
|
|
182
|
+
sys.exit(0)
|
|
183
|
+
|
|
184
|
+
tool_name = data.get("tool_name", "")
|
|
185
|
+
tool_input = data.get("tool_input", {})
|
|
186
|
+
|
|
187
|
+
# Only validate Write/Edit operations on skill files
|
|
188
|
+
if tool_name not in ["Write", "Edit"]:
|
|
189
|
+
sys.exit(0)
|
|
190
|
+
|
|
191
|
+
file_path = tool_input.get("file_path", "")
|
|
192
|
+
|
|
193
|
+
# Only check files in .claude/skills/
|
|
194
|
+
if ".claude/skills/" not in file_path:
|
|
195
|
+
sys.exit(0)
|
|
196
|
+
|
|
197
|
+
# Get content based on tool type
|
|
198
|
+
if tool_name == "Write":
|
|
199
|
+
content = tool_input.get("content", "")
|
|
200
|
+
else: # Edit
|
|
201
|
+
content = tool_input.get("new_string", "")
|
|
202
|
+
# For Edit, we might not have full file content
|
|
203
|
+
# Run more limited checks
|
|
204
|
+
|
|
205
|
+
if not content:
|
|
206
|
+
sys.exit(0)
|
|
207
|
+
|
|
208
|
+
# Run checks
|
|
209
|
+
check_skill_file_length(file_path, content)
|
|
210
|
+
check_required_sections(file_path, content)
|
|
211
|
+
check_frontmatter(file_path, content)
|
|
212
|
+
check_skill_rules_syntax(file_path, content)
|
|
213
|
+
check_resource_file_naming(file_path, content)
|
|
214
|
+
|
|
215
|
+
# Always exit 0 - warnings only, never block
|
|
216
|
+
sys.exit(0)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
if __name__ == "__main__":
|
|
220
|
+
main()
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-components-action-panel
|
|
3
|
+
description: Action panel component for @smartsoft001/pro-angular. Two layouts (card, with-action) with content modes (buttons, link, input, toggle), plain or well surface style, and configurable title placement.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Action Panel Component (Pro)
|
|
8
|
+
|
|
9
|
+
Use the wrapper `<smartpro-action-panel>` and pick a layout via `options.layout`. The panel renders a title, description, and an action area; the action area can be vertical (card) or horizontal (with-action). Each layout supports multiple content modes.
|
|
10
|
+
|
|
11
|
+
## Layouts
|
|
12
|
+
|
|
13
|
+
| `options.layout` | Selector | Description |
|
|
14
|
+
| ------------------ | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| `'card'` (default) | `smartpro-action-panel-card` | Title + description with the action area below. Surface is plain by default; set `style: 'well'` for a muted gray surface. |
|
|
16
|
+
| `'with-action'` | `smartpro-action-panel-with-action` | Horizontal layout — description and action sit on the same row. Title sits above by default; set `titleAtTop: false` to group it with the description in the left column. Set `style: 'well'` to nest the row inside a gray well. |
|
|
17
|
+
|
|
18
|
+
## Content modes
|
|
19
|
+
|
|
20
|
+
`options.contentMode` chooses how the action area renders. Modes available per layout:
|
|
21
|
+
|
|
22
|
+
| Mode (default `'buttons'`) | Layout support | Renders |
|
|
23
|
+
| -------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| `'buttons'` | both | One button per `options.actions[]` entry. Plain surface uses primary indigo style; well surface uses secondary white style. |
|
|
25
|
+
| `'link'` | `card` | Anchor link with arrow per action. |
|
|
26
|
+
| `'input'` | `card` | Form with an email field followed by the first action as a submit button. Customise via `inputPlaceholder` and `inputAriaLabel`. |
|
|
27
|
+
| `'toggle'` | `with-action` | Single switch that emits `actionClick` with `actionId: 'enable'` or `'disable'`. |
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
### IActionPanelOptionsPro (`action-panel.types.ts`)
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
type SmartActionPanelLayoutPro = 'card' | 'with-action';
|
|
35
|
+
type SmartActionPanelContentMode = 'buttons' | 'link' | 'input' | 'toggle';
|
|
36
|
+
type SmartActionPanelStyle = 'plain' | 'well';
|
|
37
|
+
|
|
38
|
+
interface IActionPanelOptionsPro {
|
|
39
|
+
layout?: SmartActionPanelLayoutPro; // 'card' (default) | 'with-action'
|
|
40
|
+
contentMode?: SmartActionPanelContentMode; // 'buttons' (default) | 'link' | 'input' | 'toggle'
|
|
41
|
+
style?: SmartActionPanelStyle; // 'plain' (default) | 'well'
|
|
42
|
+
titleAtTop?: boolean; // with-action: true (default) places title above the row, false groups it in the left column
|
|
43
|
+
inputPlaceholder?: string; // input mode only
|
|
44
|
+
inputAriaLabel?: string; // input mode only
|
|
45
|
+
title?: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
actions?: IActionPanelAction[];
|
|
48
|
+
descriptionTpl?: TemplateRef<unknown>;
|
|
49
|
+
contentTpl?: TemplateRef<unknown>; // with-action + style='well': replaces the default description rendering inside the well
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface IActionPanelAction {
|
|
53
|
+
id: string;
|
|
54
|
+
label?: string;
|
|
55
|
+
href?: string;
|
|
56
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'link';
|
|
57
|
+
iconTpl?: TemplateRef<unknown>;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Outputs
|
|
62
|
+
|
|
63
|
+
- `actionClick: { actionId: string }` — emitted on button click, link click, form submit, or toggle change. Toggle emits `actionId: 'enable'` when checked and `'disable'` when unchecked.
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
### Simple card with buttons (default)
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<smartpro-action-panel
|
|
71
|
+
[options]="{
|
|
72
|
+
title: 'Manage subscription',
|
|
73
|
+
description: 'Lorem ipsum...',
|
|
74
|
+
actions: [{ id: 'change', label: 'Change plan' }]
|
|
75
|
+
}"
|
|
76
|
+
(actionClick)="onAction($event)"
|
|
77
|
+
/>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Card with link
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<smartpro-action-panel
|
|
84
|
+
[options]="{
|
|
85
|
+
layout: 'card',
|
|
86
|
+
contentMode: 'link',
|
|
87
|
+
title: 'Need help?',
|
|
88
|
+
description: 'Read the docs.',
|
|
89
|
+
actions: [{ id: 'docs', label: 'Open docs', href: '/docs' }]
|
|
90
|
+
}"
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Card with email input
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<smartpro-action-panel
|
|
98
|
+
[options]="{
|
|
99
|
+
layout: 'card',
|
|
100
|
+
contentMode: 'input',
|
|
101
|
+
title: 'Subscribe',
|
|
102
|
+
description: 'Get product updates.',
|
|
103
|
+
actions: [{ id: 'subscribe', label: 'Subscribe' }]
|
|
104
|
+
}"
|
|
105
|
+
/>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Card with gray surface
|
|
109
|
+
|
|
110
|
+
```html
|
|
111
|
+
<smartpro-action-panel
|
|
112
|
+
[options]="{ layout: 'card', style: 'well', title: 'Notes', description: 'A muted card.', actions: [...] }"
|
|
113
|
+
/>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Horizontal panel with action button on the right
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
<smartpro-action-panel
|
|
120
|
+
[options]="{
|
|
121
|
+
layout: 'with-action',
|
|
122
|
+
title: 'Manage subscription',
|
|
123
|
+
description: 'Plan changes apply immediately.',
|
|
124
|
+
actions: [{ id: 'change', label: 'Change plan' }]
|
|
125
|
+
}"
|
|
126
|
+
/>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Horizontal panel with title grouped on the left
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<smartpro-action-panel
|
|
133
|
+
[options]="{ layout: 'with-action', titleAtTop: false, title: 'Plan', description: '...', actions: [...] }"
|
|
134
|
+
/>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Horizontal panel with toggle
|
|
138
|
+
|
|
139
|
+
```html
|
|
140
|
+
<smartpro-action-panel
|
|
141
|
+
[options]="{ layout: 'with-action', contentMode: 'toggle', title: 'Notifications', description: 'Email me on updates.' }"
|
|
142
|
+
(actionClick)="onToggle($event)"
|
|
143
|
+
/>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Horizontal panel with action inside a well
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<smartpro-action-panel
|
|
150
|
+
[options]="{ layout: 'with-action', style: 'well', title: 'Payment method', description: 'Visa ending 4242', actions: [...] }"
|
|
151
|
+
/>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## File Locations
|
|
155
|
+
|
|
156
|
+
- Wrapper: `packages/shared/angular/src/lib/components/action-panel/action-panel.component.ts`
|
|
157
|
+
- Types: `packages/shared/angular/src/lib/components/action-panel/action-panel.types.ts`
|
|
158
|
+
- Layouts: `packages/shared/angular/src/lib/components/action-panel/{card,with-action}/<name>.component.ts`
|
|
159
|
+
- Stories: `packages/shared/angular/src/lib/components/action-panel/action-panel.component.stories.ts`
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-components-avatar
|
|
3
|
+
description: Avatar component for @smartsoft001/pro-angular. Two layouts (single, group), 10 source variants via composable options (shape, size, notificationPosition, placeholderType, stackDirection, withText, notificationColor).
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Avatar Component (Pro)
|
|
8
|
+
|
|
9
|
+
Use `<smartpro-avatar>`. The wrapper picks one of two child layouts based on `layout` input or whether `group` has items.
|
|
10
|
+
|
|
11
|
+
## Layouts
|
|
12
|
+
|
|
13
|
+
| `layout` (auto-detected) | Selector | Description |
|
|
14
|
+
| ------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| `'single'` (default) | `smartpro-avatar-single` | Single avatar — image, initials, or placeholder icon. Optional notification dot (top/bottom). Optional text + subtext. |
|
|
16
|
+
| `'group'` | `smartpro-avatar-group` | Overlapping stack of avatars. Triggered when `group: IAvatarItem[]` has items. |
|
|
17
|
+
|
|
18
|
+
## Source variant mapping
|
|
19
|
+
|
|
20
|
+
| Tailwind UI variant | Pro options |
|
|
21
|
+
| ---------------------------- | ----------------------------------------------------------------- |
|
|
22
|
+
| Circular plain | `shape: 'circle'` (default) |
|
|
23
|
+
| Circular top notification | `shape: 'circle'`, `notificationPosition: 'top'` |
|
|
24
|
+
| Circular bottom notification | `shape: 'circle'`, `notificationPosition: 'bottom'` |
|
|
25
|
+
| Rounded plain | `shape: 'rounded'` |
|
|
26
|
+
| Rounded top notification | `shape: 'rounded'`, `notificationPosition: 'top'` |
|
|
27
|
+
| Rounded bottom notification | `shape: 'rounded'`, `notificationPosition: 'bottom'` |
|
|
28
|
+
| Placeholder icon | no `imageUrl` and no `initials` — defaults to icon |
|
|
29
|
+
| Placeholder initials | `initials: 'AB'` (auto), or `options.placeholderType: 'initials'` |
|
|
30
|
+
| Group stacked top-to-bottom | `group: IAvatarItem[]` (default `stackDirection`) |
|
|
31
|
+
| Group stacked bottom-to-top | `group: IAvatarItem[]`, `options.stackDirection: 'bottom-to-top'` |
|
|
32
|
+
| With text | `options.withText: true`, `options.text`, `options.subtext` |
|
|
33
|
+
|
|
34
|
+
## API
|
|
35
|
+
|
|
36
|
+
### Types (`avatar.types.ts`)
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
type SmartAvatarLayoutPro = 'single' | 'group';
|
|
40
|
+
type SmartAvatarNotificationColor = 'green' | 'gray' | 'red';
|
|
41
|
+
|
|
42
|
+
interface IAvatarOptionsPro extends IAvatarOptions {
|
|
43
|
+
layout?: SmartAvatarLayoutPro;
|
|
44
|
+
notificationColor?: SmartAvatarNotificationColor;
|
|
45
|
+
withText?: boolean;
|
|
46
|
+
text?: string;
|
|
47
|
+
subtext?: string;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`IAvatarOptions` (re-exported from `@smartsoft001/angular`) provides `placeholderType: 'icon' | 'initials'`, `stackDirection: 'top-to-bottom' | 'bottom-to-top'`.
|
|
52
|
+
|
|
53
|
+
`IAvatarItem` (re-exported): `{ id, imageUrl?, initials? }`.
|
|
54
|
+
|
|
55
|
+
`SmartAvatarSize`: `'xs' | 'sm' | 'md' | 'lg' | 'xl'`. `SmartAvatarShape`: `'circle' | 'rounded'`.
|
|
56
|
+
|
|
57
|
+
### Wrapper inputs
|
|
58
|
+
|
|
59
|
+
| Input | Type | Default | Description |
|
|
60
|
+
| ---------------------- | ----------------------------------- | ----------- | ------------------------------------------------------------------------------------------- |
|
|
61
|
+
| `imageUrl` | `string \| undefined` | `undefined` | Avatar image URL (single layout). When missing, falls back to initials, then placeholder. |
|
|
62
|
+
| `initials` | `string \| undefined` | `undefined` | Initials text (single layout) shown when `imageUrl` is absent. |
|
|
63
|
+
| `size` | `SmartAvatarSize` | `'md'` | Avatar size. |
|
|
64
|
+
| `shape` | `SmartAvatarShape` | `'circle'` | Avatar shape. |
|
|
65
|
+
| `notificationPosition` | `'top' \| 'bottom' \| undefined` | `undefined` | Renders a colored dot at the given corner. |
|
|
66
|
+
| `group` | `IAvatarItem[] \| undefined` | `undefined` | When non-empty, the wrapper auto-selects the `group` layout. |
|
|
67
|
+
| `layout` | `SmartAvatarLayoutPro \| undefined` | `undefined` | Force a layout. |
|
|
68
|
+
| `options` | `IAvatarOptionsPro \| undefined` | `undefined` | All pro options (notification color, with-text content, placeholder type, stack direction). |
|
|
69
|
+
| `class` | `string` | `''` | Forwarded to the chosen layout's host element. |
|
|
70
|
+
|
|
71
|
+
### Outputs / Slots
|
|
72
|
+
|
|
73
|
+
No outputs. No `<ng-content>` slot.
|
|
74
|
+
|
|
75
|
+
## Usage examples
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<!-- Simple circular avatar -->
|
|
79
|
+
<smartpro-avatar imageUrl="/img/me.png" />
|
|
80
|
+
|
|
81
|
+
<!-- Rounded square with notification dot -->
|
|
82
|
+
<smartpro-avatar
|
|
83
|
+
imageUrl="/img/me.png"
|
|
84
|
+
shape="rounded"
|
|
85
|
+
notificationPosition="top"
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<!-- Initials -->
|
|
89
|
+
<smartpro-avatar initials="AP" size="lg" />
|
|
90
|
+
|
|
91
|
+
<!-- Placeholder (icon) -->
|
|
92
|
+
<smartpro-avatar />
|
|
93
|
+
|
|
94
|
+
<!-- Group stack -->
|
|
95
|
+
<smartpro-avatar
|
|
96
|
+
[group]="[
|
|
97
|
+
{ id: '1', imageUrl: '/img/a.png' },
|
|
98
|
+
{ id: '2', initials: 'BC' },
|
|
99
|
+
{ id: '3', imageUrl: '/img/d.png' }
|
|
100
|
+
]"
|
|
101
|
+
/>
|
|
102
|
+
|
|
103
|
+
<!-- Group reversed stacking -->
|
|
104
|
+
<smartpro-avatar
|
|
105
|
+
[group]="members"
|
|
106
|
+
[options]="{ stackDirection: 'bottom-to-top' }"
|
|
107
|
+
/>
|
|
108
|
+
|
|
109
|
+
<!-- With text (avatar + label + subtitle) -->
|
|
110
|
+
<smartpro-avatar
|
|
111
|
+
imageUrl="/img/me.png"
|
|
112
|
+
[options]="{ withText: true, text: 'Ashley Porter', subtext: 'Product designer' }"
|
|
113
|
+
/>
|
|
114
|
+
|
|
115
|
+
<!-- Notification dot color -->
|
|
116
|
+
<smartpro-avatar
|
|
117
|
+
imageUrl="/img/me.png"
|
|
118
|
+
notificationPosition="bottom"
|
|
119
|
+
[options]="{ notificationColor: 'red' }"
|
|
120
|
+
/>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Accessibility
|
|
124
|
+
|
|
125
|
+
- Image avatars use `alt=""` (decorative); the surrounding context provides the name.
|
|
126
|
+
- Initials inherit text content for screen readers.
|
|
127
|
+
- Notification dot is `aria-hidden="true"`; status meaning must be conveyed elsewhere if it matters.
|
|
128
|
+
- Placeholder SVG is `aria-hidden="true"`.
|
|
129
|
+
|
|
130
|
+
## File Locations
|
|
131
|
+
|
|
132
|
+
- Wrapper: `packages/shared/angular/src/lib/components/avatar/avatar.component.ts`
|
|
133
|
+
- Types: `packages/shared/angular/src/lib/components/avatar/avatar.types.ts`
|
|
134
|
+
- Classes utility: `packages/shared/angular/src/lib/components/avatar/avatar-classes.util.ts`
|
|
135
|
+
- Layouts: `packages/shared/angular/src/lib/components/avatar/{single,group}/<name>.component.ts`
|
|
136
|
+
- Stories: `packages/shared/angular/src/lib/components/avatar/avatar.component.stories.ts`
|
|
137
|
+
- Module entry: `packages/shared/angular/src/lib/components/components.module.ts` (`AVATAR_COMPONENTS`)
|
|
138
|
+
|
|
139
|
+
## Peer dependency
|
|
140
|
+
|
|
141
|
+
- `@smartsoft001/angular@^2.123.0` — provides `AvatarBaseComponent`, `IAvatarItem`, `IAvatarOptions`, `SmartAvatarSize`, `SmartAvatarShape`.
|
|
142
|
+
- No `@tailwindplus/elements` dep required.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-components-badge
|
|
3
|
+
description: Badge / tag component for @smartsoft001/pro-angular. Single `default` layout with composable options (variant border/flat, shape pill/square, withDot, withRemove) across 8 colors and 2 sizes.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Badge Component (Pro)
|
|
8
|
+
|
|
9
|
+
Use `<smartpro-badge>`. A single layout covers all 16+ Tailwind UI variants via composable options on `IBadgeOptionsPro`.
|
|
10
|
+
|
|
11
|
+
## Variants matrix
|
|
12
|
+
|
|
13
|
+
| Dimension | Values |
|
|
14
|
+
| ------------ | ------------------------------------------------------------------------------ |
|
|
15
|
+
| `variant` | `'border'` (default — `bg-50` with `inset-ring`) or `'flat'` (`bg-100`) |
|
|
16
|
+
| `shape` | `'pill'` (default — `rounded-full`) or `'square'` (`rounded-md`) |
|
|
17
|
+
| `size` | `'sm'` (default — `text-xs`, `px-2`) or `'md'` (`text-sm`, `px-2.5`) |
|
|
18
|
+
| `color` | 8 colors: `gray`, `red`, `yellow`, `green`, `blue`, `indigo`, `purple`, `pink` |
|
|
19
|
+
| `withDot` | Adds a leading colored dot SVG |
|
|
20
|
+
| `withRemove` | Adds a trailing × button that emits `(removed)` |
|
|
21
|
+
|
|
22
|
+
## Source variant mapping
|
|
23
|
+
|
|
24
|
+
| Tailwind UI variant | Pro options |
|
|
25
|
+
| -------------------------- | ---------------------------------------------------- |
|
|
26
|
+
| Border (default) | `variant: 'border'` |
|
|
27
|
+
| Flat | `variant: 'flat'` |
|
|
28
|
+
| Pill | `shape: 'pill'` (default) |
|
|
29
|
+
| Square (rounded-md) | `shape: 'square'` (or `pill: false` for fork compat) |
|
|
30
|
+
| With dot | `withDot: true` |
|
|
31
|
+
| With remove (close button) | `withRemove: true` |
|
|
32
|
+
| Any of 8 colors | `color: 'gray' \| 'red' \| ... \| 'pink'` |
|
|
33
|
+
| Two sizes | `size: 'sm' \| 'md'` |
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
### Types (`badge.types.ts`)
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
type SmartBadgeShape = 'pill' | 'square';
|
|
41
|
+
|
|
42
|
+
interface IBadgeOptionsPro extends IBadgeOptions {
|
|
43
|
+
shape?: SmartBadgeShape;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`IBadgeOptions` (re-exported from `@smartsoft001/angular`): `variant?: 'border' | 'flat'`, `pill?: boolean` (fork compat — `false` ⇒ `square`), `withDot?: boolean`, `withRemove?: boolean`.
|
|
48
|
+
|
|
49
|
+
`SmartBadgeColor`: `'gray' | 'red' | 'yellow' | 'green' | 'blue' | 'indigo' | 'purple' | 'pink'`.
|
|
50
|
+
|
|
51
|
+
### Wrapper inputs
|
|
52
|
+
|
|
53
|
+
| Input | Type | Default | Description |
|
|
54
|
+
| --------- | ------------------------------- | ----------- | -------------------------------------- |
|
|
55
|
+
| `text` | `string` (required) | — | Badge label. |
|
|
56
|
+
| `color` | `SmartBadgeColor` | `'gray'` | One of 8 palette colors. |
|
|
57
|
+
| `size` | `'sm' \| 'md'` | `'sm'` | Compact (xs text) or normal (sm text). |
|
|
58
|
+
| `options` | `IBadgeOptionsPro \| undefined` | `undefined` | Shape, variant, dot, remove. |
|
|
59
|
+
| `class` | `string` | `''` | Forwarded to the host span. |
|
|
60
|
+
|
|
61
|
+
### Outputs
|
|
62
|
+
|
|
63
|
+
| Output | Payload | When |
|
|
64
|
+
| --------- | ------- | --------------------------------- |
|
|
65
|
+
| `removed` | `void` | The remove `×` button is clicked. |
|
|
66
|
+
|
|
67
|
+
## Usage examples
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<!-- Default border, pill, sm, gray -->
|
|
71
|
+
<smartpro-badge text="Badge" />
|
|
72
|
+
|
|
73
|
+
<!-- Success badge -->
|
|
74
|
+
<smartpro-badge text="Active" color="green" [options]="{ withDot: true }" />
|
|
75
|
+
|
|
76
|
+
<!-- Removable indigo tag -->
|
|
77
|
+
<smartpro-badge
|
|
78
|
+
text="React"
|
|
79
|
+
color="indigo"
|
|
80
|
+
[options]="{ withRemove: true }"
|
|
81
|
+
(removed)="onRemove()"
|
|
82
|
+
/>
|
|
83
|
+
|
|
84
|
+
<!-- Flat square, md size -->
|
|
85
|
+
<smartpro-badge
|
|
86
|
+
text="Beta"
|
|
87
|
+
color="blue"
|
|
88
|
+
size="md"
|
|
89
|
+
[options]="{ variant: 'flat', shape: 'square' }"
|
|
90
|
+
/>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Accessibility
|
|
94
|
+
|
|
95
|
+
- Dot SVG uses `aria-hidden="true"`; status meaning carried by text.
|
|
96
|
+
- Remove button uses `aria-label="Remove"`; the close glyph is `aria-hidden`.
|
|
97
|
+
|
|
98
|
+
## File Locations
|
|
99
|
+
|
|
100
|
+
- Wrapper: `packages/shared/angular/src/lib/components/badge/badge.component.ts`
|
|
101
|
+
- Types: `packages/shared/angular/src/lib/components/badge/badge.types.ts`
|
|
102
|
+
- Classes utility: `packages/shared/angular/src/lib/components/badge/badge-classes.util.ts`
|
|
103
|
+
- Layout: `packages/shared/angular/src/lib/components/badge/default/default.component.ts`
|
|
104
|
+
- Stories: `packages/shared/angular/src/lib/components/badge/badge.component.stories.ts`
|
|
105
|
+
- Module entry: `packages/shared/angular/src/lib/components/components.module.ts` (`BADGE_COMPONENTS`)
|
|
106
|
+
|
|
107
|
+
## Peer dependency
|
|
108
|
+
|
|
109
|
+
- `@smartsoft001/angular@^2.123.0` — provides `BadgeBaseComponent`, `IBadgeOptions`, `SmartBadgeColor`.
|
|
110
|
+
- No `@tailwindplus/elements` dep required.
|