aislop 0.4.0 → 0.5.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.
@@ -1,81 +1,9 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
+ import { n as runSubprocess } from "./subprocess-CQUJDGgn.js";
1
3
  import { createRequire } from "node:module";
2
4
  import fs from "node:fs";
3
5
  import path from "node:path";
4
- import { spawn } from "node:child_process";
5
6
 
6
- //#region \0rolldown/runtime.js
7
- var __defProp = Object.defineProperty;
8
- var __exportAll = (all, no_symbols) => {
9
- let target = {};
10
- for (var name in all) {
11
- __defProp(target, name, {
12
- get: all[name],
13
- enumerable: true
14
- });
15
- }
16
- if (!no_symbols) {
17
- __defProp(target, Symbol.toStringTag, { value: "Module" });
18
- }
19
- return target;
20
- };
21
-
22
- //#endregion
23
- //#region src/utils/subprocess.ts
24
- const runSubprocess = (command, args, options = {}) => {
25
- return new Promise((resolve, reject) => {
26
- const child = spawn(command, args, {
27
- cwd: options.cwd,
28
- env: {
29
- ...process.env,
30
- ...options.env
31
- },
32
- stdio: [
33
- "ignore",
34
- "pipe",
35
- "pipe"
36
- ],
37
- windowsHide: true
38
- });
39
- const stdoutBuffers = [];
40
- const stderrBuffers = [];
41
- child.stdout?.on("data", (buffer) => stdoutBuffers.push(buffer));
42
- child.stderr?.on("data", (buffer) => stderrBuffers.push(buffer));
43
- let settled = false;
44
- let timer;
45
- const finalize = (callback) => {
46
- if (settled) return;
47
- settled = true;
48
- if (timer) clearTimeout(timer);
49
- callback();
50
- };
51
- if (options.timeout && options.timeout > 0) {
52
- timer = setTimeout(() => {
53
- child.kill("SIGTERM");
54
- setTimeout(() => child.kill("SIGKILL"), 1e3).unref();
55
- finalize(() => reject(/* @__PURE__ */ new Error(`Command timed out after ${options.timeout}ms: ${command}`)));
56
- }, options.timeout);
57
- timer.unref();
58
- }
59
- child.once("error", (error) => finalize(() => reject(/* @__PURE__ */ new Error(`Failed to run ${command}: ${error.message}`))));
60
- child.once("close", (code) => {
61
- finalize(() => resolve({
62
- stdout: Buffer.concat(stdoutBuffers).toString("utf-8").trim(),
63
- stderr: Buffer.concat(stderrBuffers).toString("utf-8").trim(),
64
- exitCode: code
65
- }));
66
- });
67
- });
68
- };
69
- const isToolInstalled = async (tool) => {
70
- try {
71
- const result = await runSubprocess("which", [tool]);
72
- return result.exitCode === 0 && result.stdout.length > 0;
73
- } catch {
74
- return false;
75
- }
76
- };
77
-
78
- //#endregion
79
7
  //#region src/engines/lint/expo-doctor.ts
80
8
  var expo_doctor_exports = /* @__PURE__ */ __exportAll({ runExpoDoctor: () => runExpoDoctor });
81
9
  const esmRequire = createRequire(import.meta.url);
@@ -146,7 +74,16 @@ const toDiagnostics = (issues) => issues.map((issue) => {
146
74
  fixable: false
147
75
  };
148
76
  });
