@web-auto/camo 0.2.0 → 0.2.2
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/LICENSE +21 -21
- package/README.md +586 -586
- package/bin/browser-service.mjs +11 -11
- package/bin/camo.mjs +22 -22
- package/package.json +48 -48
- package/scripts/build.mjs +19 -19
- package/scripts/bump-version.mjs +34 -34
- package/scripts/check-file-size.mjs +80 -80
- package/scripts/file-size-policy.json +12 -2
- package/scripts/install.mjs +76 -76
- package/scripts/release.sh +54 -54
- package/src/autoscript/action-providers/index.mjs +6 -6
- package/src/autoscript/impact-engine.mjs +78 -78
- package/src/autoscript/runtime.mjs +1017 -1017
- package/src/autoscript/schema.mjs +376 -376
- package/src/cli.mjs +405 -405
- package/src/commands/attach.mjs +141 -141
- package/src/commands/autoscript.mjs +1011 -1011
- package/src/commands/browser.mjs +1255 -1255
- package/src/commands/container.mjs +401 -401
- package/src/commands/cookies.mjs +69 -69
- package/src/commands/create.mjs +98 -98
- package/src/commands/devtools.mjs +349 -349
- package/src/commands/events.mjs +152 -152
- package/src/commands/highlight-mode.mjs +24 -24
- package/src/commands/init.mjs +68 -68
- package/src/commands/lifecycle.mjs +275 -275
- package/src/commands/mouse.mjs +45 -45
- package/src/commands/profile.mjs +46 -46
- package/src/commands/record.mjs +115 -115
- package/src/commands/system.mjs +14 -14
- package/src/commands/window.mjs +123 -123
- package/src/container/change-notifier.mjs +362 -362
- package/src/container/element-filter.mjs +143 -143
- package/src/container/index.mjs +3 -3
- package/src/container/runtime-core/checkpoint.mjs +209 -209
- package/src/container/runtime-core/index.mjs +21 -21
- package/src/container/runtime-core/operations/index.mjs +774 -774
- package/src/container/runtime-core/operations/selector-scripts.mjs +277 -277
- package/src/container/runtime-core/operations/tab-pool.mjs +746 -746
- package/src/container/runtime-core/operations/viewport.mjs +189 -189
- package/src/container/runtime-core/search.mjs +190 -190
- package/src/container/runtime-core/subscription.mjs +224 -224
- package/src/container/runtime-core/utils.mjs +94 -94
- package/src/container/runtime-core/validation.mjs +127 -127
- package/src/container/runtime-core.mjs +1 -1
- package/src/container/subscription-registry.mjs +459 -459
- package/src/core/actions.mjs +561 -561
- package/src/core/browser.mjs +266 -266
- package/src/core/index.mjs +52 -52
- package/src/core/utils.mjs +91 -91
- package/src/events/daemon-entry.mjs +33 -33
- package/src/events/daemon.mjs +80 -80
- package/src/events/progress-log.mjs +109 -109
- package/src/events/ws-server.mjs +239 -239
- package/src/lib/client.mjs +200 -200
- package/src/lifecycle/cleanup.mjs +83 -83
- package/src/lifecycle/lock.mjs +126 -126
- package/src/lifecycle/session-registry.mjs +279 -279
- package/src/lifecycle/session-view.mjs +76 -76
- package/src/lifecycle/session-watchdog.mjs +281 -281
- package/src/services/browser-service/index.js +671 -671
- package/src/services/browser-service/internal/BrowserSession.input.test.js +389 -389
- package/src/services/browser-service/internal/BrowserSession.js +325 -304
- package/src/services/browser-service/internal/ElementRegistry.js +60 -60
- package/src/services/browser-service/internal/ProfileLock.js +84 -84
- package/src/services/browser-service/internal/SessionManager.js +184 -184
- package/src/services/browser-service/internal/SessionManager.test.js +39 -39
- package/src/services/browser-service/internal/browser-session/cookies.js +144 -144
- package/src/services/browser-service/internal/browser-session/input-ops.js +222 -222
- package/src/services/browser-service/internal/browser-session/input-pipeline.js +144 -144
- package/src/services/browser-service/internal/browser-session/logging.js +46 -46
- package/src/services/browser-service/internal/browser-session/navigation.js +38 -38
- package/src/services/browser-service/internal/browser-session/page-hooks.js +442 -442
- package/src/services/browser-service/internal/browser-session/page-management.js +302 -302
- package/src/services/browser-service/internal/browser-session/page-management.test.js +148 -148
- package/src/services/browser-service/internal/browser-session/recording.js +198 -198
- package/src/services/browser-service/internal/browser-session/runtime-events.js +61 -61
- package/src/services/browser-service/internal/browser-session/session-core.js +84 -84
- package/src/services/browser-service/internal/browser-session/session-state.js +38 -38
- package/src/services/browser-service/internal/browser-session/types.js +14 -14
- package/src/services/browser-service/internal/browser-session/utils.js +95 -95
- package/src/services/browser-service/internal/browser-session/viewport-manager.js +46 -46
- package/src/services/browser-service/internal/browser-session/viewport.js +215 -215
- package/src/services/browser-service/internal/container-matcher.js +851 -851
- package/src/services/browser-service/internal/container-registry.js +182 -182
- package/src/services/browser-service/internal/engine-manager.js +259 -259
- package/src/services/browser-service/internal/fingerprint.js +203 -203
- package/src/services/browser-service/internal/heartbeat.js +137 -137
- package/src/services/browser-service/internal/logging.js +46 -46
- package/src/services/browser-service/internal/page-runtime/runtime.js +1317 -1317
- package/src/services/browser-service/internal/pageRuntime.js +28 -28
- package/src/services/browser-service/internal/runtimeInjector.js +31 -31
- package/src/services/browser-service/internal/service-process-logger.js +140 -140
- package/src/services/browser-service/internal/state-bus.js +45 -45
- package/src/services/browser-service/internal/storage-paths.js +42 -42
- package/src/services/browser-service/internal/ws-server.js +1194 -1194
- package/src/services/browser-service/internal/ws-server.test.js +58 -58
- package/src/services/browser-service/server.mjs +6 -6
- package/src/services/controller/cli-bridge.js +93 -93
- package/src/services/controller/container-index.js +50 -50
- package/src/services/controller/container-storage.js +36 -36
- package/src/services/controller/controller-actions.js +207 -207
- package/src/services/controller/controller.js +1138 -1138
- package/src/services/controller/selectors.js +54 -54
- package/src/services/controller/transport.js +125 -125
- package/src/utils/args.mjs +26 -26
- package/src/utils/browser-service.mjs +544 -544
- package/src/utils/command-log.mjs +64 -64
- package/src/utils/config.mjs +214 -214
- package/src/utils/fingerprint.mjs +181 -181
- package/src/utils/help.mjs +216 -216
- package/src/utils/js-policy.mjs +13 -13
- package/src/utils/ws-client.mjs +30 -30
package/bin/browser-service.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { dirname, resolve } from 'node:path';
|
|
4
|
-
|
|
5
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
const entry = resolve(__dirname, '../src/services/browser-service/index.js');
|
|
7
|
-
|
|
8
|
-
const mod = await import(entry);
|
|
9
|
-
if (typeof mod.runBrowserServiceCli === 'function') {
|
|
10
|
-
await mod.runBrowserServiceCli(process.argv);
|
|
11
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const entry = resolve(__dirname, '../src/services/browser-service/index.js');
|
|
7
|
+
|
|
8
|
+
const mod = await import(entry);
|
|
9
|
+
if (typeof mod.runBrowserServiceCli === 'function') {
|
|
10
|
+
await mod.runBrowserServiceCli(process.argv);
|
|
11
|
+
}
|
package/bin/camo.mjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { spawn } from 'node:child_process';
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const cliPath = path.join(__dirname, '..', 'src', 'cli.mjs');
|
|
8
|
-
|
|
9
|
-
// Delegate to the modular CLI
|
|
10
|
-
const child = spawn(process.execPath, [cliPath, ...process.argv.slice(2)], {
|
|
11
|
-
stdio: 'inherit',
|
|
12
|
-
env: process.env,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
child.on('error', (err) => {
|
|
16
|
-
console.error(`Failed to start camo: ${err.message}`);
|
|
17
|
-
process.exit(1);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
child.on('exit', (code) => {
|
|
21
|
-
process.exit(code || 0);
|
|
22
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const cliPath = path.join(__dirname, '..', 'src', 'cli.mjs');
|
|
8
|
+
|
|
9
|
+
// Delegate to the modular CLI
|
|
10
|
+
const child = spawn(process.execPath, [cliPath, ...process.argv.slice(2)], {
|
|
11
|
+
stdio: 'inherit',
|
|
12
|
+
env: process.env,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
child.on('error', (err) => {
|
|
16
|
+
console.error(`Failed to start camo: ${err.message}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
child.on('exit', (code) => {
|
|
21
|
+
process.exit(code || 0);
|
|
22
|
+
});
|
package/package.json
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
2
|
"name": "@web-auto/camo",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Camoufox Browser CLI - Cross-platform browser automation",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"camo": "./bin/camo.mjs",
|
|
8
|
-
"browser-service": "./bin/browser-service.mjs"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"bin/",
|
|
12
|
-
"src/",
|
|
13
|
-
"scripts/",
|
|
14
|
-
"README.md",
|
|
15
|
-
"LICENSE"
|
|
16
|
-
],
|
|
17
|
-
"scripts": {
|
|
18
|
-
"build": "node scripts/build.mjs",
|
|
19
|
-
"check:file-size": "node scripts/check-file-size.mjs",
|
|
20
|
-
"test": "node --test 'tests/**/*.test.mjs'",
|
|
21
|
-
"test:coverage": "c8 --reporter=text --reporter=lcov node --test 'tests/**/*.test.mjs'",
|
|
22
|
-
"test:coverage:modes": "c8 --all --check-coverage --lines 90 --functions 90 --branches 90 --statements 90 --include src/commands/record.mjs --include src/commands/highlight-mode.mjs --include src/container/runtime-core/operations/selector-scripts.mjs node --test tests/unit/commands/record.test.mjs tests/unit/commands/highlight-mode.test.mjs tests/unit/container/selector-scripts.test.mjs tests/unit/commands/browser.test.mjs",
|
|
23
|
-
"version:bump": "node scripts/bump-version.mjs",
|
|
24
|
-
"install:global": "npm run build && npm install -g .",
|
|
25
|
-
"uninstall:global": "npm uninstall -g @web-auto/camo",
|
|
26
|
-
"build:global": "npm run build && npm test && npm install -g ."
|
|
27
|
-
},
|
|
28
|
-
"keywords": [
|
|
29
|
-
"browser",
|
|
30
|
-
"automation",
|
|
31
|
-
"camoufox",
|
|
32
|
-
"cli",
|
|
33
|
-
"playwright"
|
|
34
|
-
],
|
|
35
|
-
"license": "MIT",
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=20.0.0"
|
|
38
|
-
},
|
|
39
|
-
"peerDependencies": {
|
|
40
|
-
"camoufox": "^0.1.0"
|
|
41
|
-
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"c8": "^10.1.3"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"playwright": "^1.
|
|
47
|
-
"ws": "^8.19.0"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Camoufox Browser CLI - Cross-platform browser automation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"camo": "./bin/camo.mjs",
|
|
8
|
+
"browser-service": "./bin/browser-service.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"src/",
|
|
13
|
+
"scripts/",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "node scripts/build.mjs",
|
|
19
|
+
"check:file-size": "node scripts/check-file-size.mjs",
|
|
20
|
+
"test": "node --test 'tests/**/*.test.mjs'",
|
|
21
|
+
"test:coverage": "c8 --reporter=text --reporter=lcov node --test 'tests/**/*.test.mjs'",
|
|
22
|
+
"test:coverage:modes": "c8 --all --check-coverage --lines 90 --functions 90 --branches 90 --statements 90 --include src/commands/record.mjs --include src/commands/highlight-mode.mjs --include src/container/runtime-core/operations/selector-scripts.mjs node --test tests/unit/commands/record.test.mjs tests/unit/commands/highlight-mode.test.mjs tests/unit/container/selector-scripts.test.mjs tests/unit/commands/browser.test.mjs",
|
|
23
|
+
"version:bump": "node scripts/bump-version.mjs",
|
|
24
|
+
"install:global": "npm run build && npm install -g .",
|
|
25
|
+
"uninstall:global": "npm uninstall -g @web-auto/camo",
|
|
26
|
+
"build:global": "npm run build && npm test && npm install -g ."
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"browser",
|
|
30
|
+
"automation",
|
|
31
|
+
"camoufox",
|
|
32
|
+
"cli",
|
|
33
|
+
"playwright"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20.0.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"camoufox": "^0.1.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"c8": "^10.1.3"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"playwright-core": "^1.54.1",
|
|
47
|
+
"ws": "^8.19.0"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/scripts/build.mjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { copyFileSync, chmodSync, mkdirSync } from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const root = path.resolve(__dirname, '..');
|
|
8
|
-
|
|
9
|
-
// Ensure bin directory exists
|
|
10
|
-
const binDir = path.join(root, 'bin');
|
|
11
|
-
try { mkdirSync(binDir, { recursive: true }); } catch {}
|
|
12
|
-
|
|
13
|
-
// Copy source files to dist (if needed)
|
|
14
|
-
// For now, we're running directly from src/
|
|
15
|
-
|
|
16
|
-
// Make bin/camo.mjs executable
|
|
17
|
-
const binFile = path.join(binDir, 'camo.mjs');
|
|
18
|
-
chmodSync(binFile, 0o755);
|
|
19
|
-
console.log('Build: bin/camo.mjs ready');
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { copyFileSync, chmodSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const root = path.resolve(__dirname, '..');
|
|
8
|
+
|
|
9
|
+
// Ensure bin directory exists
|
|
10
|
+
const binDir = path.join(root, 'bin');
|
|
11
|
+
try { mkdirSync(binDir, { recursive: true }); } catch {}
|
|
12
|
+
|
|
13
|
+
// Copy source files to dist (if needed)
|
|
14
|
+
// For now, we're running directly from src/
|
|
15
|
+
|
|
16
|
+
// Make bin/camo.mjs executable
|
|
17
|
+
const binFile = path.join(binDir, 'camo.mjs');
|
|
18
|
+
chmodSync(binFile, 0o755);
|
|
19
|
+
console.log('Build: bin/camo.mjs ready');
|
package/scripts/bump-version.mjs
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Version bumper for camo CLI.
|
|
4
|
-
* Increments standard semver patch version (0.1.21 -> 0.1.22).
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { readFileSync, writeFileSync } from 'fs';
|
|
8
|
-
import { fileURLToPath } from 'url';
|
|
9
|
-
import { dirname, join } from 'path';
|
|
10
|
-
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = dirname(__filename);
|
|
13
|
-
const packageJsonPath = join(__dirname, '..', 'package.json');
|
|
14
|
-
|
|
15
|
-
function bumpVersion() {
|
|
16
|
-
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
17
|
-
const currentVersion = pkg.version;
|
|
18
|
-
const parts = currentVersion.split('.');
|
|
19
|
-
const major = parseInt(parts[0], 10);
|
|
20
|
-
const minor = parseInt(parts[1], 10);
|
|
21
|
-
let patch = parseInt(parts[2], 10);
|
|
22
|
-
|
|
23
|
-
patch += 1;
|
|
24
|
-
|
|
25
|
-
const newVersion = `${major}.${minor}.${patch}`;
|
|
26
|
-
|
|
27
|
-
pkg.version = newVersion;
|
|
28
|
-
writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
29
|
-
|
|
30
|
-
console.log(`Version bumped: ${currentVersion} -> ${newVersion}`);
|
|
31
|
-
return newVersion;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
bumpVersion();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Version bumper for camo CLI.
|
|
4
|
+
* Increments standard semver patch version (0.1.21 -> 0.1.22).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { dirname, join } from 'path';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
const packageJsonPath = join(__dirname, '..', 'package.json');
|
|
14
|
+
|
|
15
|
+
function bumpVersion() {
|
|
16
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
17
|
+
const currentVersion = pkg.version;
|
|
18
|
+
const parts = currentVersion.split('.');
|
|
19
|
+
const major = parseInt(parts[0], 10);
|
|
20
|
+
const minor = parseInt(parts[1], 10);
|
|
21
|
+
let patch = parseInt(parts[2], 10);
|
|
22
|
+
|
|
23
|
+
patch += 1;
|
|
24
|
+
|
|
25
|
+
const newVersion = `${major}.${minor}.${patch}`;
|
|
26
|
+
|
|
27
|
+
pkg.version = newVersion;
|
|
28
|
+
writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
29
|
+
|
|
30
|
+
console.log(`Version bumped: ${currentVersion} -> ${newVersion}`);
|
|
31
|
+
return newVersion;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
bumpVersion();
|
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
|
|
5
|
-
const ROOT = process.cwd();
|
|
6
|
-
const TARGET_DIR = path.join(ROOT, 'src');
|
|
7
|
-
const MAX_LINES = Number(process.env.FILE_MAX_LINES || 500);
|
|
8
|
-
const POLICY_FILE = path.join(ROOT, 'scripts', 'file-size-policy.json');
|
|
9
|
-
const EXTS = new Set(['.mjs', '.js', '.ts', '.tsx']);
|
|
10
|
-
|
|
11
|
-
async function walk(dir) {
|
|
12
|
-
const out = [];
|
|
13
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
14
|
-
for (const entry of entries) {
|
|
15
|
-
const fullPath = path.join(dir, entry.name);
|
|
16
|
-
if (entry.isDirectory()) {
|
|
17
|
-
if (entry.name === 'node_modules' || entry.name === '.git') continue;
|
|
18
|
-
out.push(...await walk(fullPath));
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
if (!entry.isFile()) continue;
|
|
22
|
-
const ext = path.extname(entry.name).toLowerCase();
|
|
23
|
-
if (!EXTS.has(ext)) continue;
|
|
24
|
-
out.push(fullPath);
|
|
25
|
-
}
|
|
26
|
-
return out;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function countLines(content) {
|
|
30
|
-
if (!content) return 0;
|
|
31
|
-
return content.split(/\r?\n/).length;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function relative(p) {
|
|
35
|
-
return path.relative(ROOT, p).replaceAll(path.sep, '/');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function main() {
|
|
39
|
-
let policy = { defaultMaxLines: MAX_LINES, overrides: {} };
|
|
40
|
-
try {
|
|
41
|
-
const raw = await fs.readFile(POLICY_FILE, 'utf8');
|
|
42
|
-
const parsed = JSON.parse(raw);
|
|
43
|
-
policy = {
|
|
44
|
-
defaultMaxLines: Number(parsed?.defaultMaxLines || MAX_LINES),
|
|
45
|
-
overrides: parsed?.overrides && typeof parsed.overrides === 'object' ? parsed.overrides : {},
|
|
46
|
-
};
|
|
47
|
-
} catch {}
|
|
48
|
-
|
|
49
|
-
const files = await walk(TARGET_DIR);
|
|
50
|
-
const violations = [];
|
|
51
|
-
|
|
52
|
-
for (const file of files) {
|
|
53
|
-
const text = await fs.readFile(file, 'utf8');
|
|
54
|
-
const lines = countLines(text);
|
|
55
|
-
const rel = relative(file);
|
|
56
|
-
const overrideLimit = Number(policy.overrides?.[rel]);
|
|
57
|
-
const limit = Number.isFinite(overrideLimit) && overrideLimit > 0
|
|
58
|
-
? overrideLimit
|
|
59
|
-
: policy.defaultMaxLines;
|
|
60
|
-
if (lines > limit) {
|
|
61
|
-
violations.push({ file: rel, lines, limit });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (violations.length === 0) {
|
|
66
|
-
console.log(`file-size-check: OK (${files.length} files, default max ${policy.defaultMaxLines} lines)`);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
console.error(`file-size-check: ${violations.length} file(s) exceed configured limits`);
|
|
71
|
-
for (const item of violations) {
|
|
72
|
-
console.error(` - ${item.file}: ${item.lines} > ${item.limit}`);
|
|
73
|
-
}
|
|
74
|
-
process.exit(1);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
main().catch((err) => {
|
|
78
|
-
console.error(`file-size-check: failed - ${err?.message || err}`);
|
|
79
|
-
process.exit(1);
|
|
80
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
const ROOT = process.cwd();
|
|
6
|
+
const TARGET_DIR = path.join(ROOT, 'src');
|
|
7
|
+
const MAX_LINES = Number(process.env.FILE_MAX_LINES || 500);
|
|
8
|
+
const POLICY_FILE = path.join(ROOT, 'scripts', 'file-size-policy.json');
|
|
9
|
+
const EXTS = new Set(['.mjs', '.js', '.ts', '.tsx']);
|
|
10
|
+
|
|
11
|
+
async function walk(dir) {
|
|
12
|
+
const out = [];
|
|
13
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
14
|
+
for (const entry of entries) {
|
|
15
|
+
const fullPath = path.join(dir, entry.name);
|
|
16
|
+
if (entry.isDirectory()) {
|
|
17
|
+
if (entry.name === 'node_modules' || entry.name === '.git') continue;
|
|
18
|
+
out.push(...await walk(fullPath));
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (!entry.isFile()) continue;
|
|
22
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
23
|
+
if (!EXTS.has(ext)) continue;
|
|
24
|
+
out.push(fullPath);
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function countLines(content) {
|
|
30
|
+
if (!content) return 0;
|
|
31
|
+
return content.split(/\r?\n/).length;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function relative(p) {
|
|
35
|
+
return path.relative(ROOT, p).replaceAll(path.sep, '/');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function main() {
|
|
39
|
+
let policy = { defaultMaxLines: MAX_LINES, overrides: {} };
|
|
40
|
+
try {
|
|
41
|
+
const raw = await fs.readFile(POLICY_FILE, 'utf8');
|
|
42
|
+
const parsed = JSON.parse(raw);
|
|
43
|
+
policy = {
|
|
44
|
+
defaultMaxLines: Number(parsed?.defaultMaxLines || MAX_LINES),
|
|
45
|
+
overrides: parsed?.overrides && typeof parsed.overrides === 'object' ? parsed.overrides : {},
|
|
46
|
+
};
|
|
47
|
+
} catch {}
|
|
48
|
+
|
|
49
|
+
const files = await walk(TARGET_DIR);
|
|
50
|
+
const violations = [];
|
|
51
|
+
|
|
52
|
+
for (const file of files) {
|
|
53
|
+
const text = await fs.readFile(file, 'utf8');
|
|
54
|
+
const lines = countLines(text);
|
|
55
|
+
const rel = relative(file);
|
|
56
|
+
const overrideLimit = Number(policy.overrides?.[rel]);
|
|
57
|
+
const limit = Number.isFinite(overrideLimit) && overrideLimit > 0
|
|
58
|
+
? overrideLimit
|
|
59
|
+
: policy.defaultMaxLines;
|
|
60
|
+
if (lines > limit) {
|
|
61
|
+
violations.push({ file: rel, lines, limit });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (violations.length === 0) {
|
|
66
|
+
console.log(`file-size-check: OK (${files.length} files, default max ${policy.defaultMaxLines} lines)`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.error(`file-size-check: ${violations.length} file(s) exceed configured limits`);
|
|
71
|
+
for (const item of violations) {
|
|
72
|
+
console.error(` - ${item.file}: ${item.lines} > ${item.limit}`);
|
|
73
|
+
}
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
main().catch((err) => {
|
|
78
|
+
console.error(`file-size-check: failed - ${err?.message || err}`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
});
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
2
|
"defaultMaxLines": 500,
|
|
3
3
|
"overrides": {
|
|
4
|
-
"src/autoscript/runtime.mjs":
|
|
4
|
+
"src/autoscript/runtime.mjs": 1100,
|
|
5
|
+
"src/commands/autoscript.mjs": 1100,
|
|
6
|
+
"src/commands/browser.mjs": 1300,
|
|
7
|
+
"src/container/runtime-core/operations/index.mjs": 820,
|
|
8
|
+
"src/container/runtime-core/operations/tab-pool.mjs": 800,
|
|
9
|
+
"src/services/browser-service/index.js": 700,
|
|
10
|
+
"src/services/browser-service/internal/container-matcher.js": 900,
|
|
11
|
+
"src/services/browser-service/internal/page-runtime/runtime.js": 1400,
|
|
12
|
+
"src/services/browser-service/internal/ws-server.js": 1250,
|
|
13
|
+
"src/services/controller/controller.js": 1200,
|
|
14
|
+
"src/utils/browser-service.mjs": 600,
|
|
5
15
|
"src/autoscript/xhs-unified-template.mjs": 950,
|
|
6
16
|
"src/core/actions.mjs": 620
|
|
7
17
|
}
|
package/scripts/install.mjs
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* camo CLI Global Installer
|
|
4
|
-
* Usage: node scripts/install.mjs [--prefix /usr/local]
|
|
5
|
-
*/
|
|
6
|
-
import { execSync } from 'node:child_process';
|
|
7
|
-
import fs from 'node:fs';
|
|
8
|
-
import path from 'node:path';
|
|
9
|
-
import os from 'node:os';
|
|
10
|
-
|
|
11
|
-
const isWin = os.platform() === 'win32';
|
|
12
|
-
|
|
13
|
-
function detectPrefix() {
|
|
14
|
-
const prefixIdx = process.argv.indexOf('--prefix');
|
|
15
|
-
if (prefixIdx >= 0 && process.argv[prefixIdx + 1]) {
|
|
16
|
-
return process.argv[prefixIdx + 1];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const candidates = [
|
|
20
|
-
isWin ? path.join(os.homedir(), 'AppData', 'Local', 'camo') : null,
|
|
21
|
-
'/opt/homebrew',
|
|
22
|
-
'/usr/local',
|
|
23
|
-
'/usr',
|
|
24
|
-
path.join(os.homedir(), '.local'),
|
|
25
|
-
].filter(Boolean);
|
|
26
|
-
|
|
27
|
-
for (const p of candidates) {
|
|
28
|
-
try {
|
|
29
|
-
fs.accessSync(path.dirname(p), fs.constants.W_OK);
|
|
30
|
-
return p;
|
|
31
|
-
} catch {}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return path.join(os.homedir(), '.local');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function install() {
|
|
38
|
-
const prefix = detectPrefix();
|
|
39
|
-
const binDir = path.join(prefix, 'bin');
|
|
40
|
-
const targetDir = path.join(prefix, 'share', 'camo');
|
|
41
|
-
|
|
42
|
-
console.log(`Installing camo CLI...`);
|
|
43
|
-
console.log(` Prefix: ${prefix}`);
|
|
44
|
-
console.log(` Target: ${targetDir}`);
|
|
45
|
-
console.log(` Bin: ${binDir}`);
|
|
46
|
-
|
|
47
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
48
|
-
fs.mkdirSync(binDir, { recursive: true });
|
|
49
|
-
|
|
50
|
-
const thisDir = path.dirname(new URL(import.meta.url).pathname);
|
|
51
|
-
const moduleDir = path.resolve(thisDir, '..');
|
|
52
|
-
const srcFile = path.join(moduleDir, 'bin', 'camo.mjs');
|
|
53
|
-
|
|
54
|
-
if (!fs.existsSync(srcFile)) {
|
|
55
|
-
console.error(`Source not found: ${srcFile}`);
|
|
56
|
-
console.error('Run: cp src/cli.mjs bin/camo.mjs');
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const targetFile = path.join(targetDir, 'camo.mjs');
|
|
61
|
-
fs.copyFileSync(srcFile, targetFile);
|
|
62
|
-
fs.chmodSync(targetFile, 0o755);
|
|
63
|
-
|
|
64
|
-
const binPath = path.join(binDir, 'camo');
|
|
65
|
-
const wrapper = `#!/usr/bin/env sh
|
|
66
|
-
exec node "${targetFile}" "$@"`;
|
|
67
|
-
fs.writeFileSync(binPath, wrapper);
|
|
68
|
-
fs.chmodSync(binPath, 0o755);
|
|
69
|
-
|
|
70
|
-
console.log(`\n✅ camo CLI installed!`);
|
|
71
|
-
console.log(`\nAdd to PATH if needed:`);
|
|
72
|
-
console.log(` export PATH="${binDir}:$PATH"`);
|
|
73
|
-
console.log(`\nUsage: camo --help`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
install();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* camo CLI Global Installer
|
|
4
|
+
* Usage: node scripts/install.mjs [--prefix /usr/local]
|
|
5
|
+
*/
|
|
6
|
+
import { execSync } from 'node:child_process';
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
|
|
11
|
+
const isWin = os.platform() === 'win32';
|
|
12
|
+
|
|
13
|
+
function detectPrefix() {
|
|
14
|
+
const prefixIdx = process.argv.indexOf('--prefix');
|
|
15
|
+
if (prefixIdx >= 0 && process.argv[prefixIdx + 1]) {
|
|
16
|
+
return process.argv[prefixIdx + 1];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const candidates = [
|
|
20
|
+
isWin ? path.join(os.homedir(), 'AppData', 'Local', 'camo') : null,
|
|
21
|
+
'/opt/homebrew',
|
|
22
|
+
'/usr/local',
|
|
23
|
+
'/usr',
|
|
24
|
+
path.join(os.homedir(), '.local'),
|
|
25
|
+
].filter(Boolean);
|
|
26
|
+
|
|
27
|
+
for (const p of candidates) {
|
|
28
|
+
try {
|
|
29
|
+
fs.accessSync(path.dirname(p), fs.constants.W_OK);
|
|
30
|
+
return p;
|
|
31
|
+
} catch {}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return path.join(os.homedir(), '.local');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function install() {
|
|
38
|
+
const prefix = detectPrefix();
|
|
39
|
+
const binDir = path.join(prefix, 'bin');
|
|
40
|
+
const targetDir = path.join(prefix, 'share', 'camo');
|
|
41
|
+
|
|
42
|
+
console.log(`Installing camo CLI...`);
|
|
43
|
+
console.log(` Prefix: ${prefix}`);
|
|
44
|
+
console.log(` Target: ${targetDir}`);
|
|
45
|
+
console.log(` Bin: ${binDir}`);
|
|
46
|
+
|
|
47
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
48
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
49
|
+
|
|
50
|
+
const thisDir = path.dirname(new URL(import.meta.url).pathname);
|
|
51
|
+
const moduleDir = path.resolve(thisDir, '..');
|
|
52
|
+
const srcFile = path.join(moduleDir, 'bin', 'camo.mjs');
|
|
53
|
+
|
|
54
|
+
if (!fs.existsSync(srcFile)) {
|
|
55
|
+
console.error(`Source not found: ${srcFile}`);
|
|
56
|
+
console.error('Run: cp src/cli.mjs bin/camo.mjs');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const targetFile = path.join(targetDir, 'camo.mjs');
|
|
61
|
+
fs.copyFileSync(srcFile, targetFile);
|
|
62
|
+
fs.chmodSync(targetFile, 0o755);
|
|
63
|
+
|
|
64
|
+
const binPath = path.join(binDir, 'camo');
|
|
65
|
+
const wrapper = `#!/usr/bin/env sh
|
|
66
|
+
exec node "${targetFile}" "$@"`;
|
|
67
|
+
fs.writeFileSync(binPath, wrapper);
|
|
68
|
+
fs.chmodSync(binPath, 0o755);
|
|
69
|
+
|
|
70
|
+
console.log(`\n✅ camo CLI installed!`);
|
|
71
|
+
console.log(`\nAdd to PATH if needed:`);
|
|
72
|
+
console.log(` export PATH="${binDir}:$PATH"`);
|
|
73
|
+
console.log(`\nUsage: camo --help`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
install();
|