mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 14:16:28 +03:00
Two architectural changes that make the live variant mode self-contained:
1. SSE replaces WebSocket: the server now uses Server-Sent Events for
server→browser push and regular fetch POST for browser→server
events. This eliminates the ws npm dependency entirely. The live
server is now zero-dependency pure Node.js (http, crypto, fs, net).
Browser: EventSource replaces WebSocket. sendEvent() uses fetch POST.
Server: GET /events returns SSE stream, POST /events receives browser
events. All other endpoints (poll, source, health, stop) unchanged.
2. Scripts moved to source/skills/impeccable/scripts/: live-server.mjs,
live-poll.mjs, live-wrap.mjs, live-browser.js are now part of the
skill itself. Users who install the skill via npx skills get the live
mode without needing npm install impeccable separately.
The skill reference uses {{scripts_path}}/live-server.mjs etc.
The CLI (bin/cli.js) delegates to the skill scripts as a convenience.
Removed ws from package.json dependencies.
The old src/live/ files remain as the development copy. The build system
syncs source/skills/ to all harness dirs (11 providers).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
76 lines
3.0 KiB
JavaScript
Executable File
76 lines
3.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Impeccable CLI
|
|
*
|
|
* Usage:
|
|
* npx impeccable detect [file-or-dir-or-url...]
|
|
* npx impeccable live [--port=PORT]
|
|
* npx impeccable live stop
|
|
* npx impeccable skills help|install|update
|
|
* npx impeccable --help
|
|
*/
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
import { join, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const args = process.argv.slice(2);
|
|
const command = args[0];
|
|
|
|
if (!command || command === '--help' || command === '-h') {
|
|
console.log(`Usage: impeccable <command> [options]
|
|
|
|
Commands:
|
|
detect [file-or-dir-or-url...] Scan for UI anti-patterns and design quality issues
|
|
live [--port=PORT] Start live variant server (element picker + variant cycling)
|
|
live stop Stop a running live server
|
|
poll Wait for a browser event from the live server
|
|
poll --reply <id> <status> Reply to a pending event (done, error)
|
|
wrap --id ID --count N --query Q Find element in source and create variant wrapper
|
|
skills help List all available skills and commands
|
|
skills install Install impeccable skills into your project
|
|
skills update Update skills to the latest version
|
|
skills check Check if skill updates are available
|
|
|
|
Options:
|
|
--help Show this help message
|
|
--version Show version number
|
|
|
|
Run 'impeccable <command> --help' for command-specific options.`);
|
|
process.exit(0);
|
|
}
|
|
|
|
if (command === '--version' || command === '-v') {
|
|
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
|
|
console.log(pkg.version);
|
|
process.exit(0);
|
|
}
|
|
|
|
if (command === 'detect') {
|
|
process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
|
|
const { detectCli } = await import('../src/detect-antipatterns.mjs');
|
|
await detectCli();
|
|
} else if (command === 'live') {
|
|
// Delegate to the self-contained skill script (also works via node scripts_path/live-server.mjs)
|
|
process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
|
|
await import('../source/skills/impeccable/scripts/live-server.mjs');
|
|
} else if (command === 'poll') {
|
|
process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
|
|
const { pollCli } = await import('../source/skills/impeccable/scripts/live-poll.mjs');
|
|
await pollCli();
|
|
} else if (command === 'wrap') {
|
|
process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
|
|
const { wrapCli } = await import('../source/skills/impeccable/scripts/live-wrap.mjs');
|
|
await wrapCli();
|
|
} else if (command === 'skills') {
|
|
const { run } = await import('./commands/skills.mjs');
|
|
await run(args.slice(1));
|
|
} else {
|
|
// Default: treat as detect arguments (allow `npx impeccable src/` shorthand)
|
|
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
const { detectCli } = await import('../src/detect-antipatterns.mjs');
|
|
await detectCli();
|
|
}
|