teamcopilot 0.1.1 → 0.1.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/dist/utils/redact.js +0 -2
- package/dist/utils/resource-files.js +41 -131
- package/package.json +2 -1
package/dist/utils/redact.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.maskValue = maskValue;
|
|
4
|
-
exports.isLikelySensitiveKey = isLikelySensitiveKey;
|
|
5
3
|
exports.sanitizeStringContent = sanitizeStringContent;
|
|
6
4
|
exports.sanitizeForClient = sanitizeForClient;
|
|
7
5
|
const SENSITIVE_KEY_PATTERN = /(token|secret|password|passwd|api[_-]?key|auth|credential)/i;
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createResourceFileManager = createResourceFileManager;
|
|
7
7
|
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const diff_1 = require("diff");
|
|
8
9
|
const fs_1 = __importDefault(require("fs"));
|
|
9
10
|
const path_1 = __importDefault(require("path"));
|
|
10
11
|
const redact_1 = require("./redact");
|
|
@@ -137,19 +138,6 @@ function createResourceFileManager(options) {
|
|
|
137
138
|
};
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
|
-
function findClosingQuoteIndex(input, quote) {
|
|
141
|
-
for (let i = 1; i < input.length; i += 1) {
|
|
142
|
-
const ch = input[i];
|
|
143
|
-
if (ch === "\\") {
|
|
144
|
-
i += 1;
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (ch === quote) {
|
|
148
|
-
return i;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return -1;
|
|
152
|
-
}
|
|
153
141
|
function toFileNode(parentRelativePath, name, absolutePath) {
|
|
154
142
|
const lstat = fs_1.default.lstatSync(absolutePath);
|
|
155
143
|
const isDir = lstat.isDirectory();
|
|
@@ -199,131 +187,52 @@ function createResourceFileManager(options) {
|
|
|
199
187
|
}
|
|
200
188
|
return false;
|
|
201
189
|
}
|
|
202
|
-
function
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
prefix,
|
|
216
|
-
key,
|
|
217
|
-
separator,
|
|
218
|
-
quote: '"',
|
|
219
|
-
value: remainder.slice(1, closeIdx),
|
|
220
|
-
suffix: remainder.slice(closeIdx + 1),
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
if (remainder.startsWith("'")) {
|
|
224
|
-
const closeIdx = findClosingQuoteIndex(remainder, "'");
|
|
225
|
-
if (closeIdx === -1) {
|
|
226
|
-
return { kind: "other" };
|
|
190
|
+
function buildSanitizedBoundaryMap(raw, sanitized) {
|
|
191
|
+
const boundaries = Array(sanitized.length + 1).fill(raw.length);
|
|
192
|
+
let rawIndex = 0;
|
|
193
|
+
let sanitizedIndex = 0;
|
|
194
|
+
boundaries[0] = 0;
|
|
195
|
+
for (const change of (0, diff_1.diffChars)(raw, sanitized)) {
|
|
196
|
+
const segmentLength = change.value.length;
|
|
197
|
+
if (change.added) {
|
|
198
|
+
for (let offset = 0; offset < segmentLength; offset += 1) {
|
|
199
|
+
sanitizedIndex += 1;
|
|
200
|
+
boundaries[sanitizedIndex] = rawIndex;
|
|
201
|
+
}
|
|
202
|
+
continue;
|
|
227
203
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
key,
|
|
232
|
-
separator,
|
|
233
|
-
quote: "'",
|
|
234
|
-
value: remainder.slice(1, closeIdx),
|
|
235
|
-
suffix: remainder.slice(closeIdx + 1),
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
const commentStart = remainder.search(/\s#/);
|
|
239
|
-
if (commentStart === -1) {
|
|
240
|
-
return {
|
|
241
|
-
kind: "assignment",
|
|
242
|
-
prefix,
|
|
243
|
-
key,
|
|
244
|
-
separator,
|
|
245
|
-
quote: null,
|
|
246
|
-
value: remainder.trim(),
|
|
247
|
-
suffix: "",
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
const valuePart = remainder.slice(0, commentStart).trim();
|
|
251
|
-
const suffix = remainder.slice(commentStart);
|
|
252
|
-
return {
|
|
253
|
-
kind: "assignment",
|
|
254
|
-
prefix,
|
|
255
|
-
key,
|
|
256
|
-
separator,
|
|
257
|
-
quote: null,
|
|
258
|
-
value: valuePart,
|
|
259
|
-
suffix,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
function serializeEnvAssignment(parsed) {
|
|
263
|
-
if (parsed.quote === '"') {
|
|
264
|
-
return `${parsed.prefix}${parsed.key}${parsed.separator}"${parsed.value}"${parsed.suffix}`;
|
|
265
|
-
}
|
|
266
|
-
if (parsed.quote === "'") {
|
|
267
|
-
return `${parsed.prefix}${parsed.key}${parsed.separator}'${parsed.value}'${parsed.suffix}`;
|
|
268
|
-
}
|
|
269
|
-
return `${parsed.prefix}${parsed.key}${parsed.separator}${parsed.value}${parsed.suffix}`;
|
|
270
|
-
}
|
|
271
|
-
function splitLinesPreserveNewline(input) {
|
|
272
|
-
const parts = [];
|
|
273
|
-
const regex = /([^\r\n]*)(\r\n|\n|\r|$)/g;
|
|
274
|
-
let match;
|
|
275
|
-
while ((match = regex.exec(input)) !== null) {
|
|
276
|
-
const line = match[1];
|
|
277
|
-
const newline = match[2];
|
|
278
|
-
if (line === "" && newline === "" && match.index === input.length) {
|
|
279
|
-
break;
|
|
204
|
+
if (change.removed) {
|
|
205
|
+
rawIndex += segmentLength;
|
|
206
|
+
continue;
|
|
280
207
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
208
|
+
for (let offset = 0; offset < segmentLength; offset += 1) {
|
|
209
|
+
rawIndex += 1;
|
|
210
|
+
sanitizedIndex += 1;
|
|
211
|
+
boundaries[sanitizedIndex] = rawIndex;
|
|
284
212
|
}
|
|
285
213
|
}
|
|
286
|
-
return
|
|
214
|
+
return boundaries;
|
|
287
215
|
}
|
|
288
|
-
function
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
for (const item of currentLines) {
|
|
293
|
-
const parsed = parseEnvAssignmentLine(item.line);
|
|
294
|
-
if (parsed.kind !== "assignment")
|
|
295
|
-
continue;
|
|
296
|
-
const arr = currentQueuesByKey.get(parsed.key) ?? [];
|
|
297
|
-
arr.push(parsed);
|
|
298
|
-
currentQueuesByKey.set(parsed.key, arr);
|
|
216
|
+
function mergeRedactedEditorContent(currentRaw, editedContent) {
|
|
217
|
+
const sanitizedCurrent = (0, redact_1.sanitizeStringContent)(currentRaw);
|
|
218
|
+
if (editedContent === sanitizedCurrent) {
|
|
219
|
+
return currentRaw;
|
|
299
220
|
}
|
|
221
|
+
const boundaries = buildSanitizedBoundaryMap(currentRaw, sanitizedCurrent);
|
|
300
222
|
const output = [];
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (
|
|
304
|
-
output.push(
|
|
305
|
-
continue;
|
|
306
|
-
}
|
|
307
|
-
const queue = currentQueuesByKey.get(parsedEdited.key);
|
|
308
|
-
const currentParsed = queue?.shift();
|
|
309
|
-
if (!currentParsed) {
|
|
310
|
-
output.push(item.line + item.newline);
|
|
223
|
+
let sanitizedIndex = 0;
|
|
224
|
+
for (const change of (0, diff_1.diffChars)(sanitizedCurrent, editedContent)) {
|
|
225
|
+
if (change.added) {
|
|
226
|
+
output.push(change.value);
|
|
311
227
|
continue;
|
|
312
228
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
229
|
+
const nextSanitizedIndex = sanitizedIndex + change.value.length;
|
|
230
|
+
const rawStart = boundaries[sanitizedIndex] ?? currentRaw.length;
|
|
231
|
+
const rawEnd = boundaries[nextSanitizedIndex] ?? currentRaw.length;
|
|
232
|
+
if (!change.removed) {
|
|
233
|
+
output.push(currentRaw.slice(rawStart, rawEnd));
|
|
316
234
|
}
|
|
317
|
-
|
|
318
|
-
if (parsedEdited.value !== maskedCurrent) {
|
|
319
|
-
output.push(item.line + item.newline);
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
322
|
-
const mergedLine = serializeEnvAssignment({
|
|
323
|
-
...parsedEdited,
|
|
324
|
-
value: currentParsed.value,
|
|
325
|
-
});
|
|
326
|
-
output.push(mergedLine + item.newline);
|
|
235
|
+
sanitizedIndex = nextSanitizedIndex;
|
|
327
236
|
}
|
|
328
237
|
return output.join("");
|
|
329
238
|
}
|
|
@@ -435,9 +344,10 @@ function createResourceFileManager(options) {
|
|
|
435
344
|
};
|
|
436
345
|
}
|
|
437
346
|
const name = path_1.default.basename(relativePath);
|
|
438
|
-
const
|
|
439
|
-
const
|
|
440
|
-
|
|
347
|
+
const currentRawContent = currentBytes.toString("utf-8");
|
|
348
|
+
const wasServedRedacted = name === ".env" || resourceLabel === "skill";
|
|
349
|
+
const nextContent = wasServedRedacted
|
|
350
|
+
? mergeRedactedEditorContent(currentRawContent, request.content)
|
|
441
351
|
: request.content;
|
|
442
352
|
fs_1.default.writeFileSync(absolutePath, nextContent, "utf-8");
|
|
443
353
|
const nextBytes = fs_1.default.readFileSync(absolutePath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teamcopilot",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A shared AI Agent for Teams",
|
|
5
5
|
"homepage": "https://teamcopilot.ai",
|
|
6
6
|
"repository": {
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"cookie-parser": "^1.4.7",
|
|
66
66
|
"cors": "^2.8.5",
|
|
67
67
|
"cron": "^4.4.0",
|
|
68
|
+
"diff": "^8.0.4",
|
|
68
69
|
"dotenv": "^16.4.7",
|
|
69
70
|
"express": "^4.21.2",
|
|
70
71
|
"ignore": "^7.0.5",
|