@askexenow/exe-os 0.9.261 → 0.9.263
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/bin/exe-forget.js +1 -1
- package/dist/bin/exe-search.js +1 -1
- package/dist/bin/registry-proxy.js +1 -1
- package/dist/{catchup-brief-AY3NXSZ4.js → catchup-brief-VNX2SJ2B.js} +1 -1
- package/dist/{chunk-SHN5O73O.js → chunk-FJUQ5L5R.js} +1 -1
- package/dist/{chunk-LMA3QZCR.js → chunk-KQNVIDBP.js} +9 -4
- package/dist/{chunk-N2MMYJLT.js → chunk-Y32AMMDY.js} +3 -3
- package/dist/hooks/error-recall.js +1 -1
- package/dist/hooks/manifest.json +4 -4
- package/dist/hooks/prompt-submit.js +1 -1
- package/dist/hooks/session-start.js +1 -1
- package/dist/lib/exe-daemon.js +24 -8
- package/dist/lib/hybrid-search.js +1 -1
- package/dist/lib/registry-proxy.js +1 -1
- package/dist/mcp/register-tools.js +3 -3
- package/dist/mcp/server.js +3 -3
- package/dist/{projection-worker-ONHS43GB.js → projection-worker-ZAUKM5Z3.js} +14 -6
- package/dist/{reranker-ECLOD4L4.js → reranker-OZR43HRG.js} +1 -1
- package/package.json +1 -1
- package/release-notes.json +24 -26
- /package/dist/{chunk-PISNYNHN.js → chunk-QCURGNWR.js} +0 -0
package/dist/bin/exe-forget.js
CHANGED
package/dist/bin/exe-search.js
CHANGED
|
@@ -15,7 +15,7 @@ function registryProxyOptionsFromEnv(env = process.env) {
|
|
|
15
15
|
upstreamToken,
|
|
16
16
|
pullTokens,
|
|
17
17
|
allowedNamespace: env.EXE_REGISTRY_PROXY_ALLOWED_NAMESPACE || "askexe",
|
|
18
|
-
licenseValidatorUrl: env.EXE_REGISTRY_PROXY_LICENSE_VALIDATOR_URL || ""
|
|
18
|
+
licenseValidatorUrl: env.EXE_REGISTRY_PROXY_LICENSE_VALIDATOR_URL || "https://api.askexe.com/v1/license/validate"
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
function assertRegistryProxyConfig(options) {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
isRerankerAvailable,
|
|
12
12
|
rerankWithScores
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QCURGNWR.js";
|
|
14
14
|
import {
|
|
15
15
|
getCachedLicenseGate
|
|
16
16
|
} from "./chunk-2WBBVEIB.js";
|
|
@@ -194,7 +194,7 @@ import {
|
|
|
194
194
|
import {
|
|
195
195
|
hybridSearch,
|
|
196
196
|
recentRecords
|
|
197
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-Y32AMMDY.js";
|
|
198
198
|
import {
|
|
199
199
|
attachDocumentMetadata,
|
|
200
200
|
flushBatch,
|
|
@@ -11847,13 +11847,18 @@ function findPackageRoot() {
|
|
|
11847
11847
|
throw new Error("Cannot find package root");
|
|
11848
11848
|
}
|
|
11849
11849
|
var execFileAsync2 = promisify2(execFile2);
|
|
11850
|
+
function childCliEnv() {
|
|
11851
|
+
const env = { ...process.env };
|
|
11852
|
+
delete env.EXE_IS_DAEMON;
|
|
11853
|
+
return env;
|
|
11854
|
+
}
|
|
11850
11855
|
async function runCommand(command, args, timeout = 6e4) {
|
|
11851
11856
|
const printable = [command, ...args].join(" ");
|
|
11852
11857
|
try {
|
|
11853
11858
|
const { stdout, stderr } = await execFileAsync2(command, args, {
|
|
11854
11859
|
timeout,
|
|
11855
11860
|
maxBuffer: 1024 * 1024,
|
|
11856
|
-
env:
|
|
11861
|
+
env: childCliEnv()
|
|
11857
11862
|
});
|
|
11858
11863
|
return { ok: true, command: printable, text: `${stdout}${stderr ? `
|
|
11859
11864
|
${stderr}` : ""}`.trim() || "OK" };
|
|
@@ -11879,7 +11884,7 @@ async function runDistScript(scriptName, args, timeout = 6e4) {
|
|
|
11879
11884
|
const { stdout, stderr } = await execFileAsync2(process.execPath, [scriptPath, ...args], {
|
|
11880
11885
|
timeout,
|
|
11881
11886
|
maxBuffer: 1024 * 1024,
|
|
11882
|
-
env:
|
|
11887
|
+
env: childCliEnv()
|
|
11883
11888
|
});
|
|
11884
11889
|
return { ok: true, command: printable, text: `${stdout}${stderr ? `
|
|
11885
11890
|
${stderr}` : ""}`.trim() || "OK" };
|
|
@@ -288,7 +288,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
288
288
|
let rerankerAvailable = false;
|
|
289
289
|
if (process.env.EXE_IS_DAEMON === "1") {
|
|
290
290
|
try {
|
|
291
|
-
const { isRerankerAvailable } = await import("./reranker-
|
|
291
|
+
const { isRerankerAvailable } = await import("./reranker-OZR43HRG.js");
|
|
292
292
|
rerankerAvailable = isRerankerAvailable();
|
|
293
293
|
} catch {
|
|
294
294
|
}
|
|
@@ -452,7 +452,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
452
452
|
try {
|
|
453
453
|
let rerankedRecords;
|
|
454
454
|
if (graphContextMap.size > 0) {
|
|
455
|
-
const { rerankWithContext } = await import("./reranker-
|
|
455
|
+
const { rerankWithContext } = await import("./reranker-OZR43HRG.js");
|
|
456
456
|
const candidates = merged.map((m) => ({
|
|
457
457
|
text: m.raw_text,
|
|
458
458
|
context: graphContextMap.get(m.id)
|
|
@@ -460,7 +460,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
460
460
|
const scored = await rerankWithContext(effectiveQuery, candidates, rerankReturnLimit);
|
|
461
461
|
rerankedRecords = scored.map((s) => merged[s.index]);
|
|
462
462
|
} else {
|
|
463
|
-
const { rerank } = await import("./reranker-
|
|
463
|
+
const { rerank } = await import("./reranker-OZR43HRG.js");
|
|
464
464
|
rerankedRecords = await rerank(effectiveQuery, merged, rerankReturnLimit);
|
|
465
465
|
}
|
|
466
466
|
if (rerankedRecords.length > 0) {
|
package/dist/hooks/manifest.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"generatedAt": "2026-06-10T02:
|
|
3
|
+
"generatedAt": "2026-06-10T02:59:59.107Z",
|
|
4
4
|
"hashes": {
|
|
5
5
|
"bug-report-worker.js": "5b5c47ed54222e7e9e9099dbe0032076b549d406fd0fad91e4685d345f4d465f",
|
|
6
6
|
"codex-stop-task-finalizer.js": "4470796421e93af8416e83e6822e14acfa72ecc96da6574fbfb38965f2e7d7e6",
|
|
7
7
|
"commit-complete.js": "d6a053e16241909b3ded37c13fa2868bf93f0fe593b5dcc2d7117fd367744861",
|
|
8
|
-
"error-recall.js": "
|
|
8
|
+
"error-recall.js": "3e1bb5b447fe8a7fe935e530a4534db1d455f36f361aac677da47ad413e5c2ce",
|
|
9
9
|
"exe-heartbeat-hook.js": "351dd0a9c4c1f21bf7faa3a5431b0f71f6f55bc629a6503394e1e696a9589b08",
|
|
10
10
|
"ingest-worker.js": "1f6a591f863d5bc540b0e11bb382d3ba13cf761709e4a82313f6f1d9fb9c18e2",
|
|
11
11
|
"ingest.js": "f040375367df68749331bbf3ea5527b754840f0ed2db621c966abe51b6375890",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"post-tool-combined.js": "3fbbb2d941e264291567a6da97bb02523c907a0edf742ef6d59b13e5956cd4f8",
|
|
16
16
|
"pre-compact.js": "8e7512e75a0407a5c632ebfb5f23595507c5d8972afcae839462f719ea56a973",
|
|
17
17
|
"pre-tool-use.js": "f50d7d8b341109bf5f927295d9227877b691989fdf3ef04565e7579dfac8a66a",
|
|
18
|
-
"prompt-submit.js": "
|
|
18
|
+
"prompt-submit.js": "399134512a15b121a8fc2dae7564faf5d56a3e6bb056fa5f791109ba1df47636",
|
|
19
19
|
"session-end.js": "b88b3007dadaa427f748154551790648742627ac788a8fa8f76761ad8b45ef90",
|
|
20
|
-
"session-start.js": "
|
|
20
|
+
"session-start.js": "acdaf676b827e047abbc66b32ffad23a12f889b42b3d7cdaa7619be4beb850a9",
|
|
21
21
|
"stop.js": "ab962df8d9b91f04e3eb3708e67300fb0f64cd57c25d814312bc84485c4d00ae",
|
|
22
22
|
"subagent-stop.js": "626924150de92ca5e509066b016950d6ce62d4df5e58a0d0713a4d36705aaefc",
|
|
23
23
|
"summary-worker.js": "dc0ac0448fbec252aacccf8b8a2dfe2e296ee0306e5ce41b1362db2318307b66"
|
|
@@ -163,7 +163,7 @@ You are **${ag.agentId}**. Daemon is degraded \u2014 memory unavailable.
|
|
|
163
163
|
query = `last actions on ${projectName}`;
|
|
164
164
|
header = "## Resuming Session\nHere's where you left off:";
|
|
165
165
|
try {
|
|
166
|
-
const { buildCatchupBrief } = await import("../catchup-brief-
|
|
166
|
+
const { buildCatchupBrief } = await import("../catchup-brief-VNX2SJ2B.js");
|
|
167
167
|
const brief = await buildCatchupBrief(
|
|
168
168
|
agentId,
|
|
169
169
|
projectName,
|
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -1230,7 +1230,7 @@ async function shutdown() {
|
|
|
1230
1230
|
`);
|
|
1231
1231
|
}
|
|
1232
1232
|
try {
|
|
1233
|
-
const { stopProjectionWorker } = await import("../projection-worker-
|
|
1233
|
+
const { stopProjectionWorker } = await import("../projection-worker-ZAUKM5Z3.js");
|
|
1234
1234
|
stopProjectionWorker();
|
|
1235
1235
|
} catch {
|
|
1236
1236
|
}
|
|
@@ -2036,12 +2036,13 @@ async function startMcpHttpServer() {
|
|
|
2036
2036
|
if (now - lastSeen > MCP_SESSION_TTL_MS) closeMcpSession2(sid, "session_expired");
|
|
2037
2037
|
}
|
|
2038
2038
|
}
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2039
|
+
if (MCP_ZOMBIE_THRESHOLD_MS > 0) {
|
|
2040
|
+
for (const [sid, lastSeen] of sessionLastSeen) {
|
|
2041
|
+
if (now - lastSeen > MCP_ZOMBIE_THRESHOLD_MS) {
|
|
2042
|
+
closeMcpSession2(sid, "zombie_full_cleanup");
|
|
2043
|
+
process.stderr.write(`[exed] MCP session ${sid.slice(0, 8)}\u2026 fully released (inactive ${Math.round((now - lastSeen) / 6e4)}m)
|
|
2044
2044
|
`);
|
|
2045
|
+
}
|
|
2045
2046
|
}
|
|
2046
2047
|
}
|
|
2047
2048
|
const mem = process.memoryUsage();
|
|
@@ -2135,7 +2136,8 @@ async function startMcpHttpServer() {
|
|
|
2135
2136
|
const MAX_MCP_SESSIONS = Number(process.env.EXE_MAX_MCP_SESSIONS) || 50;
|
|
2136
2137
|
const MCP_SESSION_SWEEP_MS = parseDurationMs2(process.env.EXE_MCP_SESSION_SWEEP_MS, 60 * 1e3);
|
|
2137
2138
|
const MCP_RECOVERY_ALIAS_TTL_MS = parseDurationMs2(process.env.EXE_MCP_RECOVERY_ALIAS_TTL_MS, 30 * 60 * 1e3);
|
|
2138
|
-
const
|
|
2139
|
+
const MCP_ZOMBIE_THRESHOLD_MS = parseDurationMs2(process.env.EXE_MCP_ZOMBIE_THRESHOLD_MS, 0, { allowZero: true });
|
|
2140
|
+
const MCP_PRESSURE_EVICT_MIN_IDLE_MS = parseDurationMs2(process.env.EXE_MCP_PRESSURE_EVICT_MIN_IDLE_MS, 2 * 60 * 60 * 1e3);
|
|
2139
2141
|
const sessionLastSeen = /* @__PURE__ */ new Map();
|
|
2140
2142
|
const sessionDetails = /* @__PURE__ */ new Map();
|
|
2141
2143
|
const staleSessionRecoveries = /* @__PURE__ */ new Map();
|
|
@@ -2688,6 +2690,20 @@ async function startMcpHttpServer() {
|
|
|
2688
2690
|
const recovered = await createRecoveredMcpSession(sessionId, details);
|
|
2689
2691
|
transport = recovered.transport;
|
|
2690
2692
|
req.headers["mcp-session-id"] = recovered.sessionId;
|
|
2693
|
+
} else if (sessionId && !transports.has(sessionId) && req.method === "DELETE") {
|
|
2694
|
+
recordMcpHttpEvent({
|
|
2695
|
+
level: "info",
|
|
2696
|
+
message: "session_delete_stale_ignored",
|
|
2697
|
+
method: req.method,
|
|
2698
|
+
sessionId,
|
|
2699
|
+
agentId,
|
|
2700
|
+
agentRole,
|
|
2701
|
+
runtime,
|
|
2702
|
+
activeSessions: transports.size
|
|
2703
|
+
});
|
|
2704
|
+
res.writeHead(204);
|
|
2705
|
+
res.end();
|
|
2706
|
+
return;
|
|
2691
2707
|
} else {
|
|
2692
2708
|
const message = sessionId ? "Bad Request: MCP session is stale or unknown; reconnect MCP client" : "Bad Request: missing MCP session; initialize before tool calls";
|
|
2693
2709
|
sendJsonRpcError2(res, 400, message, getJsonRpcId2(parsedBody), {
|
|
@@ -4980,7 +4996,7 @@ try {
|
|
|
4980
4996
|
process.stderr.write("[exed] Tool telemetry started (flush every 5m)\n");
|
|
4981
4997
|
setTimeout(async () => {
|
|
4982
4998
|
try {
|
|
4983
|
-
const { startProjectionWorker } = await import("../projection-worker-
|
|
4999
|
+
const { startProjectionWorker } = await import("../projection-worker-ZAUKM5Z3.js");
|
|
4984
5000
|
startProjectionWorker();
|
|
4985
5001
|
} catch {
|
|
4986
5002
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerAllTools
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-KQNVIDBP.js";
|
|
4
4
|
import "../chunk-O4D4DSNZ.js";
|
|
5
5
|
import "../chunk-557C2IGL.js";
|
|
6
6
|
import "../chunk-KPVRGCOC.js";
|
|
7
7
|
import "../chunk-PK7H6FFK.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-QCURGNWR.js";
|
|
9
9
|
import "../chunk-2WBBVEIB.js";
|
|
10
10
|
import "../chunk-AU64ZSNH.js";
|
|
11
11
|
import "../chunk-BBPRL2MP.js";
|
|
@@ -61,7 +61,7 @@ import "../chunk-GMUZHA5J.js";
|
|
|
61
61
|
import "../chunk-45W7EDXB.js";
|
|
62
62
|
import "../chunk-Z2AEOVEZ.js";
|
|
63
63
|
import "../chunk-7IZWLMTP.js";
|
|
64
|
-
import "../chunk-
|
|
64
|
+
import "../chunk-Y32AMMDY.js";
|
|
65
65
|
import "../chunk-6YHVX54O.js";
|
|
66
66
|
import "../chunk-CHCA3ZM2.js";
|
|
67
67
|
import "../chunk-P2XNRKEL.js";
|
package/dist/mcp/server.js
CHANGED
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
} from "../chunk-V4TZI6EO.js";
|
|
4
4
|
import {
|
|
5
5
|
registerAllTools
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-KQNVIDBP.js";
|
|
7
7
|
import "../chunk-O4D4DSNZ.js";
|
|
8
8
|
import "../chunk-557C2IGL.js";
|
|
9
9
|
import "../chunk-KPVRGCOC.js";
|
|
10
10
|
import "../chunk-PK7H6FFK.js";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-QCURGNWR.js";
|
|
12
12
|
import {
|
|
13
13
|
initLicenseGate
|
|
14
14
|
} from "../chunk-2WBBVEIB.js";
|
|
@@ -71,7 +71,7 @@ import "../chunk-GMUZHA5J.js";
|
|
|
71
71
|
import "../chunk-45W7EDXB.js";
|
|
72
72
|
import "../chunk-Z2AEOVEZ.js";
|
|
73
73
|
import "../chunk-7IZWLMTP.js";
|
|
74
|
-
import "../chunk-
|
|
74
|
+
import "../chunk-Y32AMMDY.js";
|
|
75
75
|
import {
|
|
76
76
|
disposeStore,
|
|
77
77
|
initStore
|
|
@@ -656,19 +656,27 @@ var projectionHandlers = {
|
|
|
656
656
|
targets.push("graph");
|
|
657
657
|
await ensureFilteredSchema(prisma);
|
|
658
658
|
const senderName = payload.sender_name ?? payload.contact_name ?? null;
|
|
659
|
-
const
|
|
659
|
+
const rawSender = payload.from ?? payload.phone ?? null;
|
|
660
660
|
const threadId = payload.conversation_id ?? payload.chat_id ?? event.source_id;
|
|
661
|
-
if (
|
|
661
|
+
if (rawSender) {
|
|
662
|
+
const bareSender = rawSender.replace(/@.*$/, "");
|
|
663
|
+
const phone = !rawSender.endsWith("@lid") && /^\+?\d{6,20}$/.test(bareSender) ? bareSender : null;
|
|
664
|
+
const name = senderName ?? phone ?? "Unknown (WhatsApp)";
|
|
662
665
|
const contactResult = await prisma.$queryRawUnsafe(
|
|
663
666
|
`INSERT INTO "filtered"."contacts" ("name", "phone", "platform", "platform_id", "last_seen")
|
|
664
667
|
VALUES ($1, $2, 'whatsapp', $3, $4)
|
|
665
668
|
ON CONFLICT ("platform", "platform_id") DO UPDATE SET
|
|
666
|
-
"name" =
|
|
669
|
+
"name" = CASE
|
|
670
|
+
WHEN EXCLUDED."name" IS NOT NULL AND EXCLUDED."name" <> 'Unknown (WhatsApp)' THEN EXCLUDED."name"
|
|
671
|
+
WHEN "filtered"."contacts"."name" ~ '@(lid|s\\.whatsapp\\.net)$' THEN EXCLUDED."name"
|
|
672
|
+
ELSE "filtered"."contacts"."name"
|
|
673
|
+
END,
|
|
674
|
+
"phone" = COALESCE(EXCLUDED."phone", "filtered"."contacts"."phone"),
|
|
667
675
|
"last_seen" = GREATEST("filtered"."contacts"."last_seen", EXCLUDED."last_seen")
|
|
668
676
|
RETURNING "id"`,
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
677
|
+
name,
|
|
678
|
+
phone,
|
|
679
|
+
rawSender,
|
|
672
680
|
event.timestamp
|
|
673
681
|
);
|
|
674
682
|
const contactId = contactResult[0]?.id;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.263",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
package/release-notes.json
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
{
|
|
2
|
-
"current": "0.9.
|
|
2
|
+
"current": "0.9.263",
|
|
3
3
|
"notes": {
|
|
4
|
+
"0.9.263": {
|
|
5
|
+
"version": "0.9.263",
|
|
6
|
+
"date": "2026-06-10",
|
|
7
|
+
"features": [],
|
|
8
|
+
"fixes": [
|
|
9
|
+
"harden diagnostics registry and projections",
|
|
10
|
+
"human-readable contact fallback for WhatsApp @lid senders"
|
|
11
|
+
],
|
|
12
|
+
"security": [],
|
|
13
|
+
"other": [],
|
|
14
|
+
"migration_notes": []
|
|
15
|
+
},
|
|
16
|
+
"0.9.262": {
|
|
17
|
+
"version": "0.9.262",
|
|
18
|
+
"date": "2026-06-10",
|
|
19
|
+
"features": [],
|
|
20
|
+
"fixes": [
|
|
21
|
+
"harden MCP session retention"
|
|
22
|
+
],
|
|
23
|
+
"security": [],
|
|
24
|
+
"other": [],
|
|
25
|
+
"migration_notes": []
|
|
26
|
+
},
|
|
4
27
|
"0.9.261": {
|
|
5
28
|
"version": "0.9.261",
|
|
6
29
|
"date": "2026-06-10",
|
|
@@ -37,31 +60,6 @@
|
|
|
37
60
|
"security": [],
|
|
38
61
|
"other": [],
|
|
39
62
|
"migration_notes": []
|
|
40
|
-
},
|
|
41
|
-
"0.9.258": {
|
|
42
|
-
"version": "0.9.258",
|
|
43
|
-
"date": "2026-06-10",
|
|
44
|
-
"features": [],
|
|
45
|
-
"fixes": [
|
|
46
|
-
"align filtered.conversations init schema with projection-worker source_ref dedup",
|
|
47
|
-
"keep projection-worker empty-queue test compatible with startup schema self-heal"
|
|
48
|
-
],
|
|
49
|
-
"security": [],
|
|
50
|
-
"other": [],
|
|
51
|
-
"migration_notes": [
|
|
52
|
-
"Fresh stack DBs now create filtered.conversations.source_ref with UNIQUE(platform, source_ref); existing stacks self-heal on projection-worker startup."
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
"0.9.256": {
|
|
56
|
-
"version": "0.9.256",
|
|
57
|
-
"date": "2026-06-09",
|
|
58
|
-
"features": [],
|
|
59
|
-
"fixes": [],
|
|
60
|
-
"security": [],
|
|
61
|
-
"other": [
|
|
62
|
-
"bump v0.9.256 — all images verified on GHCR"
|
|
63
|
-
],
|
|
64
|
-
"migration_notes": []
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
}
|
|
File without changes
|