cssprobe-cli 0.2.16 → 0.2.22
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 +1 -0
- package/dist/cli/commands.js +3 -0
- package/dist/cli/program.js +39 -11
- package/dist/daemon/session.d.ts +1 -0
- package/dist/daemon/session.js +25 -0
- package/dist/engine/analyzer.js +6 -1
- package/dist/engine/renderers/dom-tree.js +1 -1
- package/dist/help.json +5 -2
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -130,6 +130,7 @@ cssprobe-cli inspect body --json | jq '.findings[] | {id, confidence, message}'
|
|
|
130
130
|
| `open [url] --state <file>` | Open with saved cookies + localStorage |
|
|
131
131
|
| `open [url] --viewport 1280x720` | Custom viewport size |
|
|
132
132
|
| `close` | Close browser session |
|
|
133
|
+
| `close --all` | Close all sessions across all workspaces |
|
|
133
134
|
| `status` | Show session status |
|
|
134
135
|
|
|
135
136
|
### CSS Inspection
|
package/dist/cli/commands.js
CHANGED
|
@@ -63,6 +63,9 @@ const close = (0, command_1.declareCommand)({
|
|
|
63
63
|
name: 'close',
|
|
64
64
|
category: 'core',
|
|
65
65
|
description: 'Close the browser session',
|
|
66
|
+
options: z.object({
|
|
67
|
+
all: z.boolean().optional().describe('close all sessions across all workspaces'),
|
|
68
|
+
}),
|
|
66
69
|
});
|
|
67
70
|
const status = (0, command_1.declareCommand)({
|
|
68
71
|
name: 'status',
|
package/dist/cli/program.js
CHANGED
|
@@ -43,7 +43,7 @@ async function program() {
|
|
|
43
43
|
await handleOpen(command, rawArgs, output);
|
|
44
44
|
return;
|
|
45
45
|
case 'close':
|
|
46
|
-
await handleClose(output);
|
|
46
|
+
await handleClose(command, rawArgs, output);
|
|
47
47
|
return;
|
|
48
48
|
case 'status':
|
|
49
49
|
await handleStatus(output);
|
|
@@ -172,19 +172,47 @@ async function waitForSession(timeoutMs) {
|
|
|
172
172
|
}
|
|
173
173
|
return undefined;
|
|
174
174
|
}
|
|
175
|
-
async function handleClose(output) {
|
|
175
|
+
async function handleClose(command, args, output) {
|
|
176
176
|
try {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
177
|
+
const cmdArgs = splitArgs(args);
|
|
178
|
+
const parsed = (0, command_1.parseCommand)(command, cmdArgs);
|
|
179
|
+
if (parsed.all) {
|
|
180
|
+
const sessions = await (0, session_1.listAllSessions)();
|
|
181
|
+
if (sessions.length === 0) {
|
|
182
|
+
output.error('No active sessions found.');
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const results = [];
|
|
186
|
+
for (const session of sessions) {
|
|
187
|
+
try {
|
|
188
|
+
await session.stop();
|
|
189
|
+
results.push({ sessionId: session.name, closed: true });
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
results.push({ sessionId: session.name, closed: false, error: e.message });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (output.json) {
|
|
196
|
+
console.log(JSON.stringify({ closed: results }, null, 2));
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const closedCount = results.filter(r => r.closed).length;
|
|
200
|
+
console.log(`Closed ${closedCount} session(s).`);
|
|
201
|
+
}
|
|
185
202
|
}
|
|
186
203
|
else {
|
|
187
|
-
|
|
204
|
+
const session = await (0, session_1.loadSession)();
|
|
205
|
+
if (!session) {
|
|
206
|
+
output.error('No active session. Run: cssprobe-cli open <url>');
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
await session.stop();
|
|
210
|
+
if (output.json) {
|
|
211
|
+
console.log(JSON.stringify({ closed: true, sessionId: 'default' }, null, 2));
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
console.log('Browser closed.');
|
|
215
|
+
}
|
|
188
216
|
}
|
|
189
217
|
}
|
|
190
218
|
catch (e) {
|
package/dist/daemon/session.d.ts
CHANGED
|
@@ -50,3 +50,4 @@ export declare function createClientInfo(): ClientInfo;
|
|
|
50
50
|
export declare function loadSession(): Promise<Session | undefined>;
|
|
51
51
|
export declare function saveSession(config: SessionConfig): Promise<void>;
|
|
52
52
|
export declare function deleteSession(): Promise<void>;
|
|
53
|
+
export declare function listAllSessions(): Promise<Session[]>;
|
package/dist/daemon/session.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.createClientInfo = createClientInfo;
|
|
|
13
13
|
exports.loadSession = loadSession;
|
|
14
14
|
exports.saveSession = saveSession;
|
|
15
15
|
exports.deleteSession = deleteSession;
|
|
16
|
+
exports.listAllSessions = listAllSessions;
|
|
16
17
|
const crypto_1 = __importDefault(require("crypto"));
|
|
17
18
|
const fs_1 = __importDefault(require("fs"));
|
|
18
19
|
const net_1 = __importDefault(require("net"));
|
|
@@ -229,4 +230,28 @@ async function deleteSession() {
|
|
|
229
230
|
const sessionFile = path_1.default.join(clientInfo.daemonProfilesDir, 'default.session');
|
|
230
231
|
await fs_1.default.promises.unlink(sessionFile).catch(() => { });
|
|
231
232
|
}
|
|
233
|
+
async function listAllSessions() {
|
|
234
|
+
const sessions = [];
|
|
235
|
+
const baseDir = path_1.default.dirname(createClientInfo().daemonProfilesDir);
|
|
236
|
+
try {
|
|
237
|
+
const entries = await fs_1.default.promises.readdir(baseDir, { withFileTypes: true });
|
|
238
|
+
for (const entry of entries) {
|
|
239
|
+
if (!entry.isDirectory())
|
|
240
|
+
continue;
|
|
241
|
+
const sessionFile = path_1.default.join(baseDir, entry.name, 'default.session');
|
|
242
|
+
try {
|
|
243
|
+
const data = await fs_1.default.promises.readFile(sessionFile, 'utf-8');
|
|
244
|
+
const config = JSON.parse(data);
|
|
245
|
+
sessions.push(new Session({ file: sessionFile, config, daemonDir: path_1.default.join(baseDir, entry.name) }));
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// Skip invalid session files
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// Base directory doesn't exist
|
|
254
|
+
}
|
|
255
|
+
return sessions;
|
|
256
|
+
}
|
|
232
257
|
//# sourceMappingURL=session.js.map
|
package/dist/engine/analyzer.js
CHANGED
|
@@ -200,9 +200,14 @@ function analyzeScroll(snapshot) {
|
|
|
200
200
|
message = `${nodeLabel(n)} no overflow, no scroll needed`;
|
|
201
201
|
level = 'info';
|
|
202
202
|
}
|
|
203
|
+
else if (n.props.overflowY === 'visible') {
|
|
204
|
+
id = 'overflow-visible';
|
|
205
|
+
message = `${nodeLabel(n)} content visually overflows (${n.metrics.scrollHeight}>${n.metrics.clientHeight}) but overflow=visible means content is NOT clipped`;
|
|
206
|
+
level = 'info';
|
|
207
|
+
}
|
|
203
208
|
else {
|
|
204
209
|
id = 'overflow-clipped';
|
|
205
|
-
message = `${nodeLabel(n)} content overflows (${n.metrics.scrollHeight}>${n.metrics.clientHeight}) clipped by overflow=${n.props.overflowY}
|
|
210
|
+
message = `${nodeLabel(n)} content overflows (${n.metrics.scrollHeight}>${n.metrics.clientHeight}) clipped by overflow=${n.props.overflowY}`;
|
|
206
211
|
level = 'warning';
|
|
207
212
|
}
|
|
208
213
|
findings.push(makeFinding({
|
|
@@ -7,7 +7,7 @@ function renderNode(node, indent) {
|
|
|
7
7
|
return lines;
|
|
8
8
|
const cls = node.classes.length ? `.${node.classes.join('.')}` : '';
|
|
9
9
|
const id = node.id ? `#${node.id}` : '';
|
|
10
|
-
const repeat = node.repeat ? ` \u00D7${node.repeat}` : '';
|
|
10
|
+
const repeat = node.repeat ? ` \u00D7${node.repeat} (first shown, use :nth-child(N) for others)` : '';
|
|
11
11
|
const m = node.metrics;
|
|
12
12
|
const s = node.shape || {};
|
|
13
13
|
const flag = [];
|
package/dist/help.json
CHANGED
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
]
|
|
15
15
|
},
|
|
16
16
|
"close": {
|
|
17
|
-
"help": "cssprobe-cli close \n\nClose the browser session\n\n\nGlobal options:\n --json output as JSON\n --profile, -p <name> use named profile",
|
|
18
|
-
"flags": {
|
|
17
|
+
"help": "cssprobe-cli close \n\nClose the browser session\n\nOptions:\n --all close all sessions across all workspaces\n\nGlobal options:\n --json output as JSON\n --profile, -p <name> use named profile",
|
|
18
|
+
"flags": {
|
|
19
|
+
"all": "boolean"
|
|
20
|
+
},
|
|
19
21
|
"args": []
|
|
20
22
|
},
|
|
21
23
|
"status": {
|
|
@@ -167,6 +169,7 @@
|
|
|
167
169
|
},
|
|
168
170
|
"booleanOptions": [
|
|
169
171
|
"headed",
|
|
172
|
+
"all",
|
|
170
173
|
"json",
|
|
171
174
|
"brief",
|
|
172
175
|
"layout",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cssprobe-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.22",
|
|
4
4
|
"description": "Runtime CSS probe — inspect layout, colors, backgrounds, fonts and more in a live browser. AI agents and shell automation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
"automation"
|
|
15
15
|
],
|
|
16
16
|
"homepage": "https://github.com/mack-peng/cssprobe-cli#readme",
|
|
17
|
-
"repository":
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/mack-peng/cssprobe-cli.git"
|
|
20
|
+
},
|
|
18
21
|
"license": "MIT",
|
|
19
22
|
"author": "strikingly",
|
|
20
23
|
"main": "dist/index.js",
|