@ytspar/sweetlink 1.10.0 → 1.11.1

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.
Files changed (43) hide show
  1. package/README.md +32 -23
  2. package/claude-skills/screenshot/SKILL.md +381 -0
  3. package/dist/browser/SweetlinkBridge.d.ts.map +1 -1
  4. package/dist/browser/SweetlinkBridge.js +1 -1
  5. package/dist/browser/SweetlinkBridge.js.map +1 -1
  6. package/dist/browser/commands/exec.d.ts.map +1 -1
  7. package/dist/browser/commands/exec.js +5 -2
  8. package/dist/browser/commands/exec.js.map +1 -1
  9. package/dist/browser/commands/index.d.ts +2 -2
  10. package/dist/browser/commands/index.d.ts.map +1 -1
  11. package/dist/browser/commands/index.js +2 -2
  12. package/dist/browser/commands/index.js.map +1 -1
  13. package/dist/browser/commands/outline.js.map +1 -1
  14. package/dist/browser/commands/schema.d.ts.map +1 -1
  15. package/dist/browser/commands/schema.js +10 -10
  16. package/dist/browser/commands/schema.js.map +1 -1
  17. package/dist/browser/commands/screenshot.d.ts.map +1 -1
  18. package/dist/browser/commands/screenshot.js +21 -3
  19. package/dist/browser/commands/screenshot.js.map +1 -1
  20. package/dist/browser/consoleCapture.d.ts.map +1 -1
  21. package/dist/browser/consoleCapture.js +3 -1
  22. package/dist/browser/consoleCapture.js.map +1 -1
  23. package/dist/browser.js +2 -3
  24. package/dist/browser.js.map +1 -1
  25. package/dist/cdp.d.ts +1 -1
  26. package/dist/cdp.d.ts.map +1 -1
  27. package/dist/cdp.js +1 -1
  28. package/dist/cdp.js.map +1 -1
  29. package/dist/cli/sweetlink.js +479 -256
  30. package/dist/cli/sweetlink.js.map +1 -1
  31. package/dist/playwright.d.ts.map +1 -1
  32. package/dist/playwright.js.map +1 -1
  33. package/dist/server/handlers/index.d.ts +2 -2
  34. package/dist/server/handlers/index.d.ts.map +1 -1
  35. package/dist/server/handlers/index.js +1 -1
  36. package/dist/server/handlers/index.js.map +1 -1
  37. package/dist/server/index.js +3 -3
  38. package/dist/server/index.js.map +1 -1
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/types.js.map +1 -1
  41. package/dist/viewportUtils.js.map +1 -1
  42. package/package.json +12 -3
  43. package/scripts/setup-claude-context.mjs +105 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ytspar/sweetlink",
3
- "version": "1.10.0",
3
+ "version": "1.11.1",
4
4
  "description": "Autonomous development toolkit for AI agents - screenshots, DOM queries, console logs, and JavaScript execution via WebSocket and Chrome DevTools Protocol",