77
+ const hasExpoInstalled = (rootDirectory) => {
78
+ try {
79
+ createRequire(path.join(rootDirectory, "package.json")).resolve("expo/package.json");
80
+ return true;
81
+ } catch {
82
+ return false;
83
+ }
84
+ };
149
85
  const runExpoDoctor = async (context) => {
86
+ if (!hasExpoInstalled(context.rootDirectory)) return [];
150
87
  const scriptPath = resolveExpoDoctorScript();
151
88
  let stdout = "";
152
89
  let stderr = "";
@@ -187,7 +124,7 @@ const runExpoDoctor = async (context) => {
187
124
  rule: "expo-doctor/config-error",
188
125
  severity: "warning",
189
126
  message: configError,
190
- help: "Install project dependencies, then re-run `aislop scan`.",
127
+ help: "Install project dependencies, then re-run `npx aislop scan`.",
191
128
  line: 0,
192
129
  column: 0,
193
130
  category: "Expo",
@@ -197,4 +134,4 @@ const runExpoDoctor = async (context) => {
197
134
  };
198
135
 
199
136
  //#endregion
200
- export { runSubprocess as i, runExpoDoctor as n, isToolInstalled as r, expo_doctor_exports as t };
137
+ export { runExpoDoctor as n, expo_doctor_exports as t };
@@ -0,0 +1,109 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
+ import { n as runSubprocess } from "./subprocess-CQUJDGgn.js";
3
+
4
+ //#region src/engines/lint/generic.ts
5
+ var generic_exports = /* @__PURE__ */ __exportAll({
6
+ fixRubyLint: () => fixRubyLint,
7
+ runGenericLinter: () => runGenericLinter
8
+ });
9
+ const runGenericLinter = async (context, language) => {
10
+ switch (language) {
11
+ case "rust": return runClippy(context);
12
+ case "ruby": return runRubocop(context);
13
+ default: return [];
14
+ }
15
+ };
16
+ const fixRubyLint = async (rootDirectory) => {
17
+ const result = await runSubprocess("rubocop", [
18
+ "-a",
19
+ "--except",
20
+ "Layout"
21
+ ], {
22
+ cwd: rootDirectory,
23
+ timeout: 6e4
24
+ });
25
+ if (result.exitCode !== null && result.exitCode > 1) throw new Error(result.stderr || result.stdout || `rubocop exited with code ${result.exitCode}`);
26
+ };
27
+ const runClippy = async (context) => {
28
+ try {
29
+ return parseClippyDiagnostics((await runSubprocess("cargo", [
30
+ "clippy",
31
+ "--message-format=json",
32
+ "--quiet"
33
+ ], {
34
+ cwd: context.rootDirectory,
35
+ timeout: 12e4
36
+ })).stdout);
37
+ } catch {
38
+ return [];
39
+ }
40
+ };
41
+ const parseClippyEntry = (line) => {
42
+ if (!line.startsWith("{")) return null;
43
+ try {
44
+ return JSON.parse(line);
45
+ } catch {
46
+ return null;
47
+ }
48
+ };
49
+ const toClippyDiagnostic = (entry) => {
50
+ if (entry.reason !== "compiler-message" || !entry.message) return null;
51
+ const message = entry.message;
52
+ const span = message.spans?.[0];
53
+ return {
54
+ filePath: span?.file_name ?? "",
55
+ engine: "lint",
56
+ rule: `clippy/${message.code?.code ?? "unknown"}`,
57
+ severity: message.level === "error" ? "error" : "warning",
58
+ message: message.message ?? "",
59
+ help: message.children?.[0]?.message ?? "",
60
+ line: span?.line_start ?? 0,
61
+ column: span?.column_start ?? 0,
62
+ category: "Rust Lint",
63
+ fixable: false
64
+ };
65
+ };
66
+ const parseClippyDiagnostics = (output) => {
67
+ const diagnostics = [];
68
+ for (const line of output.split("\n")) {
69
+ const entry = parseClippyEntry(line);
70
+ if (!entry) continue;
71
+ const diagnostic = toClippyDiagnostic(entry);
72
+ if (diagnostic) diagnostics.push(diagnostic);
73
+ }
74
+ return diagnostics;
75
+ };
76
+ const runRubocop = async (context) => {
77
+ try {
78
+ const output = (await runSubprocess("rubocop", [
79
+ "--format",
80
+ "json",
81
+ "--except",
82
+ "Layout"
83
+ ], {
84
+ cwd: context.rootDirectory,
85
+ timeout: 6e4
86
+ })).stdout;
87
+ if (!output) return [];
88
+ const parsed = JSON.parse(output);
89
+ const diagnostics = [];
90
+ for (const file of parsed.files ?? []) for (const offense of file.offenses ?? []) diagnostics.push({
91
+ filePath: file.path,
92
+ engine: "lint",
93
+ rule: `rubocop/${offense.cop_name}`,
94
+ severity: offense.severity === "error" || offense.severity === "fatal" ? "error" : "warning",
95
+ message: offense.message,
96
+ help: "",
97
+ line: offense.location?.start_line ?? 0,
98
+ column: offense.location?.start_column ?? 0,
99
+ category: "Ruby Lint",
100
+ fixable: offense.correctable ?? false
101
+ });
102
+ return diagnostics;
103
+ } catch {
104
+ return [];
105
+ }
106
+ };
107
+
108
+ //#endregion
109
+ export { generic_exports as n, runGenericLinter as r, fixRubyLint as t };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,25 @@
1
1
  import { z } from "zod/v4";
2
2
 
3
3
  //#region src/commands/doctor.d.ts
4
- declare const doctorCommand: (directory: string) => Promise<void>;
4
+ interface DoctorEngineRow {
5
+ engine: string;
6
+ tool: string;
7
+ status: "ok" | "missing" | "skipped";
8
+ remediation?: string;
9
+ skipReason?: string;
10
+ }
11
+ interface BuildDoctorRenderInput {
12
+ projectName: string;
13
+ languageLabel: string;
14
+ rows: DoctorEngineRow[];
15
+ invocation: string;
16
+ printBrand?: boolean;
17
+ }
18
+ declare const buildDoctorRender: (input: BuildDoctorRenderInput) => string;
19
+ interface DoctorOptions {
20
+ printBrand?: boolean;
21
+ }
22
+ declare const doctorCommand: (directory: string, options?: DoctorOptions) => Promise<void>;
5
23
  //#endregion
6
24
  //#region src/config/schema.d.ts
7
25
  declare const AislopConfigSchema: z.ZodObject<{
@@ -47,6 +65,14 @@ type AislopConfig = z.infer<typeof AislopConfigSchema>;
47
65
  //#region src/config/index.d.ts
48
66
  declare const loadConfig: (directory: string) => AislopConfig;
49
67
  //#endregion
68
+ //#region src/ui/rail.d.ts
69
+ type RailStepStatus = "active" | "done" | "warn" | "failed" | "skipped";
70
+ interface RailStep {
71
+ status: RailStepStatus;
72
+ label: string;
73
+ notes?: string[];
74
+ }
75
+ //#endregion
50
76
  //#region src/commands/fix.d.ts
51
77
  interface FixOptions {
52
78
  verbose: boolean;
@@ -56,29 +82,44 @@ interface FixOptions {
56
82
  /** Print the prompt to stdout instead of launching an agent */
57
83
  prompt?: boolean;
58
84
  showHeader?: boolean;
85
+ printBrand?: boolean;
59
86
  }
60
87
  declare const fixCommand: (directory: string, config: AislopConfig, options?: FixOptions) => Promise<void>;
61
88
  //#endregion
62
89
  //#region src/commands/init.d.ts
63
- declare const initCommand: (directory: string) => Promise<void>;
90
+ interface BuildInitRenderInput {
91
+ steps: RailStep[];
92
+ nextCommand: string;
93
+ includeHeader?: boolean;
94
+ printBrand?: boolean;
95
+ }
96
+ declare const buildInitSuccessRender: (input: BuildInitRenderInput) => string;
97
+ interface InitOptions {
98
+ printBrand?: boolean;
99
+ }
100
+ declare const initCommand: (directory: string, options?: InitOptions) => Promise<void>;
64
101
  //#endregion
65
- //#region src/commands/scan.d.ts
66
- interface ScanOptions {
67
- changes: boolean;
68
- staged: boolean;
69
- verbose: boolean;
70
- json: boolean;
71
- showHeader?: boolean;
72
- /** Used for telemetry to distinguish scan vs ci invocation */
73
- command?: "scan" | "ci";
102
+ //#region src/commands/rules.d.ts
103
+ interface RuleEntry {
104
+ id: string;
105
+ engine: string;
106
+ severity: "error" | "warning" | "info";
107
+ fixable: boolean;
74
108
  }
75
- declare const scanCommand: (directory: string, config: AislopConfig, options: ScanOptions) => Promise<{
76
- exitCode: number;
77
- }>;
109
+ interface BuildRulesRenderInput {
110
+ rules: RuleEntry[];
111
+ invocation?: string;
112
+ printBrand?: boolean;
113
+ }
114
+ declare const buildRulesRender: (input: BuildRulesRenderInput) => string;
115
+ interface RulesOptions {
116
+ printBrand?: boolean;
117
+ }
118
+ declare const rulesCommand: (directory: string, options?: RulesOptions) => Promise<void>;
78
119
  //#endregion
79
120
  //#region src/utils/discover.d.ts
80
121
  type Language = "typescript" | "javascript" | "python" | "go" | "rust" | "java" | "ruby" | "php";
81
- type Framework = "nextjs" | "react" | "vite" | "remix" | "expo" | "django" | "flask" | "fastapi" | "none";
122
+ type Framework = "nextjs" | "react" | "vite" | "remix" | "expo" | "astro" | "django" | "flask" | "fastapi" | "none";
82
123
  interface ProjectInfo {
83
124
  rootDirectory: string;
84
125
  projectName: string;
@@ -112,6 +153,21 @@ interface EngineResult {
112
153
  skipReason?: string;
113
154
  }
114
155
  //#endregion
156
+ //#region src/commands/scan.d.ts
157
+ interface ScanOptions {
158
+ changes: boolean;
159
+ staged: boolean;
160
+ verbose: boolean;
161
+ json: boolean;
162
+ showHeader?: boolean;
163
+ printBrand?: boolean;
164
+ /** Used for telemetry to distinguish scan vs ci invocation */
165
+ command?: "scan" | "ci";
166
+ }
167
+ declare const scanCommand: (directory: string, config: AislopConfig, options: ScanOptions) => Promise<{
168
+ exitCode: number;
169
+ }>;
170
+ //#endregion
115
171
  //#region src/scoring/index.d.ts
116
172
  interface ScoreResult {
117
173
  score: number;
@@ -122,4 +178,4 @@ declare const calculateScore: (diagnostics: Diagnostic[], weights: Record<string
122
178
  ok: number;
123
179
  }, sourceFileCount?: number, smoothing?: number) => ScoreResult;
124
180
  //#endregion
125
- export { type AislopConfig, type Diagnostic, type EngineName, type EngineResult, type Framework, type Language, type ProjectInfo, type ScoreResult, type Severity, calculateScore, discoverProject, doctorCommand, fixCommand, initCommand, loadConfig, scanCommand };
181
+ export { type AislopConfig, type Diagnostic, type EngineName, type EngineResult, type Framework, type Language, type ProjectInfo, type ScoreResult, type Severity, buildDoctorRender, buildInitSuccessRender, buildRulesRender, calculateScore, discoverProject, doctorCommand, fixCommand, initCommand, loadConfig, rulesCommand, scanCommand };