fchek 1.0.0

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 (66) hide show
  1. package/README.md +64 -0
  2. package/bin/fchek.js +107 -0
  3. package/lib/api.js +110 -0
  4. package/lib/audit.js +211 -0
  5. package/lib/bench.js +248 -0
  6. package/lib/config.js +191 -0
  7. package/lib/context.js +356 -0
  8. package/lib/convention.js +526 -0
  9. package/lib/coverage.js +604 -0
  10. package/lib/db.js +135 -0
  11. package/lib/deps-check.js +264 -0
  12. package/lib/deps.js +374 -0
  13. package/lib/docker.js +84 -0
  14. package/lib/doctor.js +149 -0
  15. package/lib/dom.js +226 -0
  16. package/lib/fuzz.js +470 -0
  17. package/lib/git.js +290 -0
  18. package/lib/goto.js +544 -0
  19. package/lib/launch.js +182 -0
  20. package/lib/lint.js +624 -0
  21. package/lib/new_features.test.js +181 -0
  22. package/lib/output.js +46 -0
  23. package/lib/port.js +173 -0
  24. package/lib/process.js +228 -0
  25. package/lib/profile.js +453 -0
  26. package/lib/python.js +41 -0
  27. package/lib/race.js +186 -0
  28. package/lib/registry.js +179 -0
  29. package/lib/repl.js +135 -0
  30. package/lib/run.js +403 -0
  31. package/lib/screenshot.js +152 -0
  32. package/lib/secrets.js +257 -0
  33. package/lib/state.js +219 -0
  34. package/lib/test.js +471 -0
  35. package/lib/vuln.js +253 -0
  36. package/lib/watch.js +240 -0
  37. package/lib/winlog.js +123 -0
  38. package/package.json +27 -0
  39. package/skills/ACTIVATE.md +274 -0
  40. package/skills/README.md +163 -0
  41. package/skills/agent.md +444 -0
  42. package/skills/api.md +47 -0
  43. package/skills/bench.md +117 -0
  44. package/skills/context.md +116 -0
  45. package/skills/convention.md +143 -0
  46. package/skills/coverage.md +99 -0
  47. package/skills/csharp.md +97 -0
  48. package/skills/db.md +66 -0
  49. package/skills/deps-check.md +135 -0
  50. package/skills/deps.md +143 -0
  51. package/skills/docker.md +61 -0
  52. package/skills/dom.md +56 -0
  53. package/skills/fuzz.md +167 -0
  54. package/skills/goto.md +111 -0
  55. package/skills/lint.md +123 -0
  56. package/skills/port.md +57 -0
  57. package/skills/profile.md +91 -0
  58. package/skills/race.md +117 -0
  59. package/skills/repl.md +81 -0
  60. package/skills/rules.md +318 -0
  61. package/skills/run.md +135 -0
  62. package/skills/secrets.md +170 -0
  63. package/skills/security.md +360 -0
  64. package/skills/state.md +261 -0
  65. package/skills/vuln.md +57 -0
  66. package/skills/windows.md +320 -0
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # fchek — Developer & AI Autonomous Toolbox
2
+
3
+ `fchek` is a command-line toolbox designed for developers and AI agents to run code, verify tests, check network ports, query databases, audit container health, profile performance, and manage codebases efficiently.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install -g .
11
+ ```
12
+
13
+ Verify with:
14
+ ```bash
15
+ fchek --help
16
+ ```
17
+
18
+ ---
19
+
20
+ ## All Commands
21
+
22
+ ### Full Automation
23
+ * `fchek audit [dir]` — Full audit: context + secrets + lint + test + deps in one run.
24
+ * `fchek test [dir]` — Auto-detect test framework (pytest, jest, vitest, mocha, cargo, go, dotnet) and run tests.
25
+ * `fchek git <action>` — Safe git operations (status, diff, stage, commit, etc.).
26
+ * `fchek config [action]` — Read or write `.fchekrc` config.
27
+
28
+ ### Code Intelligence (Before Code)
29
+ * `fchek context <dir>` — Dump all symbols to avoid duplicates.
30
+ * `fchek convention <dir>` — Analyze coding patterns (style, error handling, logging).
31
+ * `fchek deps-check <lib>` — Live API registry checking.
32
+
33
+ ### Execute & Verify (After Code)
34
+ * `fchek run <file>` — Execute file and get structured JSON stdout/stderr/exit_code.
35
+ * `fchek secrets <path>` — Scan for credentials (gitleaks, trufflehog, or regex).
36
+ * `fchek vuln [dir]` — Scan dependencies for vulnerabilities and typosquatting.
37
+ * `fchek dom <url|file> <selector>` — Query HTML page elements using CSS selectors.
38
+
39
+ ### Network & Databases
40
+ * `fchek port <port> [--all]` — Network port inspector (checks if a port is in use and returns the process PID & name).
41
+ * `fchek api <url> [options]` — HTTP API tester with status codes, headers, and timing metrics.
42
+ * `fchek db <action> <db_path> [sql]` — SQLite schema inspector (`schema`) and query runner (`query`).
43
+ * `fchek docker <action> [options]` — Docker assistant: lists containers (`list`) or gets logs (`logs`).
44
+
45
+ ### Windows Integration
46
+ * `fchek screenshot [--window=<title>]` — Screenshot window or desktop.
47
+ * `fchek launch <exe>` — Launch application and wait for window creation.
48
+ * `fchek winlog` — Get Windows event logs.
49
+ * `fchek registry <action>` — Query or modify Windows Registry.
50
+ * `fchek process <action>` — Manage processes.
51
+ * `fchek watch <dir>` — Watch directory, rebuild, and relaunch on modification.
52
+
53
+ ### Analysis & Memory
54
+ * `fchek profile <file>` — Hot path profiling.
55
+ * `fchek coverage <dir>` — Code coverage reports.
56
+ * `fchek bench --before --after` — Benchmark code speedups.
57
+ * `fchek lint <dir>` — Code format and linter with auto-fixing.
58
+ * `fchek deps <dir>` — Identify dead code/circular dependencies.
59
+ * `fchek race <file>` — ThreadSanitizer/AddressSanitizer checks.
60
+ * `fchek fuzz <file>` — AFL++/cargo-fuzz runner.
61
+ * `fchek goto <file:line>` — Navigation & references.
62
+ * `fchek state <action>` — Persistent project memory.
63
+ * `fchek repl` — Interactive REPL with session variables.
64
+ * `fchek doctor` — Verify local environment & dependencies.
package/bin/fchek.js ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ const COMMANDS = {
6
+ context: () => require('../lib/context'),
7
+ convention: () => require('../lib/convention'),
8
+ 'deps-check': () => require('../lib/deps-check'),
9
+ run: () => require('../lib/run'),
10
+ test: () => require('../lib/test'),
11
+ secrets: () => require('../lib/secrets'),
12
+ audit: () => require('../lib/audit'),
13
+ git: () => require('../lib/git'),
14
+ config: () => require('../lib/config'),
15
+ screenshot: () => require('../lib/screenshot'),
16
+ launch: () => require('../lib/launch'),
17
+ winlog: () => require('../lib/winlog'),
18
+ registry: () => require('../lib/registry'),
19
+ process: () => require('../lib/process'),
20
+ watch: () => require('../lib/watch'),
21
+ profile: () => require('../lib/profile'),
22
+ coverage: () => require('../lib/coverage'),
23
+ bench: () => require('../lib/bench'),
24
+ lint: () => require('../lib/lint'),
25
+ deps: () => require('../lib/deps'),
26
+ race: () => require('../lib/race'),
27
+ fuzz: () => require('../lib/fuzz'),
28
+ goto: () => require('../lib/goto'),
29
+ state: () => require('../lib/state'),
30
+ repl: () => require('../lib/repl'),
31
+ doctor: () => require('../lib/doctor'),
32
+ port: () => require('../lib/port'),
33
+ api: () => require('../lib/api'),
34
+ db: () => require('../lib/db'),
35
+ docker: () => require('../lib/docker'),
36
+ vuln: () => require('../lib/vuln'),
37
+ dom: () => require('../lib/dom'),
38
+ };
39
+
40
+ const HELP = `
41
+ fchek — developer & AI autonomous toolbox
42
+
43
+ ── Full Automation ──────────────────────────────────────────────────────
44
+ audit [dir] [--quick] Full audit in one command
45
+ test [dir] [--filter=<n>] Auto-detect & run tests
46
+ git <action> status/diff/log/stage/commit
47
+ config [action] Read/write .fchekrc
48
+
49
+ ── Code Intelligence (BEFORE code) ─────────────────────────────────────
50
+ context <dir> All symbols — avoid duplicates
51
+ convention <dir> Coding patterns (style, errors, logging)
52
+ deps-check <lib> Live API check from registry
53
+
54
+ ── Execute & Verify (AFTER code) ───────────────────────────────────────
55
+ run <file> Run → stdout/stderr/exit_code
56
+ secrets <path> Scan for credentials
57
+ vuln [dir] Scan for typosquatting & vulnerabilities
58
+ dom <url|file> <sel> Query HTML DOM elements
59
+
60
+ ── Windows ─────────────────────────────────────────────────────────────
61
+ screenshot [--window=<title>] Capture window/screen → PNG
62
+ launch <exe> [--wait=ms] Launch app, wait for window
63
+ winlog [--filter=<app>] Event Viewer logs
64
+ registry <action> <key> Read/write registry
65
+ process <action> [name|pid] List/kill/info processes
66
+ watch <dir> [--cmd=<build>] Auto-rebuild on file change
67
+
68
+ ── Network & Databases ─────────────────────────────────────────────────
69
+ port <port> [--all] Network port scanner & connection info
70
+ api <url> [options] API / HTTP query tester
71
+ db <action> <db> [sql] SQLite schema & query runner
72
+ docker <action> [options] Docker ps and logs helper
73
+
74
+ ── Analysis ────────────────────────────────────────────────────────────
75
+ profile / coverage / bench / lint / deps / race / fuzz / goto
76
+
77
+ ── Memory & Environment ────────────────────────────────────────────────
78
+ state / repl / doctor
79
+
80
+ Output: JSON { "status": "ok"|"error", "data":{...} }
81
+ `.trim();
82
+
83
+ async function main() {
84
+ const args = process.argv.slice(2);
85
+ if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
86
+ console.log(HELP); process.exit(0);
87
+ }
88
+
89
+ const cmd = args[0];
90
+ const cmdArgs = args.slice(1);
91
+
92
+ if (!COMMANDS[cmd]) {
93
+ console.error(`\nError: unknown command "${cmd}"\n`);
94
+ console.log(HELP); process.exit(1);
95
+ }
96
+
97
+ try {
98
+ await COMMANDS[cmd]().run(cmdArgs);
99
+ } catch (err) {
100
+ const { output, fail } = require('../lib/output');
101
+ output(fail(err.message, cmd));
102
+ if (process.env.DEBUG) console.error(err.stack);
103
+ process.exit(1);
104
+ }
105
+ }
106
+
107
+ main();
package/lib/api.js ADDED
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ const http = require('http');
4
+ const https = require('https');
5
+ const { URL } = require('url');
6
+ const { output, ok, fail } = require('./output');
7
+
8
+ const HELP = `
9
+ fchek api <url> [--method=<method>] [--headers=<key:val,key2:val2>] [--body=<body>]
10
+
11
+ Test API endpoints and HTTP services.
12
+ Returns response status, headers, body size, and roundtrip latency.
13
+ `.trim();
14
+
15
+ function run(args) {
16
+ if (args.includes('--help') || args.includes('-h')) {
17
+ console.log(HELP);
18
+ return Promise.resolve();
19
+ }
20
+
21
+ const urlStr = args.find(a => !a.startsWith('-'));
22
+ if (!urlStr) {
23
+ output(fail('Please specify a URL (e.g. fchek api https://api.github.com)', 'api'));
24
+ return Promise.resolve();
25
+ }
26
+
27
+ let method = 'GET';
28
+ let headers = {};
29
+ let body = '';
30
+
31
+ for (const arg of args) {
32
+ if (arg.startsWith('--method=')) {
33
+ method = arg.split('=')[1].toUpperCase();
34
+ } else if (arg.startsWith('--headers=')) {
35
+ const headersStr = arg.slice(10);
36
+ const items = headersStr.split(',');
37
+ for (const item of items) {
38
+ const colonIdx = item.indexOf(':');
39
+ if (colonIdx !== -1) {
40
+ const k = item.slice(0, colonIdx).trim();
41
+ const v = item.slice(colonIdx + 1).trim();
42
+ headers[k] = v;
43
+ }
44
+ }
45
+ } else if (arg.startsWith('--body=')) {
46
+ body = arg.slice(7);
47
+ }
48
+ }
49
+
50
+ let parsedUrl;
51
+ try {
52
+ parsedUrl = new URL(urlStr);
53
+ } catch (err) {
54
+ output(fail(`Invalid URL: ${err.message}`, 'api'));
55
+ return Promise.resolve();
56
+ }
57
+
58
+ const protocol = parsedUrl.protocol === 'https:' ? https : http;
59
+ const options = {
60
+ method,
61
+ headers,
62
+ timeout: 10000,
63
+ };
64
+
65
+ const startTime = process.hrtime();
66
+
67
+ return new Promise((resolve) => {
68
+ const req = protocol.request(urlStr, options, (res) => {
69
+ let responseData = '';
70
+ res.setEncoding('utf8');
71
+ res.on('data', (chunk) => {
72
+ responseData += chunk;
73
+ });
74
+
75
+ res.on('end', () => {
76
+ const diff = process.hrtime(startTime);
77
+ const timeMs = Math.round(diff[0] * 1000 + diff[1] / 1000000);
78
+
79
+ output(ok({
80
+ status_code: res.statusCode,
81
+ status_text: res.statusMessage || '',
82
+ time_ms: timeMs,
83
+ headers: res.headers,
84
+ body_size_bytes: Buffer.byteLength(responseData, 'utf8'),
85
+ body: responseData.slice(0, 10000), // Cap body output to avoid massive JSONs
86
+ body_truncated: responseData.length > 10000,
87
+ }, 'api'));
88
+ resolve();
89
+ });
90
+ });
91
+
92
+ req.on('error', (err) => {
93
+ output(fail(`Request failed: ${err.message}`, 'api'));
94
+ resolve();
95
+ });
96
+
97
+ req.on('timeout', () => {
98
+ req.destroy();
99
+ output(fail('Request timed out after 10s', 'api'));
100
+ resolve();
101
+ });
102
+
103
+ if (body) {
104
+ req.write(body);
105
+ }
106
+ req.end();
107
+ });
108
+ }
109
+
110
+ module.exports = { run };
package/lib/audit.js ADDED
@@ -0,0 +1,211 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * audit.js — full project audit in one command
5
+ *
6
+ * Runs sequentially: context → convention → secrets → lint → test → deps → coverage
7
+ * Returns consolidated JSON with summary and per-tool results.
8
+ * Agent uses this at project start to understand the full picture.
9
+ */
10
+
11
+ const path = require('path');
12
+ const fs = require('fs');
13
+ const { output, ok, fail } = require('./output');
14
+
15
+ const HELP = `
16
+ fchek audit [dir] [--quick] [--fix]
17
+
18
+ Run a full project audit: context, convention, secrets, lint, test, deps, coverage.
19
+ One command instead of six. Use at project start or before a major change.
20
+
21
+ Options:
22
+ --quick Skip slow steps (coverage, fuzz). Faster for CI.
23
+ --fix Apply auto-fixes during lint step.
24
+ --json Always output JSON (default)
25
+
26
+ Output: consolidated report with status per tool and overall verdict.
27
+
28
+ Examples:
29
+ fchek audit .
30
+ fchek audit src/ --quick
31
+ fchek audit . --fix
32
+ `.trim();
33
+
34
+ async function runStep(name, fn) {
35
+ const t0 = Date.now();
36
+ try {
37
+ // Capture output by temporarily overriding console.log
38
+ const lines = [];
39
+ const orig = console.log;
40
+ console.log = (s) => lines.push(s);
41
+ await fn();
42
+ console.log = orig;
43
+
44
+ let data = null;
45
+ if (lines.length > 0) {
46
+ try { data = JSON.parse(lines[lines.length - 1]); } catch {}
47
+ }
48
+
49
+ return {
50
+ step: name,
51
+ status: data?.status ?? 'ok',
52
+ duration_ms: Date.now() - t0,
53
+ data: data?.data ?? null,
54
+ error: data?.error ?? null,
55
+ };
56
+ } catch (err) {
57
+ return {
58
+ step: name,
59
+ status: 'error',
60
+ duration_ms: Date.now() - t0,
61
+ data: null,
62
+ error: err.message,
63
+ };
64
+ }
65
+ }
66
+
67
+ async function run(args) {
68
+ if (args[0] === '--help') { console.log(HELP); return; }
69
+
70
+ const dir = args.find(a => !a.startsWith('--')) || '.';
71
+ const quick = args.includes('--quick');
72
+ const fix = args.includes('--fix');
73
+
74
+ if (!fs.existsSync(dir)) {
75
+ return output(fail(`Directory not found: ${dir}`));
76
+ }
77
+
78
+ const absDir = path.resolve(dir);
79
+ const results = [];
80
+ const t0Total = Date.now();
81
+
82
+ console.error(`[fchek audit] Starting full audit of: ${absDir}`);
83
+
84
+ // 1. context — what exists
85
+ console.error('[fchek audit] 1/7 context...');
86
+ results.push(await runStep('context', async () => {
87
+ await require('./context').run([absDir, '--names-only']);
88
+ }));
89
+
90
+ // 2. convention — project patterns
91
+ console.error('[fchek audit] 2/7 convention...');
92
+ results.push(await runStep('convention', async () => {
93
+ await require('./convention').run([absDir]);
94
+ }));
95
+
96
+ // 3. secrets — credentials scan
97
+ console.error('[fchek audit] 3/7 secrets...');
98
+ results.push(await runStep('secrets', async () => {
99
+ await require('./secrets').run([absDir]);
100
+ }));
101
+
102
+ // 4. lint — code quality
103
+ console.error('[fchek audit] 4/7 lint...');
104
+ results.push(await runStep('lint', async () => {
105
+ const lintArgs = [absDir];
106
+ if (!fix) lintArgs.push('--no-fix');
107
+ await require('./lint').run(lintArgs);
108
+ }));
109
+
110
+ // 5. test — run tests
111
+ console.error('[fchek audit] 5/7 test...');
112
+ results.push(await runStep('test', async () => {
113
+ await require('./test').run([absDir]);
114
+ }));
115
+
116
+ // 6. deps — dependencies
117
+ console.error('[fchek audit] 6/7 deps...');
118
+ results.push(await runStep('deps', async () => {
119
+ await require('./deps').run([absDir]);
120
+ }));
121
+
122
+ // 7. coverage — only if not quick
123
+ if (!quick) {
124
+ console.error('[fchek audit] 7/7 coverage...');
125
+ results.push(await runStep('coverage', async () => {
126
+ await require('./coverage').run([absDir]);
127
+ }));
128
+ }
129
+
130
+ const totalMs = Date.now() - t0Total;
131
+
132
+ // Build summary
133
+ const secretsStep = results.find(r => r.step === 'secrets');
134
+ const testStep = results.find(r => r.step === 'test');
135
+ const lintStep = results.find(r => r.step === 'lint');
136
+ const coverageStep = results.find(r => r.step === 'coverage');
137
+ const depsStep = results.find(r => r.step === 'deps');
138
+
139
+ const criticalIssues = [];
140
+
141
+ if (secretsStep?.data?.verdict && secretsStep.data.verdict !== 'clean') {
142
+ criticalIssues.push(`SECRETS: ${secretsStep.data.total_findings} findings (${secretsStep.data.verdict})`);
143
+ }
144
+ if (testStep?.data?.verdict === 'failures_found') {
145
+ criticalIssues.push(`TESTS: ${testStep.data.failed} failed`);
146
+ }
147
+ if (lintStep?.data?.issues_count > 0) {
148
+ criticalIssues.push(`LINT: ${lintStep.data.issues_count} issues`);
149
+ }
150
+ if (coverageStep?.data?.total_pct !== null && coverageStep?.data?.total_pct < 60) {
151
+ criticalIssues.push(`COVERAGE: ${coverageStep.data.total_pct}% (below 60%)`);
152
+ }
153
+
154
+ const verdict = criticalIssues.length === 0 ? 'healthy' : 'needs_attention';
155
+
156
+ output(ok({
157
+ dir: absDir,
158
+ verdict,
159
+ critical_issues: criticalIssues,
160
+ total_ms: totalMs,
161
+ quick_mode: quick,
162
+ steps: results.map(r => ({
163
+ step: r.step,
164
+ status: r.status,
165
+ duration_ms: r.duration_ms,
166
+ // Key metrics per step
167
+ summary: buildStepSummary(r),
168
+ })),
169
+ full_results: results,
170
+ next_actions: buildNextActions(criticalIssues, results),
171
+ }));
172
+ }
173
+
174
+ function buildStepSummary(r) {
175
+ if (!r.data) return r.error ? `error: ${r.error.slice(0, 80)}` : 'no data';
176
+ const d = r.data;
177
+ switch (r.step) {
178
+ case 'context': return `${d.total_symbols ?? 0} symbols in ${d.total_files ?? 0} files`;
179
+ case 'convention': return d.summary ?? 'ok';
180
+ case 'secrets': return `${d.total_findings ?? 0} findings, verdict: ${d.verdict ?? '?'}`;
181
+ case 'lint': return `${d.issues_count ?? 0} issues, build_clean: ${d.build_clean ?? '?'}`;
182
+ case 'test': return `${d.passed ?? 0} passed, ${d.failed ?? 0} failed (${d.framework ?? '?'})`;
183
+ case 'deps': return `${d.package_count ?? 0} packages, ${d.outdated_count ?? 0} outdated`;
184
+ case 'coverage': return `${d.total_pct ?? '?'}% coverage`;
185
+ default: return 'ok';
186
+ }
187
+ }
188
+
189
+ function buildNextActions(issues, results) {
190
+ const actions = [];
191
+ for (const issue of issues) {
192
+ if (issue.startsWith('SECRETS')) {
193
+ actions.push('Fix secrets: replace hardcoded values with environment variables');
194
+ }
195
+ if (issue.startsWith('TESTS')) {
196
+ actions.push('Fix failing tests before making any other changes');
197
+ }
198
+ if (issue.startsWith('LINT')) {
199
+ actions.push('Run: fchek lint . --fix to apply auto-fixes');
200
+ }
201
+ if (issue.startsWith('COVERAGE')) {
202
+ actions.push('Add tests for uncovered code: fchek coverage . to see which lines');
203
+ }
204
+ }
205
+ if (actions.length === 0) {
206
+ actions.push('Project looks healthy. Proceed with your task.');
207
+ }
208
+ return actions;
209
+ }
210
+
211
+ module.exports = { run };