@skilly-hand/skilly-hand 0.11.1 → 0.13.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/CHANGELOG.md CHANGED
@@ -5,11 +5,32 @@ All notable changes to this project are documented in this file.
5
5
  ## [Unreleased]
6
6
 
7
7
  ### Added
8
- - _None._
8
+ - Figma plugin detection support
9
+ - New test fixtures for figma-plugin projects
9
10
 
10
11
  ### Changed
12
+ - Improved project detection logic with configExists helper function
13
+ - Updated skill recommendations for React, Next.js, Angular, Vite, and other technologies
14
+ - Changed figma-mcp-0to1 skill detectors from "always" to "figma"
15
+
16
+ ### Fixed
17
+ - _None._
18
+
19
+ ### Removed
11
20
  - _None._
12
21
 
22
+ ## [0.12.0] - 2026-04-05
23
+ [View on npm](https://www.npmjs.com/package/@skilly-hand/skilly-hand/v/0.12.0)
24
+
25
+ ### Added
26
+ - Added `SECURITY.md` policy for vulnerability reporting and response procedures.
27
+ - Added `security-check` script to scan source code for exposed secrets and API keys.
28
+ - Integrated security scanning into the `verify:publish` pipeline to catch credential leaks before release.
29
+
30
+ ### Changed
31
+ - Updated `.gitignore` to include `.env*` pattern for environment variable files.
32
+ - Updated `verify-packlist.mjs` to whitelist `SECURITY.md` in npm package.
33
+
13
34
  ### Fixed
14
35
  - _None._
15
36
 
package/SECURITY.md ADDED
@@ -0,0 +1,37 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ Only the latest version published on npm is supported with security fixes. No backport patches are issued for older versions.
6
+
7
+ ## Reporting a Vulnerability
8
+
9
+ If you discover a security vulnerability, please **do not open a public GitHub issue**. Instead, use [GitHub Security Advisories](https://github.com/Davecelot/skilly-hand/security/advisories/new) to report it privately.
10
+
11
+ Include as much detail as possible:
12
+
13
+ - A description of the vulnerability and its potential impact
14
+ - Steps to reproduce or a minimal proof-of-concept
15
+ - The version of `@skilly-hand/skilly-hand` you are using
16
+ - Your environment (OS, Node.js version)
17
+
18
+ ## Response Timeline
19
+
20
+ This is a solo-maintained project. I will do my best to:
21
+
22
+ - Acknowledge the report within a few days
23
+ - Triage and provide an estimated fix timeline once reviewed
24
+ - Publish a patch and disclose the issue publicly after the fix ships
25
+
26
+ ## Out of Scope
27
+
28
+ The following are not considered security vulnerabilities in this project:
29
+
30
+ - Content inside skill `.md` files — these are prose instructions for AI agents, not executable code
31
+ - Vulnerabilities in third-party dependencies — please report those directly to the upstream package maintainers
32
+ - Issues that require physical access to the machine running the CLI
33
+
34
+ ## Please Do Not
35
+
36
+ - Disclose the vulnerability publicly before a fix has been released
37
+ - Open a public GitHub issue to report security concerns
@@ -4,7 +4,7 @@
4
4
  "description": "Guide users from Figma MCP installation and authentication through first canvas creation, with function-level tool coverage and operational recovery patterns.",
5
5
  "portable": true,
6
6
  "tags": ["figma", "mcp", "workflow", "design"],
7
- "detectors": ["always"],
7
+ "detectors": ["figma"],
8
8
  "detectionTriggers": ["manual"],
9
9
  "installsFor": ["all"],
10
10
  "agentSupport": ["codex", "claude", "cursor", "gemini", "copilot", "antigravity", "windsurf", "trae"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skilly-hand/skilly-hand",
3
- "version": "0.11.1",
3
+ "version": "0.13.0",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -14,7 +14,8 @@
14
14
  "packages",
15
15
  "README.md",
16
16
  "CHANGELOG.md",
17
- "LICENSE"
17
+ "LICENSE",
18
+ "SECURITY.md"
18
19
  ],
19
20
  "workspaces": [
20
21
  "packages/*"
@@ -28,8 +29,9 @@
28
29
  "catalog:sync": "node ./scripts/sync-catalog-readme.mjs",
29
30
  "agentic:self:sync": "node ./scripts/sync-self-agentic.mjs",
30
31
  "test": "node --test tests/*.test.js",
32
+ "security:check": "node ./scripts/security-check.mjs",
31
33
  "verify:packlist": "node ./scripts/verify-packlist.mjs",
32
- "verify:publish": "npm run catalog:check && npm test && npm run verify:packlist",
34
+ "verify:publish": "npm run security:check && npm run catalog:check && npm test && npm run verify:packlist",
33
35
  "publish:prepare": "npm run verify:publish && npm pack --dry-run --json",
34
36
  "publish:otp": "node ./scripts/publish-with-otp.mjs",
35
37
  "publish:next": "node ./scripts/publish-with-otp.mjs --tag next",
@@ -10,6 +10,13 @@ async function pathExists(filePath) {
10
10
  }
11
11
  }
12
12
 
13
+ async function configExists(cwd, base, extensions = ["js", "ts"]) {
14
+ for (const ext of extensions) {
15
+ if (await pathExists(path.join(cwd, `${base}.${ext}`))) return true;
16
+ }
17
+ return false;
18
+ }
19
+
13
20
  async function readJson(filePath) {
14
21
  if (!(await pathExists(filePath))) {
15
22
  return null;
@@ -41,14 +48,10 @@ export async function detectProject(cwd) {
41
48
  const packageJson = await readJson(path.join(cwd, "package.json"));
42
49
  const tsconfigExists = await pathExists(path.join(cwd, "tsconfig.json"));
43
50
  const angularJsonExists = await pathExists(path.join(cwd, "angular.json"));
44
- const viteConfigExists =
45
- (await pathExists(path.join(cwd, "vite.config.js"))) ||
46
- (await pathExists(path.join(cwd, "vite.config.ts")));
47
- const nextConfigExists =
48
- (await pathExists(path.join(cwd, "next.config.js"))) ||
49
- (await pathExists(path.join(cwd, "next.config.mjs"))) ||
50
- (await pathExists(path.join(cwd, "next.config.ts")));
51
+ const viteConfigExists = await configExists(cwd, "vite.config");
52
+ const nextConfigExists = await configExists(cwd, "next.config", ["js", "mjs", "ts"]);
51
53
  const storybookDirExists = await pathExists(path.join(cwd, ".storybook"));
54
+ const figmaConfigExists = await configExists(cwd, "figma.config");
52
55
  const results = [];
53
56
 
54
57
  if (packageJson) {
@@ -56,27 +59,34 @@ export async function detectProject(cwd) {
56
59
  technology: "nodejs",
57
60
  confidence: 1,
58
61
  reasons: ["Found package.json"],
59
- recommendedSkillIds: ["token-optimizer", "commit-writer", "pr-writer", "spec-driven-development"]
62
+ recommendedSkillIds: [
63
+ "token-optimizer",
64
+ "spec-driven-development",
65
+ "review-rangers",
66
+ "project-teacher"
67
+ ]
60
68
  });
61
69
  }
62
70
 
63
- if (packageJson || tsconfigExists) {
71
+ const deps = packageJson ? { ...packageJson.dependencies, ...packageJson.devDependencies } : {};
72
+
73
+ if (tsconfigExists || "typescript" in deps) {
64
74
  addDetection(results, {
65
75
  technology: "typescript",
66
- confidence: tsconfigExists ? 0.95 : 0.7,
67
- reasons: tsconfigExists ? ["Found tsconfig.json"] : ["TypeScript inferred from project layout"],
76
+ confidence: tsconfigExists ? 0.95 : 0.9,
77
+ reasons: tsconfigExists
78
+ ? ["Found tsconfig.json"]
79
+ : ['Dependency "typescript" found in package.json'],
68
80
  recommendedSkillIds: ["token-optimizer"]
69
81
  });
70
82
  }
71
83
 
72
- const deps = packageJson ? { ...packageJson.dependencies, ...packageJson.devDependencies } : {};
73
-
74
84
  if ("react" in deps) {
75
85
  addDetection(results, {
76
86
  technology: "react",
77
87
  confidence: 0.95,
78
88
  reasons: ['Dependency "react" found in package.json'],
79
- recommendedSkillIds: ["accessibility-audit", "storybook-component-stories", "playwright-ui-testing"]
89
+ recommendedSkillIds: ["accessibility-audit", "react-guidelines", "frontend-design"]
80
90
  });
81
91
  }
82
92
 
@@ -84,8 +94,15 @@ export async function detectProject(cwd) {
84
94
  addDetection(results, {
85
95
  technology: "nextjs",
86
96
  confidence: nextConfigExists ? 1 : 0.9,
87
- reasons: nextConfigExists ? ["Found next.config.*"] : ['Dependency "next" found in package.json'],
88
- recommendedSkillIds: ["accessibility-audit", "playwright-ui-testing", "spec-driven-development"]
97
+ reasons: nextConfigExists
98
+ ? ["Found next.config.*"]
99
+ : ['Dependency "next" found in package.json'],
100
+ recommendedSkillIds: [
101
+ "accessibility-audit",
102
+ "spec-driven-development",
103
+ "react-guidelines",
104
+ "frontend-design"
105
+ ]
89
106
  });
90
107
  }
91
108
 
@@ -93,12 +110,14 @@ export async function detectProject(cwd) {
93
110
  addDetection(results, {
94
111
  technology: "angular",
95
112
  confidence: angularJsonExists ? 1 : 0.95,
96
- reasons: angularJsonExists ? ["Found angular.json"] : ['Dependency "@angular/core" found in package.json'],
113
+ reasons: angularJsonExists
114
+ ? ["Found angular.json"]
115
+ : ['Dependency "@angular/core" found in package.json'],
97
116
  recommendedSkillIds: [
98
117
  "angular-guidelines",
99
- "vitest-component-testing",
100
- "storybook-component-stories",
101
- "accessibility-audit"
118
+ "accessibility-audit",
119
+ "frontend-design",
120
+ "test-driven-development"
102
121
  ]
103
122
  });
104
123
  }
@@ -107,8 +126,10 @@ export async function detectProject(cwd) {
107
126
  addDetection(results, {
108
127
  technology: "vite",
109
128
  confidence: viteConfigExists ? 1 : 0.9,
110
- reasons: viteConfigExists ? ["Found vite.config.*"] : ['Dependency "vite" found in package.json'],
111
- recommendedSkillIds: ["storybook-component-stories", "playwright-ui-testing"]
129
+ reasons: viteConfigExists
130
+ ? ["Found vite.config.*"]
131
+ : ['Dependency "vite" found in package.json'],
132
+ recommendedSkillIds: ["frontend-design"]
112
133
  });
113
134
  }
114
135
 
@@ -117,7 +138,7 @@ export async function detectProject(cwd) {
117
138
  technology: "playwright",
118
139
  confidence: 0.95,
119
140
  reasons: ['Dependency "@playwright/test" found in package.json'],
120
- recommendedSkillIds: ["playwright-ui-testing"]
141
+ recommendedSkillIds: ["test-driven-development"]
121
142
  });
122
143
  }
123
144
 
@@ -126,16 +147,19 @@ export async function detectProject(cwd) {
126
147
  technology: "vitest",
127
148
  confidence: 0.95,
128
149
  reasons: ['Dependency "vitest" found in package.json'],
129
- recommendedSkillIds: ["vitest-component-testing"]
150
+ recommendedSkillIds: ["test-driven-development"]
130
151
  });
131
152
  }
132
153
 
133
- if ("tailwindcss" in deps || (await pathExists(path.join(cwd, "tailwind.config.js"))) || (await pathExists(path.join(cwd, "tailwind.config.ts")))) {
154
+ const tailwindConfigExists = await configExists(cwd, "tailwind.config");
155
+ if ("tailwindcss" in deps || tailwindConfigExists) {
134
156
  addDetection(results, {
135
157
  technology: "tailwindcss",
136
- confidence: 0.9,
137
- reasons: ['Dependency "tailwindcss" or config file found'],
138
- recommendedSkillIds: ["accessibility-audit", "css-modules"]
158
+ confidence: tailwindConfigExists ? 1 : 0.9,
159
+ reasons: tailwindConfigExists
160
+ ? ["Found tailwind.config.*"]
161
+ : ['Dependency "tailwindcss" found in package.json'],
162
+ recommendedSkillIds: ["accessibility-audit", "frontend-design"]
139
163
  });
140
164
  }
141
165
 
@@ -143,8 +167,23 @@ export async function detectProject(cwd) {
143
167
  addDetection(results, {
144
168
  technology: "storybook",
145
169
  confidence: storybookDirExists ? 1 : 0.9,
146
- reasons: storybookDirExists ? ["Found .storybook directory"] : ["Storybook dependency found"],
147
- recommendedSkillIds: ["storybook-component-stories", "playwright-ui-testing"]
170
+ reasons: storybookDirExists
171
+ ? ["Found .storybook directory"]
172
+ : ["Storybook dependency found in package.json"],
173
+ recommendedSkillIds: ["frontend-design"]
174
+ });
175
+ }
176
+
177
+ const figmaDeps = ["@figma/plugin-typings", "@figma/widget-typings", "figma-api"];
178
+ const figmaDepFound = figmaDeps.find((dep) => dep in deps);
179
+ if (figmaConfigExists || figmaDepFound) {
180
+ addDetection(results, {
181
+ technology: "figma",
182
+ confidence: figmaConfigExists ? 1 : 0.95,
183
+ reasons: figmaConfigExists
184
+ ? ["Found figma.config.*"]
185
+ : [`Dependency "${figmaDepFound}" found in package.json`],
186
+ recommendedSkillIds: ["figma-mcp-0to1"]
148
187
  });
149
188
  }
150
189
 
@@ -152,7 +191,20 @@ export async function detectProject(cwd) {
152
191
  }
153
192
 
154
193
  export async function inspectProjectFiles(cwd) {
155
- const probes = ["package.json", "tsconfig.json", "angular.json", ".storybook"];
194
+ const probes = [
195
+ "package.json",
196
+ "tsconfig.json",
197
+ "angular.json",
198
+ ".storybook",
199
+ "vite.config.js",
200
+ "vite.config.ts",
201
+ "next.config.js",
202
+ "next.config.mjs",
203
+ "tailwind.config.js",
204
+ "tailwind.config.ts",
205
+ "figma.config.js",
206
+ "figma.config.ts"
207
+ ];
156
208
  const statuses = [];
157
209
 
158
210
  for (const probe of probes) {