pilotignore 0.1.2 → 0.2.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.
@@ -1,178 +0,0 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
-
4
- // Helper function for logging
5
- function appendLog(cwd, message) {
6
- try {
7
- const logDir = path.join(cwd, ".copilot", "logs");
8
- const logFile = path.join(logDir, "pilotignore.log");
9
-
10
- // Ensure the log directory exists
11
- if (!fs.existsSync(logDir)) {
12
- fs.mkdirSync(logDir, { recursive: true });
13
- }
14
-
15
- const timestamp = new Date().toISOString();
16
- fs.appendFileSync(logFile, `[${timestamp}] ${message}\n`);
17
- } catch (e) {
18
- // If logging fails, do not crash the entire program
19
- }
20
- }
21
-
22
- let input = "";
23
- process.stdin.setEncoding("utf8");
24
- process.stdin.on("data", (chunk) => {
25
- input += chunk;
26
- });
27
-
28
- process.stdin.on("end", () => {
29
- // Default cwd, updated if a better one is found in the payload
30
- let currentCwd = process.cwd();
31
- appendLog(currentCwd, `HOOK PROCESS STARTED (pid: ${process.pid})`);
32
-
33
- try {
34
- const payload = JSON.parse(input || "{}");
35
- currentCwd = payload.cwd || currentCwd; // Use the project root
36
-
37
- const candidates = [];
38
- function collect(val) {
39
- if (!val) return;
40
- if (typeof val === "string") {
41
- try {
42
- const parsed = JSON.parse(val);
43
- if (parsed && typeof parsed === "object") {
44
- collect(parsed);
45
- return;
46
- }
47
- } catch (e) {}
48
- candidates.push(val);
49
- return;
50
- }
51
- if (Array.isArray(val)) {
52
- val.forEach(collect);
53
- return;
54
- }
55
- if (typeof val === "object") {
56
- Object.values(val).forEach(collect);
57
- return;
58
- }
59
- candidates.push(String(val));
60
- }
61
-
62
- if (payload.tool_input) collect(payload.tool_input);
63
- if (
64
- payload.tool_input_as_string &&
65
- typeof payload.tool_input_as_string === "string"
66
- ) {
67
- try {
68
- collect(JSON.parse(payload.tool_input_as_string));
69
- } catch (e) {}
70
- }
71
-
72
- if (payload.toolArgs) collect(payload.toolArgs);
73
- if (payload.arguments) collect(payload.arguments);
74
-
75
- if (candidates.length === 0) {
76
- collect(payload);
77
- }
78
-
79
- [
80
- "path",
81
- "file",
82
- "target",
83
- "filePath",
84
- "args",
85
- "files",
86
- "targetPath",
87
- "file_path",
88
- ].forEach((k) => collect(payload[k]));
89
-
90
- appendLog(currentCwd, `Candidate paths: ${JSON.stringify(candidates)}`);
91
-
92
- const ignoreRules = [];
93
- const ignoreFilePath = path.join(currentCwd, ".pilotignore");
94
- if (fs.existsSync(ignoreFilePath)) {
95
- const content = fs.readFileSync(ignoreFilePath, "utf8");
96
- content.split(/\r?\n/).forEach((line) => {
97
- const trimmed = line.trim();
98
- if (trimmed && !trimmed.startsWith("#")) ignoreRules.push(trimmed);
99
- });
100
- appendLog(
101
- currentCwd,
102
- `Loaded ${ignoreRules.length} rules from the .pilotignore file.`,
103
- );
104
- } else {
105
- appendLog(
106
- currentCwd,
107
- `Warning: .pilotignore file not found at path ${ignoreFilePath}`,
108
- );
109
- }
110
-
111
- const isBlocked = candidates.some((candidate) => {
112
- const absolutePath = path.resolve(currentCwd, candidate);
113
- const relative = path.relative(currentCwd, absolutePath).replace(/\\/g, "/");
114
-
115
- return ignoreRules.some((rule) => {
116
- const cleanRule = rule.endsWith("/") ? rule.slice(0, -1) : rule;
117
-
118
- const relLower = relative.toLowerCase();
119
- const ruleLower = cleanRule.toLowerCase();
120
-
121
- if (relLower === ruleLower) return true;
122
- if (relLower.startsWith(ruleLower + "/")) return true;
123
- if (relLower.endsWith("/" + ruleLower)) return true;
124
- if (relLower.includes("/" + ruleLower + "/")) return true;
125
-
126
- return false;
127
- });
128
- });
129
-
130
- if (isBlocked) {
131
- const reason = "File reading is blocked based on a .pilotignore rule.";
132
- appendLog(
133
- currentCwd,
134
- `DECISION: DENY (Blocked) - Path found on the blocklist.`,
135
- );
136
-
137
- console.log(
138
- JSON.stringify({
139
- hookSpecificOutput: {
140
- hookEventName: "PreToolUse",
141
- permissionDecision: "deny",
142
- permissionDecisionReason: reason,
143
- },
144
- }),
145
- );
146
-
147
- console.error(reason);
148
-
149
- if (input.includes("vscode") || input.includes("copilot-chat")) {
150
- process.exit(0); // copilot chat VS Code IDE
151
- } else {
152
- process.exit(2); // copilot CLI
153
- }
154
- }
155
-
156
- appendLog(currentCwd, `DECISION: ALLOW`);
157
- console.log(
158
- JSON.stringify({
159
- hookSpecificOutput: {
160
- hookEventName: "PreToolUse",
161
- permissionDecision: "allow",
162
- },
163
- }),
164
- );
165
- process.exit(0);
166
- } catch (err) {
167
- appendLog(currentCwd, `ERROR: ${err.message}`);
168
- console.log(
169
- JSON.stringify({
170
- hookSpecificOutput: {
171
- hookEventName: "PreToolUse",
172
- permissionDecision: "allow",
173
- },
174
- }),
175
- );
176
- process.exit(0);
177
- }
178
- });