@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.
- package/README.md +32 -23
- package/claude-skills/screenshot/SKILL.md +381 -0
- package/dist/browser/SweetlinkBridge.d.ts.map +1 -1
- package/dist/browser/SweetlinkBridge.js +1 -1
- package/dist/browser/SweetlinkBridge.js.map +1 -1
- package/dist/browser/commands/exec.d.ts.map +1 -1
- package/dist/browser/commands/exec.js +5 -2
- package/dist/browser/commands/exec.js.map +1 -1
- package/dist/browser/commands/index.d.ts +2 -2
- package/dist/browser/commands/index.d.ts.map +1 -1
- package/dist/browser/commands/index.js +2 -2
- package/dist/browser/commands/index.js.map +1 -1
- package/dist/browser/commands/outline.js.map +1 -1
- package/dist/browser/commands/schema.d.ts.map +1 -1
- package/dist/browser/commands/schema.js +10 -10
- package/dist/browser/commands/schema.js.map +1 -1
- package/dist/browser/commands/screenshot.d.ts.map +1 -1
- package/dist/browser/commands/screenshot.js +21 -3
- package/dist/browser/commands/screenshot.js.map +1 -1
- package/dist/browser/consoleCapture.d.ts.map +1 -1
- package/dist/browser/consoleCapture.js +3 -1
- package/dist/browser/consoleCapture.js.map +1 -1
- package/dist/browser.js +2 -3
- package/dist/browser.js.map +1 -1
- package/dist/cdp.d.ts +1 -1
- package/dist/cdp.d.ts.map +1 -1
- package/dist/cdp.js +1 -1
- package/dist/cdp.js.map +1 -1
- package/dist/cli/sweetlink.js +479 -256
- package/dist/cli/sweetlink.js.map +1 -1
- package/dist/playwright.d.ts.map +1 -1
- package/dist/playwright.js.map +1 -1
- package/dist/server/handlers/index.d.ts +2 -2
- package/dist/server/handlers/index.d.ts.map +1 -1
- package/dist/server/handlers/index.js +1 -1
- package/dist/server/handlers/index.js.map +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/viewportUtils.js.map +1 -1
- package/package.json +12 -3
- 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.
|
|
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
|
|
3
|
+
* Setup script to symlink shared Claude context and skills to the consuming project.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
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
|
-
*
|
|
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 {
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
const
|
|
65
|
+
function setupContext(claudeDir) {
|
|
66
|
+
const sourceDir = join(packageRoot, 'claude-context');
|
|
67
|
+
if (!existsSync(sourceDir)) return;
|
|
28
68
|
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
57
|
-
|
|
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
|
-
|
|
138
|
+
setup();
|