5
5
  "keywords": [
6
6
  "autonomous-development",
@@ -89,6 +89,7 @@
89
89
  "files": [
90
90
  "dist",
91
91
  "scripts",
92
+ "claude-skills",
92
93
  "README.md",
93
94
  "LICENSE"
94
95
  ],
@@ -101,31 +102,39 @@
101
102
  "private": false,
102
103
  "peerDependencies": {
103
104
  "axe-core": "^4.0.0",
105
+ "html2canvas-pro": "^2.0.0",
104
106
  "playwright": "^1.40.0",
107
+ "puppeteer-core": "^24.0.0",
105
108
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
106
109
  },
107
110
  "peerDependenciesMeta": {
108
111
  "axe-core": {
109
112
  "optional": true
110
113
  },
114
+ "html2canvas-pro": {
115
+ "optional": true
116
+ },
111
117
  "playwright": {
112
118
  "optional": true
113
119
  },
120
+ "puppeteer-core": {
121
+ "optional": true
122
+ },
114
123
  "vite": {
115
124
  "optional": true
116
125
  }
117
126
  },
118
127
  "dependencies": {
119
128
  "dotenv": "^17.2.4",
120
- "html2canvas-pro": "^2.0.0",
121
- "puppeteer-core": "^24.37.5",
122
129
  "ws": "^8.18.3"
123
130
  },
124
131
  "devDependencies": {
125
132
  "@types/node": "^25.2.3",
126
133
  "@types/ws": "^8.18.1",
127
134
  "axe-core": "^4.10.2",
135
+ "html2canvas-pro": "^2.0.0",
128
136
  "playwright": "^1.58.0",
137
+ "puppeteer-core": "^24.37.5",
129
138
  "typescript": "^5.0.0",
130
139
  "vite": "^7.0.0"
131
140
  },
@@ -1,14 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Setup script to symlink shared Claude context files to the consuming project
3
+ * Setup script to symlink shared Claude context and skills to the consuming project.
4
4
  *
5
- * This script runs as postinstall and creates symlinks from the project's
6
- * .claude/context/ directory to the shared context files in this package.
5
+ * Can be run directly (`node scripts/setup-claude-context.mjs`) or via CLI (`pnpm sweetlink setup`).
7
6
  *
8
- * Symlinks are relative paths so they work across different environments.
7
+ * Creates relative symlinks so they work across different environments.
8
+ *
9
+ * What gets linked:
10
+ * - .claude/context/ ← context files from this package's claude-context/
11
+ * - .claude/skills/ ← skill directories from this package's claude-skills/
9
12
  */
10
13
 
11
- import { existsSync, mkdirSync, readlinkSync, symlinkSync, unlinkSync } from 'fs';
14
+ import {
15
+ existsSync,
16
+ lstatSync,
17
+ mkdirSync,
18
+ readdirSync,
19
+ readlinkSync,
20
+ symlinkSync,
21
+ unlinkSync,
22
+ } from 'fs';
12
23
  import { dirname, join, relative } from 'path';
13
24
  import { fileURLToPath } from 'url';
14
25
 
@@ -20,82 +31,108 @@ const packageRoot = join(__dirname, '..');
20
31
  const nodeModules = join(packageRoot, '..', '..', '..');
21
32
  const projectRoot = join(nodeModules, '..');
22
33
 
23
- // Source: this package's claude-context/
24
- const sourceDir = join(packageRoot, 'claude-context');
34
+ /**
35
+ * Create a relative symlink, skipping if already correct.
36
+ * Won't overwrite non-symlink files.
37
+ */
38
+ function linkOne(sourcePath, targetPath, label) {
39
+ const targetDir = dirname(targetPath);
40
+ const relativePath = relative(targetDir, sourcePath);
41
+
42
+ if (existsSync(targetPath) || lstatSync(targetPath, { throwIfNoEntry: false })) {
43
+ try {
44
+ const currentLink = readlinkSync(targetPath);
45
+ if (currentLink === relativePath) {
46
+ return; // Already correct
47
+ }
48
+ // Remove incorrect symlink
49
+ unlinkSync(targetPath);
50
+ } catch {
51
+ // Not a symlink — don't overwrite user's files
52
+ console.log(` [skip] ${label} — file exists (not a symlink)`);
53
+ return;
54
+ }
55
+ }
56
+
57
+ try {
58
+ symlinkSync(relativePath, targetPath);
59
+ console.log(` [link] ${label}`);
60
+ } catch (err) {
61
+ console.error(` [error] ${label} — ${err.message}`);
62
+ }
63
+ }
25
64
 
26
- // Target: project's .claude/context/
27
- const targetDir = join(projectRoot, '.claude', 'context');
65
+ function setupContext(claudeDir) {
66
+ const sourceDir = join(packageRoot, 'claude-context');
67
+ if (!existsSync(sourceDir)) return;
28
68
 
29
- // Files to symlink (add more as needed)
30
- const filesToLink = [
31
- 'ui-verification-mandate.md',
32
- 'debugging-protocol.md',
33
- 'sweetlink-architecture.md',
34
- 'component-development-guide.md',
35
- ];
69
+ const targetDir = join(claudeDir, 'context');
70
+ mkdirSync(targetDir, { recursive: true });
36
71
 
37
- function setupSymlinks() {
38
- // Skip if running in the tools repo itself (during development)
39
- if (projectRoot.includes('ytspar/devbar')) {
40
- return;
72
+ const files = readdirSync(sourceDir).filter((f) => f.endsWith('.md'));
73
+ if (files.length === 0) return;
74
+
75
+ console.log('[@ytspar/sweetlink] Setting up Claude context symlinks...');
76
+ for (const file of files) {
77
+ linkOne(join(sourceDir, file), join(targetDir, file), file);
78
+ }
79
+ }
80
+
81
+ function setupSkills(claudeDir) {
82
+ const sourceDir = join(packageRoot, 'claude-skills');
83
+ if (!existsSync(sourceDir)) return;
84
+
85
+ const targetDir = join(claudeDir, 'skills');
86
+ mkdirSync(targetDir, { recursive: true });
87
+
88
+ // Each subdirectory in claude-skills/ is a skill
89
+ const skills = readdirSync(sourceDir, { withFileTypes: true })
90
+ .filter((d) => d.isDirectory())
91
+ .map((d) => d.name);
92
+
93
+ if (skills.length === 0) return;
94
+
95
+ console.log('[@ytspar/sweetlink] Setting up Claude skill symlinks...');
96
+
97
+ // If .claude/skills is itself a symlink (e.g. to a shared tools repo),
98
+ // we can't add entries inside it. Warn and provide instructions.
99
+ try {
100
+ const stat = lstatSync(targetDir);
101
+ if (stat.isSymbolicLink()) {
102
+ const linkTarget = readlinkSync(targetDir);
103
+ console.log(` [info] .claude/skills is a symlink → ${linkTarget}`);
104
+ console.log(
105
+ ` [info] Skills from @ytspar/sweetlink should be symlinked inside that directory.`
106
+ );
107
+ console.log(
108
+ ` [info] Run: cd ${linkTarget} && ln -sf ${relative(linkTarget, sourceDir)}/<skill> .`
109
+ );
110
+ return;
111
+ }
112
+ } catch {
113
+ // Doesn't exist yet, will be created above
41
114
  }
42
115
 
43
- // Check if source directory exists
44
- if (!existsSync(sourceDir)) {
45
- // claude-context not built yet, skip silently
116
+ for (const skill of skills) {
117
+ linkOne(join(sourceDir, skill), join(targetDir, skill), `skills/${skill}`);
118
+ }
119
+ }
120
+
121
+ function setup() {
122
+ // Skip if running inside the devbar repo itself (development)
123
+ if (projectRoot.includes('ytspar/devbar')) {
124
+ console.log('[@ytspar/sweetlink] Skipping setup (running inside devbar repo)');
46
125
  return;
47
126
  }
48
127
 
49
- // Check if project has .claude directory (indicates Claude Code project)
50
128
  const claudeDir = join(projectRoot, '.claude');
51
129
  if (!existsSync(claudeDir)) {
52
130
  // Not a Claude Code project, skip silently
53
131
  return;
54
132
  }
55
133
 
56
- // Ensure target directory exists
57
- if (!existsSync(targetDir)) {
58
- mkdirSync(targetDir, { recursive: true });
59
- }
60
-
61
- console.log('[@ytspar/sweetlink] Setting up Claude context symlinks...');
62
-
63
- for (const file of filesToLink) {
64
- const sourcePath = join(sourceDir, file);
65
- const targetPath = join(targetDir, file);
66
-
67
- // Skip if source doesn't exist
68
- if (!existsSync(sourcePath)) {
69
- continue;
70
- }
71
-
72
- // Calculate relative path for symlink
73
- const relativePath = relative(targetDir, sourcePath);
74
-
75
- // Check if symlink already exists and points to correct location
76
- if (existsSync(targetPath)) {
77
- try {
78
- const currentLink = readlinkSync(targetPath);
79
- if (currentLink === relativePath) {
80
- continue; // Already correct
81
- }
82
- // Remove incorrect symlink
83
- unlinkSync(targetPath);
84
- } catch {
85
- // Not a symlink - don't overwrite user's files
86
- console.log(` [skip] ${file} - file exists (not a symlink)`);
87
- continue;
88
- }
89
- }
90
-
91
- // Create symlink
92
- try {
93
- symlinkSync(relativePath, targetPath);
94
- console.log(` [link] ${file}`);
95
- } catch (err) {
96
- console.error(` [error] ${file} - ${err.message}`);
97
- }
98
- }
134
+ setupContext(claudeDir);
135
+ setupSkills(claudeDir);
99
136
  }
100
137
 
101
- setupSymlinks();
138
+ setup();