@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
80 lines (79 loc) • 3.8 kB
JavaScript
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
import { follow as discordFollow, readMany as discordReadMany, readRange as discordReadRange, readStream as discordReadStream, } from "../../core/discord/read.js";
import { readdir as discordReaddir } from "../../core/discord/readdir.js";
import { stat as discordStat } from "../../core/discord/stat.js";
import {} from "../../io/types.js";
import { BaseVFS } from "../base.js";
export const VFS_MD = `\`\`\`text
{prefix}
<guild-name>__<guild-id>/
channels/
<channel-name>__<channel-id>/
<yyyy-mm-dd>/
chat.jsonl # messages for that date
files/ # attachments shared that day
<name>__<att-id>.<ext> # cat downloads it from Discord's CDN
members/
<username>__<user-id>.json # member profile
\`\`\`
- A guild, channel, member or attachment name is \`<display-name>__<id>\`.
The display name keeps Discord's spelling (spaces, apostrophes, emoji);
only \`/\` becomes \`∕\` (U+2215). \`ls\` the parent first to find exact
names, and quote a name that has spaces.
- Messages are JSONL; use \`jq\` for fields such as \`.content\`,
\`.author.username\` and \`.attachments\`. A day's \`files/\` may be empty.
- Without \`start_time\`/\`end_time\`, a channel lists the latest 30 days up
to its newest message; a date glob finds earlier days.
- With \`start_time\`/\`end_time\`, listings cover that scope; messages and
attachments outside it are absent, direct paths included. Users and
channel metadata stay available as context.
- \`grep\` and \`rg\` read the files they reach, so \`grep\` needs \`-r\` for a
directory. Under a channel that reads every listed day, attachments
included: they download from the CDN, and binary ones such as JPG or
PDF produce noise.`;
/**
* Discord's functions over its accessor, which the node and browser
* packages build over their own transport.
*/
export class DiscordVFS extends BaseVFS {
readsRanges = true;
handed = {
readdir: ['entry'],
read: ['entry', 'parent'],
follow: ['entry', 'parent'],
readMany: ['entry', 'parent'],
stat: ['entry', 'parent'],
};
readdir(path, handed) {
return discordReaddir(this.accessor, path, handed?.entry, null, handed?.limit);
}
read(path, handed, offset = 0, size = null, signal) {
const entry = handed?.entry ?? null;
const parent = handed?.parent ?? null;
if (offset === 0 && size === null)
return discordReadStream(this.accessor, path, handed?.entry, handed?.parent, signal);
return discordReadRange(this.accessor, path, entry, parent, size === null ? { offset } : { offset, size });
}
readMany(paths, limit, handed) {
return discordReadMany(this.accessor, paths, limit, handed);
}
follow(path, n, interval, handed) {
return discordFollow(this.accessor, path, n, interval, handed?.entry, handed?.parent);
}
stat(path, handed) {
return discordStat(this.accessor, path, handed?.entry, handed?.parent);
}
}
//# sourceMappingURL=discord.js.map