UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

79 lines • 3.71 kB
// ========= 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 { IOResult } from "../../../io/types.js"; import { command } from "../../config.js"; import { quoteText } from "../../quote.js"; import { specOf } from "../../spec/builtins.js"; import { FlagView } from "../../spec/flag_view.js"; import { UNKNOWN_NAME, identityOf } from "../utils/identity.js"; const ENC = new TextEncoder(); const CONTEXT = 'id: --context (-Z) works only on an SELinux-enabled kernel\n'; const ONE_CHOICE = 'id: cannot print "only" of more than one choice\n'; const NAMES_NEED = 'id: printing only names or real IDs requires -u, -g, or -G\n'; const ZERO_DEFAULT = 'id: option --zero not permitted in default format\n'; // GNU `id` over mirage's identity: the session's profile, as both its user // and its group. Mirage has names but no numbers, so every id slot holds the // name, `-` for a session with no profile; errors and their order are // coreutils 9.7's. function idCmd(_accessor, _paths, texts, ctx) { const fl = new FlagView(ctx.flags, specOf('id')); if (fl.asBool('context')) return [null, new IOResult({ exitCode: 1, stderr: ENC.encode(CONTEXT) })]; const only = ['user', 'group', 'groups'].filter((dest) => fl.asBool(dest)); if (only.length > 1) return [null, new IOResult({ exitCode: 1, stderr: ENC.encode(ONE_CHOICE) })]; const useName = fl.asBool('name'); const zero = fl.asBool('zero'); if (only.length === 0 && (useName || fl.asBool('real'))) return [null, new IOResult({ exitCode: 1, stderr: ENC.encode(NAMES_NEED) })]; if (only.length === 0 && zero) return [null, new IOResult({ exitCode: 1, stderr: ENC.encode(ZERO_DEFAULT) })]; const identity = identityOf(ctx); const user = identity.profile ?? UNKNOWN_NAME; const group = user; const end = zero ? '\0' : '\n'; const out = []; const err = []; const names = texts.length > 0 ? texts : [null]; for (const name of names) { if (name !== null && name !== identity.profile) { const why = name === '' ? ': No such file or directory' : ''; err.push(`id: '${quoteText(name)}': no such user${why}\n`); continue; } const choice = only[0]; if (choice === undefined) { out.push(`uid=${user} gid=${group} groups=${group}${end}`); continue; } const kind = choice === 'user' ? 'user' : 'group'; const known = identity.profile; if (useName && known === null) err.push(`id: cannot find name for ${kind} ID\n`); const many = zero && choice === 'groups' && texts.length > 1; out.push((kind === 'user' ? user : group) + (many ? '\0\0' : end)); } const body = out.join(''); return [ body === '' ? null : ENC.encode(body), new IOResult({ exitCode: err.length > 0 ? 1 : 0, stderr: ENC.encode(err.join('')) }), ]; } export const GENERAL_ID = command({ name: 'id', vfs: null, spec: specOf('id'), fn: idCmd, }); //# sourceMappingURL=id.js.map