@master4n/master-cli 3.0.2 → 3.0.3
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/README.md +82 -21
- package/SECURITY.md +90 -0
- package/bin/catalog.agent.d.ts +3 -0
- package/bin/catalog.classic.d.ts +3 -0
- package/bin/catalog.d.ts +5 -1
- package/bin/catalog.os.d.ts +7 -0
- package/bin/catalog.power.d.ts +7 -0
- package/bin/commands/base.d.ts +7 -0
- package/bin/commands/calc.d.ts +7 -0
- package/bin/commands/case.d.ts +7 -0
- package/bin/commands/clip.d.ts +7 -0
- package/bin/commands/count.d.ts +7 -0
- package/bin/commands/cron.d.ts +7 -0
- package/bin/commands/cron.engine.d.ts +18 -0
- package/bin/commands/diff.d.ts +7 -0
- package/bin/commands/disk.d.ts +7 -0
- package/bin/commands/dns.d.ts +7 -0
- package/bin/commands/dotenv.d.ts +7 -0
- package/bin/commands/env.d.ts +7 -0
- package/bin/commands/epoch.interactive.d.ts +6 -0
- package/bin/commands/escape.d.ts +7 -0
- package/bin/commands/ext.d.ts +7 -0
- package/bin/commands/freq.d.ts +7 -0
- package/bin/commands/have.d.ts +7 -0
- package/bin/commands/http.d.ts +7 -0
- package/bin/commands/imports.d.ts +7 -0
- package/bin/commands/index.d.ts +38 -1
- package/bin/commands/ip.d.ts +7 -0
- package/bin/commands/json.d.ts +7 -0
- package/bin/commands/lines.d.ts +7 -0
- package/bin/commands/notify.d.ts +7 -0
- package/bin/commands/open.d.ts +7 -0
- package/bin/commands/outline.d.ts +7 -0
- package/bin/commands/outline.engine.d.ts +13 -0
- package/bin/commands/pkg.d.ts +7 -0
- package/bin/commands/ports.d.ts +7 -0
- package/bin/commands/procs.d.ts +7 -0
- package/bin/commands/recent.d.ts +7 -0
- package/bin/commands/regex.d.ts +7 -0
- package/bin/commands/replace.d.ts +7 -0
- package/bin/commands/repo.d.ts +7 -0
- package/bin/commands/schema.d.ts +7 -0
- package/bin/commands/semver.d.ts +7 -0
- package/bin/commands/size.d.ts +7 -0
- package/bin/commands/sys.d.ts +7 -0
- package/bin/commands/trash.d.ts +7 -0
- package/bin/commands/url.d.ts +7 -0
- package/bin/commands/wait.d.ts +7 -0
- package/bin/index.js +6 -6
- package/bin/index.js.map +1 -1
- package/bin/interface/CliCommand.d.ts +15 -0
- package/bin/interface/index.d.ts +1 -0
- package/bin/utility/guard.d.ts +28 -0
- package/bin/utility/index.d.ts +1 -1
- package/bin/utility/suggest.d.ts +6 -0
- package/llms.txt +114 -45
- package/package.json +5 -1
package/bin/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import e from"yargs";import{format as t}from"util";import n,{resolve as o,normalize as r}from"path";import s,{readFileSync as
|
|
2
|
+
import e from"yargs";import{format as t}from"util";import n,{resolve as o,normalize as r}from"path";import s,{readFileSync as i,writeFile as a,statSync as l}from"fs";import"assert";import{fileURLToPath as c}from"url";import d from"chalk";import u,{platform as m,homedir as p}from"node:os";import f from"fs-extra";import{execFile as h}from"node:child_process";import g from"fuzzy";import{parseToEpoch as y,getEpochNow as b,convertEpochToTimezone as v,convertEpoch as x}from"@master4n/temporal-transformer";import{promisify as w}from"node:util";import{platform as $}from"os";import{randomBytes as j,randomUUID as S,getHashes as N,createHash as k}from"node:crypto";import{readFile as E}from"node:fs/promises";import{createServer as I,createConnection as O}from"node:net";import A from"node:path";import T,{existsSync as L}from"node:fs";import{lookup as M,resolve4 as z,resolve6 as C,resolveCname as R,resolveMx as _,resolveTxt as F,resolveNs as D}from"node:dns/promises";function B(){return process.versions.electron&&!process.defaultApp?0:1}
|
|
3
3
|
/**
|
|
4
4
|
* @license
|
|
5
5
|
* Copyright (c) 2016, Contributors
|
|
6
6
|
* SPDX-License-Identifier: ISC
|
|
7
7
|
*/
|
|
8
|
-
function
|
|
8
|
+
function P(e){if(e!==e.toLowerCase()&&e!==e.toUpperCase()||(e=e.toLowerCase()),-1===e.indexOf("-")&&-1===e.indexOf("_"))return e;{let t="",n=!1;const o=e.match(/^-+/);for(let r=o?o[0].length:0;r<e.length;r++){let o=e.charAt(r);n&&(n=!1,o=o.toUpperCase()),0===r||"-"!==o&&"_"!==o?"-"!==o&&"_"!==o&&(t+=o):n=!0}return t}}
|
|
9
9
|
/**
|
|
10
10
|
* @license
|
|
11
11
|
* Copyright (c) 2016, Contributors
|
|
12
12
|
* SPDX-License-Identifier: ISC
|
|
13
13
|
*/
|
|
14
|
-
var
|
|
14
|
+
var U;
|
|
15
15
|
/**
|
|
16
16
|
* @license
|
|
17
17
|
* Copyright (c) 2016, Contributors
|
|
18
18
|
* SPDX-License-Identifier: ISC
|
|
19
19
|
*/
|
|
20
|
-
let
|
|
20
|
+
let W;!function(e){e.BOOLEAN="boolean",e.STRING="string",e.NUMBER="number",e.ARRAY="array"}(U||(U={}));function J(e){return void 0!==e?e+1:1}function Z(e){return"__proto__"===e?"___proto___":e}
|
|
21
21
|
/**
|
|
22
22
|
* @fileoverview Main entrypoint for libraries using yargs-parser in Node.js
|
|
23
23
|
* CJS and ESM environments.
|
|
@@ -26,11 +26,11 @@ let B;!function(e){e.BOOLEAN="boolean",e.STRING="string",e.NUMBER="number",e.ARR
|
|
|
26
26
|
* Copyright (c) 2016, Contributors
|
|
27
27
|
* SPDX-License-Identifier: ISC
|
|
28
28
|
*/
|
|
29
|
-
var
|
|
29
|
+
var q,G,H;const Y=process&&process.env&&process.env.YARGS_MIN_NODE_VERSION?Number(process.env.YARGS_MIN_NODE_VERSION):12,V=null!==(G=null===(q=null===process||void 0===process?void 0:process.versions)||void 0===q?void 0:q.node)&&void 0!==G?G:null===(H=null===process||void 0===process?void 0:process.version)||void 0===H?void 0:H.slice(1);if(V){if(Number(V.match(/^([^.]+)/)[1])<Y)throw Error(`yargs parser supports a minimum Node.js version of ${Y}. Read our version support policy: https://github.com/yargs/yargs-parser#supported-nodejs-versions`)}const K=process?process.env:{};new class{constructor(e){W=e}parse(e,t){const n=Object.assign({alias:void 0,array:void 0,boolean:void 0,config:void 0,configObjects:void 0,configuration:void 0,coerce:void 0,count:void 0,default:void 0,envPrefix:void 0,narg:void 0,normalize:void 0,string:void 0,number:void 0,__:void 0,key:void 0},t),o=
|
|
30
30
|
/**
|
|
31
31
|
* @license
|
|
32
32
|
* Copyright (c) 2016, Contributors
|
|
33
33
|
* SPDX-License-Identifier: ISC
|
|
34
34
|
*/
|
|
35
|
-
function(e){if(Array.isArray(e))return e.map(e=>"string"!=typeof e?e+"":e);e=e.trim();let t=0,n=null,o=null,r=null;const s=[];for(let a=0;a<e.length;a++)n=o,o=e.charAt(a)," "!==o||r?(o===r?r=null:"'"!==o&&'"'!==o||r||(r=o),s[t]||(s[t]=""),s[t]+=o):" "!==n&&t++;return s}(e),r="string"==typeof e,s=function(e){const t=[],n=Object.create(null);let o=!0;Object.keys(e).forEach(function(n){t.push([].concat(e[n],n))});for(;o;){o=!1;for(let e=0;e<t.length;e++)for(let n=e+1;n<t.length;n++){if(t[e].filter(function(e){return-1!==t[n].indexOf(e)}).length){t[e]=t[e].concat(t[n]),t.splice(n,1),o=!0;break}}}return t.forEach(function(e){const t=(e=e.filter(function(e,t,n){return n.indexOf(e)===t})).pop();void 0!==t&&"string"==typeof t&&(n[t]=e)}),n}(Object.assign(Object.create(null),n.alias)),a=Object.assign({"boolean-negation":!0,"camel-case-expansion":!0,"combine-arrays":!1,"dot-notation":!0,"duplicate-arguments-array":!0,"flatten-duplicate-arrays":!0,"greedy-arrays":!0,"halt-at-non-option":!1,"nargs-eats-options":!1,"negation-prefix":"no-","parse-numbers":!0,"parse-positional-numbers":!0,"populate--":!1,"set-placeholder-key":!1,"short-option-groups":!0,"strip-aliased":!1,"strip-dashed":!1,"unknown-options-as-args":!1},n.configuration),i=Object.assign(Object.create(null),n.default),c=n.configObjects||[],l=n.envPrefix,u=a["populate--"],f=u?"--":"_",d=Object.create(null),p=Object.create(null),m=n.__||B.format,h={aliases:Object.create(null),arrays:Object.create(null),bools:Object.create(null),strings:Object.create(null),numbers:Object.create(null),counts:Object.create(null),normalize:Object.create(null),configs:Object.create(null),nargs:Object.create(null),coercions:Object.create(null),keys:[]},g=/^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/,y=new RegExp("^--"+a["negation-prefix"]+"(.+)");[].concat(n.array||[]).filter(Boolean).forEach(function(e){const t="object"==typeof e?e.key:e,n=Object.keys(e).map(function(e){return{boolean:"bools",string:"strings",number:"numbers"}[e]}).filter(Boolean).pop();n&&(h[n][t]=!0),h.arrays[t]=!0,h.keys.push(t)}),[].concat(n.boolean||[]).filter(Boolean).forEach(function(e){h.bools[e]=!0,h.keys.push(e)}),[].concat(n.string||[]).filter(Boolean).forEach(function(e){h.strings[e]=!0,h.keys.push(e)}),[].concat(n.number||[]).filter(Boolean).forEach(function(e){h.numbers[e]=!0,h.keys.push(e)}),[].concat(n.count||[]).filter(Boolean).forEach(function(e){h.counts[e]=!0,h.keys.push(e)}),[].concat(n.normalize||[]).filter(Boolean).forEach(function(e){h.normalize[e]=!0,h.keys.push(e)}),"object"==typeof n.narg&&Object.entries(n.narg).forEach(([e,t])=>{"number"==typeof t&&(h.nargs[e]=t,h.keys.push(e))}),"object"==typeof n.coerce&&Object.entries(n.coerce).forEach(([e,t])=>{"function"==typeof t&&(h.coercions[e]=t,h.keys.push(e))}),void 0!==n.config&&(Array.isArray(n.config)||"string"==typeof n.config?[].concat(n.config).filter(Boolean).forEach(function(e){h.configs[e]=!0}):"object"==typeof n.config&&Object.entries(n.config).forEach(([e,t])=>{"boolean"!=typeof t&&"function"!=typeof t||(h.configs[e]=t)})),function(...e){e.forEach(function(e){Object.keys(e||{}).forEach(function(e){h.aliases[e]||(h.aliases[e]=[].concat(s[e]||[]),h.aliases[e].concat(e).forEach(function(t){if(/-/.test(t)&&a["camel-case-expansion"]){const n=F(t);n!==e&&-1===h.aliases[e].indexOf(n)&&(h.aliases[e].push(n),d[n]=!0)}}),h.aliases[e].concat(e).forEach(function(t){if(t.length>1&&/[A-Z]/.test(t)&&a["camel-case-expansion"]){const n=function(e,t){const n=e.toLowerCase();t=t||"-";let o="";for(let r=0;r<e.length;r++){const s=n.charAt(r),a=e.charAt(r);o+=s!==a&&r>0?`${t}${n.charAt(r)}`:a}return o}(t,"-");n!==e&&-1===h.aliases[e].indexOf(n)&&(h.aliases[e].push(n),d[n]=!0)}}),h.aliases[e].forEach(function(t){h.aliases[t]=[e].concat(h.aliases[e].filter(function(e){return t!==e}))}))})})}(n.key,s,n.default,h.arrays),Object.keys(i).forEach(function(e){(h.aliases[e]||[]).forEach(function(t){i[t]=i[e]})});let b=null;Object.keys(h.counts).find(e=>M(e,h.arrays)?(b=Error(m("Invalid configuration: %s, opts.count excludes opts.array.",e)),!0):!!M(e,h.nargs)&&(b=Error(m("Invalid configuration: %s, opts.count excludes opts.narg.",e)),!0));let v=[];const x=Object.assign(Object.create(null),{_:[]}),j={};for(let e=0;e<o.length;e++){const t=o[e],n=t.replace(/^-{3,}/,"---");let r,s,i,c,l,u;if("--"!==t&&/^-/.test(t)&&R(t))w(t);else{if(n.match(/^---+(=|$)/)){w(t);continue}if(t.match(/^--.+=/)||!a["short-option-groups"]&&t.match(/^-.+=/))c=t.match(/^--?([^=]+)=([\s\S]*)$/),null!==c&&Array.isArray(c)&&c.length>=3&&(M(c[1],h.arrays)?e=$(e,c[1],o,c[2]):!1!==M(c[1],h.nargs)?e=E(e,c[1],o,c[2]):S(c[1],c[2],!0));else if(t.match(y)&&a["boolean-negation"])c=t.match(y),null!==c&&Array.isArray(c)&&c.length>=2&&(s=c[1],S(s,!!M(s,h.arrays)&&[!1]));else if(t.match(/^--.+/)||!a["short-option-groups"]&&t.match(/^-[^-]+/))c=t.match(/^--?(.+)/),null!==c&&Array.isArray(c)&&c.length>=2&&(s=c[1],M(s,h.arrays)?e=$(e,s,o):!1!==M(s,h.nargs)?e=E(e,s,o):(l=o[e+1],void 0===l||l.match(/^-/)&&!l.match(g)||M(s,h.bools)||M(s,h.counts)?/^(true|false)$/.test(l)?(S(s,l),e++):S(s,P(s)):(S(s,l),e++)));else if(t.match(/^-.\..+=/))c=t.match(/^-([^=]+)=([\s\S]*)$/),null!==c&&Array.isArray(c)&&c.length>=3&&S(c[1],c[2]);else if(t.match(/^-.\..+/)&&!t.match(g))l=o[e+1],c=t.match(/^-(.\..+)/),null!==c&&Array.isArray(c)&&c.length>=2&&(s=c[1],void 0===l||l.match(/^-/)||M(s,h.bools)||M(s,h.counts)?S(s,P(s)):(S(s,l),e++));else if(t.match(/^-[^-]+/)&&!t.match(g)){i=t.slice(1,-1).split(""),r=!1;for(let n=0;n<i.length;n++){if(l=t.slice(n+2),i[n+1]&&"="===i[n+1]){u=t.slice(n+3),s=i[n],M(s,h.arrays)?e=$(e,s,o,u):!1!==M(s,h.nargs)?e=E(e,s,o,u):S(s,u),r=!0;break}if("-"!==l){if(/[A-Za-z]/.test(i[n])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(l)&&!1===M(l,h.bools)){S(i[n],l),r=!0;break}if(i[n+1]&&i[n+1].match(/\W/)){S(i[n],l),r=!0;break}S(i[n],P(i[n]))}else S(i[n],l)}s=t.slice(-1)[0],r||"-"===s||(M(s,h.arrays)?e=$(e,s,o):!1!==M(s,h.nargs)?e=E(e,s,o):(l=o[e+1],void 0===l||/^(-|--)[^-]/.test(l)&&!l.match(g)||M(s,h.bools)||M(s,h.counts)?/^(true|false)$/.test(l)?(S(s,l),e++):S(s,P(s)):(S(s,l),e++)))}else if(t.match(/^-[0-9]$/)&&t.match(g)&&M(t.slice(1),h.bools))s=t.slice(1),S(s,P(s));else{if("--"===t){v=o.slice(e+1);break}if(a["halt-at-non-option"]){v=o.slice(e);break}w(t)}}}function w(e){const t=N("_",e);"string"!=typeof t&&"number"!=typeof t||x._.push(t)}function E(e,t,n,o){let r,s=M(t,h.nargs);if(s="number"!=typeof s||isNaN(s)?1:s,0===s)return J(o)||(b=Error(m("Argument unexpected for: %s",t))),S(t,P(t)),e;let i=J(o)?0:1;if(a["nargs-eats-options"])n.length-(e+1)+i<s&&(b=Error(m("Not enough arguments following: %s",t))),i=s;else{for(r=e+1;r<n.length&&(!n[r].match(/^-[^0-9]/)||n[r].match(g)||R(n[r]));r++)i++;i<s&&(b=Error(m("Not enough arguments following: %s",t)))}let c=Math.min(i,s);for(!J(o)&&c>0&&(S(t,o),c--),r=e+1;r<c+e+1;r++)S(t,n[r]);return e+c}function $(e,t,n,o){let s=[],c=o||n[e+1];const l=M(t,h.nargs);if(M(t,h.bools)&&!/^(true|false)$/.test(c))s.push(!0);else if(J(c)||J(o)&&/^-/.test(c)&&!g.test(c)&&!R(c)){if(void 0!==i[t]){const e=i[t];s=Array.isArray(e)?e:[e]}}else{J(o)||s.push(k(t,o,!0));for(let o=e+1;o<n.length&&!(!a["greedy-arrays"]&&s.length>0||l&&"number"==typeof l&&s.length>=l)&&(c=n[o],!/^-/.test(c)||g.test(c)||R(c));o++)e=o,s.push(k(t,c,r))}return"number"==typeof l&&(l&&s.length<l||isNaN(l)&&0===s.length)&&(b=Error(m("Not enough arguments following: %s",t))),S(t,s),e}function S(e,t,n=r){if(/-/.test(e)&&a["camel-case-expansion"]){const t=e.split(".").map(function(e){return F(e)}).join(".");O(e,t)}const o=k(e,t,n),s=e.split(".");if(z(x,s,o),h.aliases[e]&&h.aliases[e].forEach(function(e){const t=e.split(".");z(x,t,o)}),s.length>1&&a["dot-notation"]&&(h.aliases[s[0]]||[]).forEach(function(t){let n=t.split(".");const r=[].concat(s);r.shift(),n=n.concat(r),(h.aliases[e]||[]).includes(n.join("."))||z(x,n,o)}),M(e,h.normalize)&&!M(e,h.arrays)){[e].concat(h.aliases[e]||[]).forEach(function(e){Object.defineProperty(j,e,{enumerable:!0,get:()=>t,set(e){t="string"==typeof e?B.normalize(e):e}})})}}function O(e,t){h.aliases[e]&&h.aliases[e].length||(h.aliases[e]=[t],d[t]=!0),h.aliases[t]&&h.aliases[t].length||O(t,e)}function k(e,t,n){n&&(t=function(e){return"string"!=typeof e||"'"!==e[0]&&'"'!==e[0]||e[e.length-1]!==e[0]?e:e.substring(1,e.length-1)}(t)),(M(e,h.bools)||M(e,h.counts))&&"string"==typeof t&&(t="true"===t);let o=Array.isArray(t)?t.map(function(t){return N(e,t)}):N(e,t);return M(e,h.counts)&&(J(o)||"boolean"==typeof o)&&(o=C()),M(e,h.normalize)&&M(e,h.arrays)&&(o=Array.isArray(t)?t.map(e=>B.normalize(e)):B.normalize(t)),o}function N(e,t){if(!a["parse-positional-numbers"]&&"_"===e)return t;if(!M(e,h.strings)&&!M(e,h.bools)&&!Array.isArray(t)){(null!=(n=t)&&("number"==typeof n||!!/^0x[0-9a-f]+$/i.test(n)||!/^0[^.]/.test(n)&&/^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(n))&&a["parse-numbers"]&&Number.isSafeInteger(Math.floor(parseFloat(`${t}`)))||!J(t)&&M(e,h.numbers))&&(t=Number(t))}var n;return t}function I(e,t){Object.keys(e).forEach(function(n){const o=e[n],r=t?t+"."+n:n;"object"==typeof o&&null!==o&&!Array.isArray(o)&&a["dot-notation"]?I(o,r):(!_(x,r.split("."))||M(r,h.arrays)&&a["combine-arrays"])&&S(r,o)})}function A(e,t){if(void 0===l)return;const n="string"==typeof l?l:"",o=B.env();Object.keys(o).forEach(function(r){if(""===n||0===r.lastIndexOf(n,0)){const s=r.split("__").map(function(e,t){return 0===t&&(e=e.substring(n.length)),F(e)});(t&&h.configs[s.join(".")]||!t)&&!_(e,s)&&S(s.join("."),o[r])}})}function T(e,t,n,o=!1){Object.keys(n).forEach(function(r){_(e,r.split("."))||(z(e,r.split("."),n[r]),o&&(p[r]=!0),(t[r]||[]).forEach(function(t){_(e,t.split("."))||z(e,t.split("."),n[r])}))})}function _(e,t){let n=e;a["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){n=n[e]||{}});const o=t[t.length-1];return"object"==typeof n&&o in n}function z(e,t,n){let o=e;a["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){e=D(e),"object"==typeof o&&void 0===o[e]&&(o[e]={}),"object"!=typeof o[e]||Array.isArray(o[e])?(Array.isArray(o[e])?o[e].push({}):o[e]=[o[e],{}],o=o[e][o[e].length-1]):o=o[e]});const r=D(t[t.length-1]),s=M(t.join("."),h.arrays),i=Array.isArray(n);let c=a["duplicate-arguments-array"];!c&&M(r,h.nargs)&&(c=!0,(!J(o[r])&&1===h.nargs[r]||Array.isArray(o[r])&&o[r].length===h.nargs[r])&&(o[r]=void 0)),n===C()?o[r]=C(o[r]):Array.isArray(o[r])?c&&s&&i?o[r]=a["flatten-duplicate-arrays"]?o[r].concat(n):(Array.isArray(o[r][0])?o[r]:[o[r]]).concat([n]):c||Boolean(s)!==Boolean(i)?o[r]=o[r].concat([n]):o[r]=n:void 0===o[r]&&s?o[r]=i?n:[n]:!c||void 0===o[r]||M(r,h.counts)||M(r,h.bools)?o[r]=n:o[r]=[o[r],n]}function M(e,t){const n=[].concat(h.aliases[e]||[],e),o=Object.keys(t),r=n.find(e=>o.includes(e));return!!r&&t[r]}function U(e){const t=Object.keys(h);return[].concat(t.map(e=>h[e])).some(function(t){return Array.isArray(t)?t.includes(e):t[e]})}function R(e){return a["unknown-options-as-args"]&&function(e){if(e=e.replace(/^-{3,}/,"--"),e.match(g))return!1;if(function(e){if(e.match(g)||!e.match(/^-[^-]+/))return!1;let t,n=!0;const o=e.slice(1).split("");for(let r=0;r<o.length;r++){if(t=e.slice(r+2),!U(o[r])){n=!1;break}if(o[r+1]&&"="===o[r+1]||"-"===t||/[A-Za-z]/.test(o[r])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(t)||o[r+1]&&o[r+1].match(/\W/))break}return n}(e))return!1;return!function(e,...t){return[].concat(...t).some(function(t){const n=e.match(t);return n&&U(n[1])})}(e,/^-+([^=]+?)=[\s\S]*$/,y,/^-+([^=]+?)$/,/^-+([^=]+?)-$/,/^-+([^=]+?\d+)$/,/^-+([^=]+?)\W+.*$/)}(e)}function P(e){return M(e,h.bools)||M(e,h.counts)||!(`${e}`in i)?(t=function(e){let t=L.BOOLEAN;return M(e,h.strings)?t=L.STRING:M(e,h.numbers)?t=L.NUMBER:M(e,h.bools)?t=L.BOOLEAN:M(e,h.arrays)&&(t=L.ARRAY),t}(e),{[L.BOOLEAN]:!0,[L.STRING]:"",[L.NUMBER]:void 0,[L.ARRAY]:[]}[t]):i[e];var t}function J(e){return void 0===e}return A(x,!0),A(x,!1),function(e){const t=Object.create(null);T(t,h.aliases,i),Object.keys(h.configs).forEach(function(n){const o=e[n]||t[n];if(o)try{let e=null;const t=B.resolve(B.cwd(),o),r=h.configs[n];if("function"==typeof r){try{e=r(t)}catch(t){e=t}if(e instanceof Error)return void(b=e)}else e=B.require(t);I(e)}catch(t){"PermissionDenied"===t.name?b=t:e[n]&&(b=Error(m("Invalid JSON config file: %s",o)))}})}(x),void 0!==c&&c.forEach(function(e){I(e)}),T(x,h.aliases,i,!0),function(e){let t;const n=new Set;Object.keys(e).forEach(function(o){if(!n.has(o)&&(t=M(o,h.coercions),"function"==typeof t))try{const r=N(o,t(e[o]));[].concat(h.aliases[o]||[],o).forEach(t=>{n.add(t),e[t]=r})}catch(e){b=e}})}(x),a["set-placeholder-key"]&&function(e){h.keys.forEach(t=>{~t.indexOf(".")||void 0===e[t]&&(e[t]=void 0)})}(x),Object.keys(h.counts).forEach(function(e){_(x,e.split("."))||S(e,0)}),u&&v.length&&(x[f]=[]),v.forEach(function(e){x[f].push(e)}),a["camel-case-expansion"]&&a["strip-dashed"]&&Object.keys(x).filter(e=>"--"!==e&&e.includes("-")).forEach(e=>{delete x[e]}),a["strip-aliased"]&&[].concat(...Object.keys(s).map(e=>s[e])).forEach(e=>{a["camel-case-expansion"]&&e.includes("-")&&delete x[e.split(".").map(e=>F(e)).join(".")],delete x[e]}),{aliases:Object.assign({},h.aliases),argv:Object.assign(j,x),configuration:a,defaulted:Object.assign({},p),error:b,newAliases:Object.assign({},d)}}}({cwd:process.cwd,env:()=>G,format:t,normalize:r,resolve:o,require:e=>{if("undefined"!=typeof require)return require(e);if(e.match(/\.json$/))return JSON.parse(a(e,"utf8"));throw Error("only .json config files are supported in ESM")}});var W={fs:{readFileSync:a,writeFile:i},format:t,resolve:o,exists:e=>{try{return c(e).isFile()}catch(e){return!1}}};let Y;class Z{constructor(e){e=e||{},this.directory=e.directory||"./locales",this.updateFiles="boolean"!=typeof e.updateFiles||e.updateFiles,this.locale=e.locale||"en",this.fallbackToLanguage="boolean"!=typeof e.fallbackToLanguage||e.fallbackToLanguage,this.cache=Object.create(null),this.writeQueue=[]}__(...e){if("string"!=typeof arguments[0])return this._taggedLiteral(arguments[0],...arguments);const t=e.shift();let n=function(){};return"function"==typeof e[e.length-1]&&(n=e.pop()),n=n||function(){},this.cache[this.locale]||this._readLocaleFile(),!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]=t,this._enqueueWrite({directory:this.directory,locale:this.locale,cb:n})):n(),Y.format.apply(Y.format,[this.cache[this.locale][t]||t].concat(e))}__n(){const e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),o=e.shift();let r=function(){};"function"==typeof e[e.length-1]&&(r=e.pop()),this.cache[this.locale]||this._readLocaleFile();let s=1===o?t:n;if(this.cache[this.locale][t]){s=this.cache[this.locale][t][1===o?"one":"other"]}!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]={one:t,other:n},this._enqueueWrite({directory:this.directory,locale:this.locale,cb:r})):r();const a=[s];return~s.indexOf("%d")&&a.push(o),Y.format.apply(Y.format,a.concat(e))}setLocale(e){this.locale=e}getLocale(){return this.locale}updateLocale(e){this.cache[this.locale]||this._readLocaleFile();for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(this.cache[this.locale][t]=e[t])}_taggedLiteral(e,...t){let n="";return e.forEach(function(e,o){const r=t[o+1];n+=e,void 0!==r&&(n+="%s")}),this.__.apply(this,[n].concat([].slice.call(t,1)))}_enqueueWrite(e){this.writeQueue.push(e),1===this.writeQueue.length&&this._processWriteQueue()}_processWriteQueue(){const e=this,t=this.writeQueue[0],n=t.directory,o=t.locale,r=t.cb,s=this._resolveLocaleFile(n,o),a=JSON.stringify(this.cache[o],null,2);Y.fs.writeFile(s,a,"utf-8",function(t){e.writeQueue.shift(),e.writeQueue.length>0&&e._processWriteQueue(),r(t)})}_readLocaleFile(){let e={};const t=this._resolveLocaleFile(this.directory,this.locale);try{Y.fs.readFileSync&&(e=JSON.parse(Y.fs.readFileSync(t,"utf-8")))}catch(n){if(n instanceof SyntaxError&&(n.message="syntax error in "+t),"ENOENT"!==n.code)throw n;e={}}this.cache[this.locale]=e}_resolveLocaleFile(e,t){let n=Y.resolve(e,"./",t+".json");if(this.fallbackToLanguage&&!this._fileExistsSync(n)&&~t.lastIndexOf("_")){const o=Y.resolve(e,"./",t.split("_")[0]+".json");this._fileExistsSync(o)&&(n=o)}return n}_fileExistsSync(e){return Y.exists(e)}}let Q;try{Q=l(import.meta.url)}catch(e){Q=process.cwd()}Q.substring(0,Q.lastIndexOf("node_modules"))||process.cwd(),process.cwd,process.exit,process.nextTick,void 0!==process.stdout.columns&&process.stdout.columns,function(e,t){Y=t;const n=new Z(e);n.__.bind(n),n.__n.bind(n),n.setLocale.bind(n),n.getLocale.bind(n),n.updateLocale.bind(n),n.locale}({directory:o(Q,"../../../locales"),updateFiles:!1},W);const q=()=>(new Date).toISOString();function H(){return{info:e=>console.error(`${u.blue("INFO")} [${u.magenta(q())}] ${u.white(e)}`),warn:e=>console.error(`${u.yellow("WARN")} [${u.magenta(q())}] ${u.white(e)}`),error:e=>console.error(`${u.red("ERROR")} [${u.magenta(q())}] ${u.white(e)}`),debug:e=>console.error(`${u.cyan("DEBUG")} [${u.magenta(q())}] ${u.white(e)}`)}}function K(){const e=p.homedir();return n.join(e,".mfn","cache")}const V=e=>u.green(e);async function X(e,t){await m.writeJson(t,e,{spaces:2})}const ee=[{name:"capabilities",summary:"Self-describing manifest of every command an agent can call",examples:["mfn capabilities --json"]},{name:"epoch",summary:"Convert between epoch timestamps and dates (auto-detects unit)",examples:["mfn epoch 1622547800 --json","mfn epoch --from 2021-06-01T11:43:20Z --json"]},{name:"date",summary:"Convert/format a date across timezones (defaults to now)",examples:["mfn date --json","mfn date 2024-07-04T15:30:30Z --tz America/New_York --json"]},{name:"decode",summary:"Decode a JWT token (header + payload; signature not verified)",examples:["mfn decode -t <jwt> --json"]},{name:"kill",summary:"Kill the process(es) listening on specific ports",examples:["mfn kill -p 3000 8080 -y --json"]},{name:"sc",summary:"Find files/folders under the current directory (fuzzy match)",examples:["mfn sc service --json"]},{name:"cts",summary:"Print (or export) a tree of the current working directory",examples:["mfn cts --json","mfn cts -t png"]},{name:"update",summary:"Update the CLI or a specified package to the latest version",examples:["mfn update --json","mfn update <package> --json"]},{name:"id",summary:"Generate identifiers (UUID v4/v7 or URL-safe nano id)",examples:["mfn id --json","mfn id -t uuid7 -n 3 --json"]},{name:"hash",summary:"Hash a string, file, or stdin (md5/sha1/sha256/sha512)",examples:["mfn hash hello --json","mfn hash -a md5 -f ./file.txt --json"]},{name:"encode",summary:"Encode/decode text (base64, base64url, hex, url)",examples:["mfn encode hello --json","mfn encode aGVsbG8= -d --json"]},{name:"random",summary:"Generate secure random bytes or a password",examples:["mfn random --json","mfn random -p -l 32 --json"]},{name:"port",summary:"Find a free port, or check whether a specific port is available",examples:["mfn port --json","mfn port -c 3000 --json"]}];var te="@master4n/master-cli",ne="3.0.2";const oe=["add --json to any command for clean, machine-readable output","piping a command (no TTY) auto-emits JSON — great for agents & scripts","every command returns a stable exit code: 0 = ok, non-zero = failure","mfn <command> --help shows its flags and copy-paste examples","mfn capabilities --json lists every command an agent can call","mfn kill -p 3000 8080 -y frees stuck ports in one shot"],re=e=>u.hex(e)("─".repeat(62));!function(){const e=p.homedir(),t=n.join(e,".mfn","cache");if(!s.existsSync(t))try{s.existsSync(n.join(e,".mfn"))||s.mkdirSync(n.join(e,".mfn")),s.mkdirSync(t,{recursive:!0})}catch{}}(),await(async()=>{if(!(Boolean(process.stdout.isTTY)&&!process.argv.includes("--json")))return;const e=await(t="M4N-CLI",new Promise((e,n)=>{f(t,(t,o)=>t?n(t):e(o??""))}));var t;const n=d(u.hex("#27A244").bold(e),{padding:1,margin:{top:1,bottom:0,left:1,right:1},borderStyle:"round",borderColor:"#C1C110",dimBorder:!0}),o=function(){const e=p.platform();return"win32"===e?process.env.USERNAME||"User":"darwin"===e||"linux"===e?process.env.USER||"User":""}(),r=u.dim(" • "),s=[u.hex("#44bcd8").bold(`mfn v${ne}`),u.gray(`node ${process.version}`),u.gray(`${process.platform}/${process.arch}`),u.green.bold("AI-friendly")].join(r);let a="";try{const e=g();a=`${e.iso.replace("T"," ").slice(0,19)} ${u.dim(`(${e.timezone})`)}`}catch{}const i=ee.map(e=>u.cyan(e.name)).join(u.dim(" · ")),c=oe[Math.floor(Math.random()*oe.length)],l=(e="")=>console.error(e);l(re("#C1C110")),l(n),l(" "+(o?u.magenta(`👋 Welcome, ${u.bold(o)}`):u.magenta("👋 Welcome"))+r+s),a&&l(" "+u.gray("🕒 ")+u.white(a)),l(""),l(" "+u.yellow.bold("🧰 tools ")+i),l(" "+u.yellow.bold("💡 tip ")+u.white(c)),l(" "+u.yellow.bold("🤖 help ")+u.white("mfn <command> --help")),l(re("#C1C110"))})();const se=e(process.argv.slice(z()+1));const ae=u.hex("#44bcd8").bold("mfn");var ie=se.scriptName(ae);const ce=()=>Boolean(process.stdout.isTTY),le=e=>e.option("json",{type:"boolean",default:!1,describe:"Emit a single machine-readable JSON object on stdout"}),ue=e=>Boolean(e?.json)||!ce(),fe=e=>{process.stdout.write(JSON.stringify(e)+"\n")};function de(e,t,n){ue(e)?fe({ok:!0,...t}):n()}function pe(e,t,n,o=1){ue(e)?fe({ok:!1,error:t,message:n}):console.error(n),process.exit(o)}const me=e=>ce()&&!e?.json;async function he(){if(process.stdin.isTTY)return"";const e=[];for await(const t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf8")}function ge(e,t,n=2){process.argv.includes("--json")||!ce()?process.stdout.write(JSON.stringify({ok:!1,error:e,message:t})+"\n"):console.error(t),process.exit(n)}const ye=H(),be=n.join(K(),"cts_ignore.json"),ve=["node_modules",".git",".nx"];function xe(e,t,o=""){let r,s="";try{r=m.readdirSync(e).filter(e=>!t.has(e)).sort()}catch{return`${o}└── [unreadable]\n`}return r.forEach((a,i)=>{const c=n.join(e,a),l=i===r.length-1;let u=!1;try{u=m.statSync(c).isDirectory()}catch{u=!1}s+=`${o}${l?"└── ":"├── "}${a}\n`,u&&(s+=xe(c,t,`${o}${l?" ":"│ "}`))}),s}const je={command:"cts",describe:"Print (or export) a tree of the current working directory",builder:e=>le(e).option("type",{alias:"t",describe:"Output format: text (stdout, default) or an image file",type:"string",choices:["text","svg","png","jpeg"],default:"text"}).option("ignore",{alias:"i",describe:"Folder names to ignore",type:"array"}).option("length",{alias:"l",describe:"Image height",type:"number",default:250}).option("breadth",{alias:"b",describe:"Image width",type:"number",default:200}).example("mfn cts","print the tree as text").example("mfn cts --json","tree as JSON").example("mfn cts -t png","export the tree to <dir>.png"),handler:async e=>{let t=e.ignore??[];t.length>0?await X({ignores:t},be).catch(()=>{}):t=(await async function(){try{return await m.readJson(be)}catch(e){if("ENOENT"===e.code)return{ignores:[]};throw e}}()).ignores??[];const o=new Set([...ve,...t]),r=process.cwd(),s=n.basename(r);let a;try{a=s+"\n"+xe(r,o)}catch(t){return pe(e,"TreeError",`Failed to build tree for ${r}: ${t instanceof Error?t.message:String(t)}`)}const i=String(e.type);if("text"===i)return de(e,{root:s,path:r,format:"text",tree:a},()=>{process.stdout.write(a.endsWith("\n")?a:a+"\n")});if(!function(...e){for(const t of e)if(isNaN(t)||t<1||t>1e3)return!1;return!0}(e.length,e.breadth))return pe(e,"InvalidDimensions","Length & breadth must be numbers in 1..1000.",2);const c=`${s}.${i}`;try{const t=function(e,t,n){return`<svg xmlns="http://www.w3.org/2000/svg" width="${n}" height="${t}"><rect width="100%" height="100%" fill="white"/><g fill="black" font-family="monospace" font-size="12">${e.split("\n").map((e,t)=>`<text style="white-space: pre;" x="0" y="${20+20*t}">${e.replace(/&/g,"&").replace(/</g,"<")}</text>`).join("")}</g></svg>`}(a,e.length,e.breadth);"svg"===i?m.outputFileSync(c,t):await x(Buffer.from(t))["png"===i?"png":"jpeg"]().toFile(c)}catch(t){const n=t instanceof Error?t.message:String(t);return pe(e,"ExportFailed",`Failed to write ${c}: ${n}`)}de(e,{root:s,path:r,format:i,file:c},()=>ye.info(`Tree for ${s} written to ${c}`))}},we=H(),Ee=n.join(K(),"sc_ignore.json"),$e=["node_modules",".git","dist","build",".nx","coverage"];function Se(e,t,o){const r=[],s=new Set([...$e,...t]),a=(t,i)=>{if(i>o)return;let c;try{c=m.readdirSync(t,{withFileTypes:!0})}catch{return}for(const o of c){if(s.has(o.name))continue;const c=n.join(t,o.name),l=n.relative(e,c);r.push(o.isDirectory()?l+n.sep:l),o.isDirectory()&&a(c,i+1)}};return a(e,0),r}const Oe={command:"sc [pattern]",describe:"Find files/folders under the current directory (fuzzy match)",builder:e=>le(e).positional("pattern",{describe:"Fuzzy pattern to match against paths (omit to list all)",type:"string"}).option("ignore",{alias:"i",describe:"Additional directory names to ignore",type:"array"}).option("depth",{type:"number",default:6,describe:"Max recursion depth"}).option("limit",{type:"number",default:500,describe:"Max results returned"}).example("mfn sc service --json",'find paths matching "service"'),handler:async e=>{const t=process.cwd(),o=Number(e.depth),r=Number(e.limit);if(!Number.isInteger(o)||o<0)return pe(e,"InvalidDepth","--depth must be a non-negative integer.",2);if(!Number.isInteger(r)||r<1)return pe(e,"InvalidLimit","--limit must be a positive integer.",2);let s=e.ignore??[];if(s.length>0?await X({ignores:s},Ee).catch(()=>{}):s=(await async function(){try{return await m.readJson(Ee)}catch(e){if("ENOENT"===e.code)return{ignores:[]};throw e}}()).ignores??[],void 0===e.pattern&&me(e))return async function(e,t,o,r,s){const a=Se(t,o,r),{pattern:i}=await j.prompt([{type:"input",name:"pattern",message:V("Filter (fuzzy, blank = all):")}]),c=String(i??"").trim(),l=(c?w.filter(c,a).map(e=>e.original):a).slice(0,s);if(0===l.length)return de(e,{pattern:c||null,root:t,count:0,matches:[]},()=>we.warn("No matches."));const{selected:u}=await j.prompt([{type:"list",name:"selected",message:V("Select a path:"),choices:l,pageSize:15,loop:!1}]),f=m.statSync(n.join(t,u));de(e,{path:u,type:f.isDirectory()?"directory":"file"},()=>{we.info(`${f.isDirectory()?"Directory":"File"}: ${u}`),f.isDirectory()&&we.info(`cd ${u}`)})}(e,t,s,o,r);const a=Se(t,s,o),i=e.pattern?w.filter(String(e.pattern),a).map(e=>e.original):a,c=i.slice(0,r);de(e,{pattern:e.pattern??null,root:t,count:c.length,truncated:i.length>c.length,matches:c},()=>{we.info(`${c.length} match(es) under ${t}`);for(const e of c)console.log(e)})}},ke=H();function Ne(e){const t=Buffer.from(e,"base64url").toString("utf-8");return JSON.parse(t)}const Ie={command:"decode",describe:"Decode a JWT token (header + payload; signature not verified)",builder:e=>le(e).option("token",{alias:"t",describe:'JWT token to decode (a leading "Bearer " is stripped)',type:"string",demandOption:!0}).example("mfn decode -t <jwt> --json","decode a JWT"),handler:e=>{const t=String(e.token).replace(/^Bearer\s+/i,"").trim().split(".");if(3!==t.length)return pe(e,"InvalidJWT","Invalid JWT structure: expected three dot-separated segments.",2);let n,o;try{n=Ne(t[0]),o=Ne(t[1])}catch(t){return pe(e,"DecodeError",`Could not decode JWT: ${t instanceof Error?t.message:String(t)}`,2)}const r=o?.exp;let s;if("number"==typeof r&&Number.isFinite(r)){const e=Math.round(r-Date.now()/1e3);s={exp:r,expired:e<=0,expiresInSeconds:e}}de(e,{header:n,payload:o,...s?{expiry:s}:{}},()=>{ke.info("Decoded JWT (signature NOT verified)"),console.log(u.cyanBright.bold("header:")),console.log(u.greenBright(JSON.stringify(n,null,2))),console.log(u.cyanBright.bold("payload:")),console.log(u.greenBright(JSON.stringify(o,null,2))),s&&console.log(u.cyanBright.bold("expiry: ")+(s.expired?u.red(`expired ${-s.expiresInSeconds}s ago`):u.green(`valid for ${s.expiresInSeconds}s`)))})}},Ae=H(),Te="yyyy-MM-dd HH:mm:ss",_e=()=>Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC";function ze(e){const t=e.format||Te,n=e.tz||_e();let o,r,s;try{o=void 0!==e.from?y(String(e.from),e.inFormat,e.inTz).epochInMilliseconds:g().milliseconds}catch(t){const n=t instanceof Error?t.message:String(t);return pe(e,t instanceof Error?t.name:"ParseError",n,2)}try{r=b(o,"UTC",t),s=b(o,n,t)}catch(t){const n=t instanceof Error?t.message:String(t);return pe(e,t instanceof Error?t.name:"TimezoneError",n,2)}de(e,{epochInSeconds:Math.floor(o/1e3),epochInMilliseconds:o,utc:r,zoned:s,timezone:n,format:t},()=>{Ae.info("Date conversion"),console.table([{UTC:r,[n]:s,Epoch_ms:o}])})}const Fe={command:"date [from]",describe:"Convert/format a date across timezones (defaults to now)",builder:e=>le(e).positional("from",{describe:"Date string to convert (ISO 8601 unless --in-format given). Omit for now.",type:"string"}).option("tz",{type:"string",describe:"Target output timezone (IANA; default: local)"}).option("format",{type:"string",describe:`Output format (default: ${Te})`}).option("in-format",{type:"string",describe:"Luxon parse format for the input"}).option("in-tz",{type:"string",describe:"Timezone used to interpret the input"}).example("mfn date --json","now, in UTC + local").example("mfn date 2024-07-04T15:30:30Z --tz America/New_York --json","convert to a timezone"),handler:async e=>{const t={from:e.from,inFormat:e["in-format"],inTz:e["in-tz"],tz:e.tz,format:e.format,json:e.json};if(void 0===e.from&&void 0===e.tz&&void 0===e.format&&me(e))return async function(e){const t=await j.prompt([{type:"input",name:"from",message:V("Date string (blank = now, ISO 8601):")},{type:"input",name:"tz",message:V(`Target timezone (blank = ${_e()}):`)},{type:"input",name:"format",message:V(`Output format (blank = ${Te}):`)}]);ze({...e,from:t.from?.trim()||void 0,tz:t.tz?.trim()||void 0,format:t.format?.trim()||void 0})}(t);ze(t)}},Le=H();function Be(e,t){let n;try{n=v(t)}catch(t){const n=t instanceof Error?t.message:String(t);return pe(e,t instanceof Error?t.name:"InvalidEpoch",n,2)}de(e,{epoch:n.epoch,unit:n.epochUnit,utc:n.dateTimeInGMT,local:n.dateTime,timezone:n.timezone,relative:n.relative},()=>{Le.info("Epoch → date"),console.table([{Epoch:`${n.epoch} (${n.epochUnit})`,Local:n.dateTime,GMT:n.dateTimeInGMT,Relative:n.relative}])})}function Ce(e,t,n,o){let r,s;try{r=y(t,n,o)}catch(t){const n=t instanceof Error?t.message:String(t);return pe(e,t instanceof Error?t.name:"ParseError",n,2)}try{s=v(r.epochInSeconds).relative}catch{s=void 0}de(e,{epochInSeconds:r.epochInSeconds,epochInMilliseconds:r.epochInMilliseconds,utc:r.dateTimeInGMT,local:r.dateTime,timezone:r.timezone,relative:s},()=>{Le.info("Date → epoch"),console.table([{Seconds:r.epochInSeconds,Milliseconds:r.epochInMilliseconds,Local:r.dateTime,GMT:r.dateTimeInGMT,Timezone:r.timezone}])})}const De={command:"epoch [value]",describe:"Convert between epoch timestamps and dates (auto-detects unit)",builder:e=>le(e).positional("value",{describe:"Epoch value to convert to a date (s / ms / µs / ns auto-detected)",type:"string"}).option("from",{type:"string",describe:"A date string to convert TO epoch (ISO 8601 unless --format given)"}).option("format",{type:"string",describe:'Luxon parse format for --from (e.g. "dd/MM/yyyy")'}).option("tz",{type:"string",describe:"IANA timezone used to interpret --from (default: local)"}).example("mfn epoch 1622547800 --json","epoch → date").example("mfn epoch --from 2021-06-01T11:43:20Z --json","date → epoch"),handler:async e=>{if(void 0!==e.from)return Ce(e,String(e.from),e.format,e.tz);if(void 0!==e.value&&null!==e.value){const t=String(e.value).trim();return""===t?pe(e,"MissingInput","Epoch value is empty. Provide a numeric epoch.",2):Be(e,Number(t))}if(me(e))return async function(e){const{operation:t}=await j.prompt([{type:"rawlist",name:"operation",message:V("What do you want to do?"),choices:[{name:"Convert epoch → human-readable date",value:"epochToDate"},{name:"Convert date string → epoch",value:"dateToEpoch"}]}]);if("epochToDate"===t){const{value:t}=await j.prompt([{type:"input",name:"value",message:V("Enter epoch value:"),validate:e=>e.trim()&&!isNaN(Number(e))||"Enter a number"}]);Be(e,Number(t))}else{const{input:t}=await j.prompt([{type:"input",name:"input",message:V("Enter a date string (ISO 8601):"),validate:e=>Boolean(e.trim())||"Enter a date string"}]);Ce(e,t,void 0,e.tz)}}(e);pe(e,"MissingInput","Provide an epoch <value>, or --from <dateString>. See `mfn epoch --help`.",2)}},Me=H(),Ue=E(h),Re=n.join(K(),"ports.json"),Pe="win32"===$();async function Je(e){try{if(Pe){const{stdout:t}=await Ue("netstat",["-ano"]),n=t.split("\n").find(t=>t.includes(`:${e}`)&&/LISTENING/i.test(t)),o=n?n.trim().split(/\s+/).pop():null;return o?{port:e,pid:o}:null}const{stdout:t}=await Ue("lsof",["-i",`:${e}`]),n=t.split("\n").find(e=>/LISTEN/.test(e)),o=n?n.trim().split(/\s+/)[1]:null;return o?{port:e,pid:o}:null}catch{return null}}async function Ge(e){Pe?await Ue("taskkill",["/PID",e,"/F"]):await Ue("kill",["-9",e])}const We={command:"kill",describe:"Kill the process(es) listening on specific ports",builder:e=>le(e).option("ports",{alias:"p",describe:"Port number(s) to free",type:"array",coerce:e=>(Array.isArray(e)?e:[e]).map(e=>{const t=Number(e);if(isNaN(t))throw new Error(`Invalid port number: ${e}`);return t})}).option("yes",{alias:"y",type:"boolean",default:!1,describe:"Kill all matching processes without the interactive prompt"}).example("mfn kill -p 3000 8080 -y --json","free ports 3000 and 8080"),handler:async e=>{let t=e.ports??[];if(0===t.length){const n=me(e)?await async function(){try{return await m.readJson(Re)}catch(e){if("ENOENT"===e.code)return{ports:[]};throw e}}():{ports:[]};if(!n.ports?.length)return pe(e,"NoPorts","No ports provided. Use -p <port...>. See `mfn kill --help`.",2);t=n.ports,Me.info(`Using cached ports [${t.join(", ")}]`)}await X({ports:t},Re).catch(()=>{});const n=(await Promise.all(t.map(Je))).filter(e=>null!==e),o=t.filter(e=>!n.some(t=>t.port===e));if(0===n.length)return de(e,{killed:[],failed:[],notFound:o},()=>Me.info(`No processes listening on [${t.join(", ")}]`));let r=n;if(me(e)&&!e.yes){const{pids:e}=await j.prompt([{type:"checkbox",name:"pids",message:V("Select the processes to kill:"),choices:n.map(e=>({name:`Port ${e.port} → PID ${e.pid}`,value:e.pid}))}]);r=n.filter(t=>e.includes(t.pid))}const s=[],a=[];for(const e of r)try{await Ge(e.pid),s.push(e)}catch(t){a.push({...e,error:t instanceof Error?t.message:String(t)})}de(e,{killed:s,failed:a,notFound:o},()=>{for(const e of s)Me.info(`Killed PID ${e.pid} on port ${e.port}`);for(const e of a)Me.error(`Failed to kill PID ${e.pid} (port ${e.port}): ${e.error}`);o.length&&Me.warn(`No process on [${o.join(", ")}]`)}),a.length>0&&process.exit(1)}},Ye=H(),Ze=E(h);const Qe={command:"update [package]",describe:"Update the CLI or a specified package to the latest version",builder:e=>le(e).positional("package",{describe:"npm package to update globally (default: this CLI)",type:"string",default:"@master4n/master-cli"}).example("mfn update","update master-cli itself to the latest version").example("mfn update typescript --json","update a specific global package"),handler:async e=>{const t=String(e.package??"@master4n/master-cli"),n=me(e)?S():null,o=Date.now();n?.start(u.green(`updating/installing ${t}`));try{await async function(e){await Ze("npm",["install","-g",e])}(t);const r=await async function(e){try{const{stdout:t}=await Ze("npm",["view",e,"version"]);return t.trim()||null}catch{return null}}(t),s=Date.now()-o;n?.succeed(`${u.green(`updated ${t}`)} ${u.dim(`(${(s/1e3).toFixed(3)}s)`)}`),de(e,{package:t,version:r,durationMs:s},()=>{Ye.info(`${t} updated/installed${r?` -> ${u.green(r)}`:""}`)})}catch(o){n?.fail(u.red(`failed updating ${t}`));const r=o instanceof Error?o.message:String(o);pe(e,"UpdateFailed",`Failed to update "${t}": ${r}`)}}},qe={command:"capabilities",describe:"List every command an agent can call (self-describing manifest)",builder:e=>le(e).example("mfn capabilities --json","machine-readable manifest"),handler:e=>{de(e,{name:te,version:ne,bin:"mfn",conventions:{json:"pass --json, or pipe (non-TTY auto-emits) — one {ok,...} object on stdout",exitCodes:{ok:0,error:1,usage:2},logs:"banners and logs go to stderr; stdout carries data only"},commands:ee.map(e=>({name:e.name,summary:e.summary,examples:e.examples}))},()=>{console.log(`${te} v${ne} (bin: mfn)`),console.log("Commands an agent can call headlessly:");for(const e of ee)console.log(` ${e.name.padEnd(10)} ${e.summary}`);console.log("\nConventions: --json for machine output · exit 0/1/2 · logs on stderr")})}};function He(e){switch(e){case"uuid":case"uuid4":return k();case"uuid7":return function(){const e=O(16);e.writeUIntBE(Date.now(),0,6),e[6]=15&e[6]|112,e[8]=63&e[8]|128;const t=e.toString("hex");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}();default:return""}}const Ke=1e5,Ve={command:"id",describe:"Generate identifiers (UUID v4/v7 or URL-safe nano id)",builder:e=>le(e).option("type",{alias:"t",describe:"Identifier type",type:"string",choices:["uuid","uuid4","uuid7","nano"],default:"uuid"}).option("count",{alias:"n",describe:"How many to generate",type:"number",default:1}).option("size",{describe:"Length for --type nano",type:"number",default:21}).example("mfn id --json","one UUID v4").example("mfn id -t uuid7 -n 3 --json","three time-ordered UUID v7").example("mfn id -t nano --size 12 --json","a 12-char URL-safe id"),handler:e=>{const t=String(e.type),n=Number(e.count),o=Number(e.size);if(!Number.isInteger(n)||n<1||n>Ke)return pe(e,"InvalidCount","--count must be an integer in 1..100000.",2);if("nano"===t&&(!Number.isInteger(o)||o<1||o>4096))return pe(e,"InvalidSize","--size must be an integer in 1..4096.",2);const r=Array.from({length:n},()=>"nano"===t?function(e){let t="";for(;t.length<e;){const n=O(e);for(let o=0;o<n.length&&t.length<e;o++)t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"[63&n[o]]}return t}(o):He(t));de(e,{type:t,count:n,ids:r},()=>r.forEach(e=>console.log(e)))}},Xe=["md5","sha1","sha256","sha512"],et={command:"hash [text]",describe:"Hash a string, file, or stdin (md5/sha1/sha256/sha512)",builder:e=>le(e).positional("text",{describe:"String to hash (or pipe via stdin, or use --file)",type:"string"}).option("algo",{alias:"a",describe:"Hash algorithm",type:"string",choices:Xe,default:"sha256"}).option("file",{alias:"f",describe:"Hash the contents of this file instead",type:"string"}).option("encoding",{alias:"e",describe:"Digest encoding",type:"string",choices:["hex","base64","base64url"],default:"hex"}).example("mfn hash hello --json",'sha256 of "hello"').example("mfn hash -a md5 -f ./file.txt --json","md5 of a file").example("cat file | mfn hash --json","hash piped stdin"),handler:async e=>{const t=String(e.algo),n=String(e.encoding);let o,r;try{if(void 0!==e.file)o=await A(String(e.file)),r=`file:${e.file}`;else if(void 0!==e.text)o=Buffer.from(String(e.text),"utf8"),r="text";else{const t=await he();if(!t)return pe(e,"MissingInput","Provide a string, --file <path>, or pipe stdin.",2);o=Buffer.from(t,"utf8"),r="stdin"}}catch(t){return pe(e,"ReadError",t instanceof Error?t.message:String(t))}if(!N().includes(t))return pe(e,"UnsupportedAlgo",`Algorithm "${t}" is not available.`,2);const s=I(t).update(o).digest(n);de(e,{algo:t,encoding:n,source:r,bytes:o.length,hash:s},()=>console.log(s))}};const tt={hex:/^[0-9a-fA-F]*$/,base64:/^[A-Za-z0-9+/]*={0,2}$/,base64url:/^[A-Za-z0-9_-]*$/};const nt={command:"encode [text]",describe:"Encode/decode text (base64, base64url, hex, url)",builder:e=>le(e).positional("text",{describe:"Text to (de/en)code (or pipe via stdin)",type:"string"}).option("as",{alias:"a",describe:"Codec",type:"string",choices:["base64","base64url","hex","url"],default:"base64"}).option("decode",{alias:"d",describe:"Decode instead of encode",type:"boolean",default:!1}).example("mfn encode hello --json",'base64-encode "hello"').example("mfn encode aGVsbG8= -d --json","base64-decode").example('mfn encode "a b&c" --as url --json',"url-encode"),handler:async e=>{const t=String(e.as),n=Boolean(e.decode);let o,r;if(void 0!==e.text)o=String(e.text);else if(o=(await he()).replace(/\n$/,""),!o)return pe(e,"MissingInput","Provide text or pipe stdin.",2);try{r=n?function(e,t){if("url"===t)return decodeURIComponent(e);const n=tt[t],o="hex"===t?e:e.trim();if(!n.test(o)||"hex"===t&&o.length%2!=0)throw new Error(`not valid ${t}`);return Buffer.from(o,t).toString("utf8")}(o,t):function(e,t){switch(t){case"base64":return Buffer.from(e,"utf8").toString("base64");case"base64url":return Buffer.from(e,"utf8").toString("base64url");case"hex":return Buffer.from(e,"utf8").toString("hex");case"url":return encodeURIComponent(e)}}(o,t)}catch(o){return pe(e,"CodecError",`Could not ${n?"decode":"encode"} as ${t}: ${o instanceof Error?o.message:String(o)}`)}de(e,{operation:n?"decode":"encode",codec:t,input:o,output:r},()=>console.log(r))}};const ot=1048576,rt={command:"random",describe:"Generate cryptographically secure random bytes or a password",builder:e=>le(e).option("bytes",{alias:"b",describe:"Number of random bytes",type:"number",default:32}).option("encoding",{alias:"e",describe:"Output encoding for bytes",type:"string",choices:["hex","base64","base64url"],default:"hex"}).option("password",{alias:"p",describe:"Generate a password instead of raw bytes",type:"boolean",default:!1}).option("length",{alias:"l",describe:"Password length",type:"number",default:24}).example("mfn random --json","32 secure random bytes as hex").example("mfn random -b 16 -e base64url --json","16 bytes, base64url").example("mfn random -p -l 32 --json","a 32-char password"),handler:e=>{if(e.password){const t=Number(e.length);if(!Number.isInteger(t)||t<1||t>4096)return pe(e,"InvalidLength","--length must be an integer in 1..4096.",2);const n=function(e,t){const n=t.length,o=Math.floor(256/n)*n;let r="";for(;r.length<e;)for(const s of O(2*e))if(s<o&&(r+=t[s%n],r.length===e))break;return r}(t,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*-_=+");return de(e,{kind:"password",length:t,value:n},()=>console.log(n))}const t=Number(e.bytes);if(!Number.isInteger(t)||t<1||t>ot)return pe(e,"InvalidBytes","--bytes must be an integer in 1..1048576.",2);const n=String(e.encoding),o=O(t).toString(n);de(e,{kind:"bytes",bytes:t,encoding:n,value:o},()=>console.log(o))}};function st(e,t){return new Promise(n=>{const o=_({port:e,host:t});o.setTimeout(500);const r=e=>{o.destroy(),n(e)};o.once("connect",()=>r(!0)),o.once("timeout",()=>r(!1)),o.once("error",()=>r(!1))})}function at(){return new Promise((e,t)=>{const n=T();n.unref(),n.on("error",t),n.listen(0,()=>{const t=n.address(),o="object"==typeof t&&t?t.port:0;e({port:o,close:()=>n.close()})})})}const it={command:"port",describe:"Find a free port, or check whether a specific port is available",builder:e=>le(e).option("check",{alias:"c",describe:"Check if this specific port is free",type:"number"}).option("count",{alias:"n",describe:"Return this many distinct free ports",type:"number",default:1}).example("mfn port --json","one free port").example("mfn port -n 3 --json","three free ports").example("mfn port -c 3000 --json","is port 3000 free?"),handler:async e=>{if(void 0!==e.check){const t=Number(e.check);if(!Number.isInteger(t)||t<1||t>65535)return pe(e,"InvalidPort","--check must be an integer in 1..65535.",2);const n=await async function(e){const[t,n]=await Promise.all([st(e,"127.0.0.1"),st(e,"::1")]);return!t&&!n}(t);return de(e,{port:t,available:n},()=>console.log(`${t} is ${n?"free":"in use"}`))}const t=Number(e.count);if(!Number.isInteger(t)||t<1)return pe(e,"InvalidCount","--count must be a positive integer.",2);const n=[];try{for(;n.length<t;){const e=await at();n.push(e)}}catch(t){n.forEach(e=>e.close());return pe(e,"PortError",`Could not allocate a free port: ${t instanceof Error?t.message:String(t)}`)}const o=n.map(e=>e.port);n.forEach(e=>e.close()),de(e,{count:t,ports:o,port:o[0]},()=>o.forEach(e=>console.log(e)))}},ct=e=>function(e){return{add:(t,n,o,r)=>{e.command({command:t,describe:n,builder:o,handler:r})}}}(ie).add(e.command,e.describe,e.builder,e.handler);ct(qe),ct(Ve),ct(et),ct(nt),ct(rt),ct(De),ct(Fe),ct(Ie),ct(it),ct(We),ct(Oe),ct(je),ct(Qe),ie.usage("mfn <command> [options]\n\nMaster CLI for developers and AI agents — headless, JSON-first commands that\nreplace boilerplate agents regenerate on every machine. Every command supports\n--json (machine output) and -h/--help (this text).").version(ne).alias("version","v").help().alias("help","h").epilogue("Discover every command (machine-readable): mfn capabilities --json\nAgent contract & examples: see llms.txt in this package.\nDocs: https://github.com/Master4Novice/master-cli#readme").wrap(null).strict().demandCommand(1,"No command given. Run `mfn capabilities` to list commands.").fail((e,t)=>{t&&ge("CommandError",t.message||String(t),1),ge("UsageError",e||"Invalid command invocation.",2)}).parse();
|
|
35
|
+
function(e){if(Array.isArray(e))return e.map(e=>"string"!=typeof e?e+"":e);e=e.trim();let t=0,n=null,o=null,r=null;const s=[];for(let i=0;i<e.length;i++)n=o,o=e.charAt(i)," "!==o||r?(o===r?r=null:"'"!==o&&'"'!==o||r||(r=o),s[t]||(s[t]=""),s[t]+=o):" "!==n&&t++;return s}(e),r="string"==typeof e,s=function(e){const t=[],n=Object.create(null);let o=!0;Object.keys(e).forEach(function(n){t.push([].concat(e[n],n))});for(;o;){o=!1;for(let e=0;e<t.length;e++)for(let n=e+1;n<t.length;n++){if(t[e].filter(function(e){return-1!==t[n].indexOf(e)}).length){t[e]=t[e].concat(t[n]),t.splice(n,1),o=!0;break}}}return t.forEach(function(e){const t=(e=e.filter(function(e,t,n){return n.indexOf(e)===t})).pop();void 0!==t&&"string"==typeof t&&(n[t]=e)}),n}(Object.assign(Object.create(null),n.alias)),i=Object.assign({"boolean-negation":!0,"camel-case-expansion":!0,"combine-arrays":!1,"dot-notation":!0,"duplicate-arguments-array":!0,"flatten-duplicate-arrays":!0,"greedy-arrays":!0,"halt-at-non-option":!1,"nargs-eats-options":!1,"negation-prefix":"no-","parse-numbers":!0,"parse-positional-numbers":!0,"populate--":!1,"set-placeholder-key":!1,"short-option-groups":!0,"strip-aliased":!1,"strip-dashed":!1,"unknown-options-as-args":!1},n.configuration),a=Object.assign(Object.create(null),n.default),l=n.configObjects||[],c=n.envPrefix,d=i["populate--"],u=d?"--":"_",m=Object.create(null),p=Object.create(null),f=n.__||W.format,h={aliases:Object.create(null),arrays:Object.create(null),bools:Object.create(null),strings:Object.create(null),numbers:Object.create(null),counts:Object.create(null),normalize:Object.create(null),configs:Object.create(null),nargs:Object.create(null),coercions:Object.create(null),keys:[]},g=/^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/,y=new RegExp("^--"+i["negation-prefix"]+"(.+)");[].concat(n.array||[]).filter(Boolean).forEach(function(e){const t="object"==typeof e?e.key:e,n=Object.keys(e).map(function(e){return{boolean:"bools",string:"strings",number:"numbers"}[e]}).filter(Boolean).pop();n&&(h[n][t]=!0),h.arrays[t]=!0,h.keys.push(t)}),[].concat(n.boolean||[]).filter(Boolean).forEach(function(e){h.bools[e]=!0,h.keys.push(e)}),[].concat(n.string||[]).filter(Boolean).forEach(function(e){h.strings[e]=!0,h.keys.push(e)}),[].concat(n.number||[]).filter(Boolean).forEach(function(e){h.numbers[e]=!0,h.keys.push(e)}),[].concat(n.count||[]).filter(Boolean).forEach(function(e){h.counts[e]=!0,h.keys.push(e)}),[].concat(n.normalize||[]).filter(Boolean).forEach(function(e){h.normalize[e]=!0,h.keys.push(e)}),"object"==typeof n.narg&&Object.entries(n.narg).forEach(([e,t])=>{"number"==typeof t&&(h.nargs[e]=t,h.keys.push(e))}),"object"==typeof n.coerce&&Object.entries(n.coerce).forEach(([e,t])=>{"function"==typeof t&&(h.coercions[e]=t,h.keys.push(e))}),void 0!==n.config&&(Array.isArray(n.config)||"string"==typeof n.config?[].concat(n.config).filter(Boolean).forEach(function(e){h.configs[e]=!0}):"object"==typeof n.config&&Object.entries(n.config).forEach(([e,t])=>{"boolean"!=typeof t&&"function"!=typeof t||(h.configs[e]=t)})),function(...e){e.forEach(function(e){Object.keys(e||{}).forEach(function(e){h.aliases[e]||(h.aliases[e]=[].concat(s[e]||[]),h.aliases[e].concat(e).forEach(function(t){if(/-/.test(t)&&i["camel-case-expansion"]){const n=P(t);n!==e&&-1===h.aliases[e].indexOf(n)&&(h.aliases[e].push(n),m[n]=!0)}}),h.aliases[e].concat(e).forEach(function(t){if(t.length>1&&/[A-Z]/.test(t)&&i["camel-case-expansion"]){const n=function(e,t){const n=e.toLowerCase();t=t||"-";let o="";for(let r=0;r<e.length;r++){const s=n.charAt(r),i=e.charAt(r);o+=s!==i&&r>0?`${t}${n.charAt(r)}`:i}return o}(t,"-");n!==e&&-1===h.aliases[e].indexOf(n)&&(h.aliases[e].push(n),m[n]=!0)}}),h.aliases[e].forEach(function(t){h.aliases[t]=[e].concat(h.aliases[e].filter(function(e){return t!==e}))}))})})}(n.key,s,n.default,h.arrays),Object.keys(a).forEach(function(e){(h.aliases[e]||[]).forEach(function(t){a[t]=a[e]})});let b=null;Object.keys(h.counts).find(e=>z(e,h.arrays)?(b=Error(f("Invalid configuration: %s, opts.count excludes opts.array.",e)),!0):!!z(e,h.nargs)&&(b=Error(f("Invalid configuration: %s, opts.count excludes opts.narg.",e)),!0));let v=[];const x=Object.assign(Object.create(null),{_:[]}),w={};for(let e=0;e<o.length;e++){const t=o[e],n=t.replace(/^-{3,}/,"---");let r,s,a,l,c,d;if("--"!==t&&/^-/.test(t)&&R(t))$(t);else{if(n.match(/^---+(=|$)/)){$(t);continue}if(t.match(/^--.+=/)||!i["short-option-groups"]&&t.match(/^-.+=/))l=t.match(/^--?([^=]+)=([\s\S]*)$/),null!==l&&Array.isArray(l)&&l.length>=3&&(z(l[1],h.arrays)?e=S(e,l[1],o,l[2]):!1!==z(l[1],h.nargs)?e=j(e,l[1],o,l[2]):N(l[1],l[2],!0));else if(t.match(y)&&i["boolean-negation"])l=t.match(y),null!==l&&Array.isArray(l)&&l.length>=2&&(s=l[1],N(s,!!z(s,h.arrays)&&[!1]));else if(t.match(/^--.+/)||!i["short-option-groups"]&&t.match(/^-[^-]+/))l=t.match(/^--?(.+)/),null!==l&&Array.isArray(l)&&l.length>=2&&(s=l[1],z(s,h.arrays)?e=S(e,s,o):!1!==z(s,h.nargs)?e=j(e,s,o):(c=o[e+1],void 0===c||c.match(/^-/)&&!c.match(g)||z(s,h.bools)||z(s,h.counts)?/^(true|false)$/.test(c)?(N(s,c),e++):N(s,_(s)):(N(s,c),e++)));else if(t.match(/^-.\..+=/))l=t.match(/^-([^=]+)=([\s\S]*)$/),null!==l&&Array.isArray(l)&&l.length>=3&&N(l[1],l[2]);else if(t.match(/^-.\..+/)&&!t.match(g))c=o[e+1],l=t.match(/^-(.\..+)/),null!==l&&Array.isArray(l)&&l.length>=2&&(s=l[1],void 0===c||c.match(/^-/)||z(s,h.bools)||z(s,h.counts)?N(s,_(s)):(N(s,c),e++));else if(t.match(/^-[^-]+/)&&!t.match(g)){a=t.slice(1,-1).split(""),r=!1;for(let n=0;n<a.length;n++){if(c=t.slice(n+2),a[n+1]&&"="===a[n+1]){d=t.slice(n+3),s=a[n],z(s,h.arrays)?e=S(e,s,o,d):!1!==z(s,h.nargs)?e=j(e,s,o,d):N(s,d),r=!0;break}if("-"!==c){if(/[A-Za-z]/.test(a[n])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(c)&&!1===z(c,h.bools)){N(a[n],c),r=!0;break}if(a[n+1]&&a[n+1].match(/\W/)){N(a[n],c),r=!0;break}N(a[n],_(a[n]))}else N(a[n],c)}s=t.slice(-1)[0],r||"-"===s||(z(s,h.arrays)?e=S(e,s,o):!1!==z(s,h.nargs)?e=j(e,s,o):(c=o[e+1],void 0===c||/^(-|--)[^-]/.test(c)&&!c.match(g)||z(s,h.bools)||z(s,h.counts)?/^(true|false)$/.test(c)?(N(s,c),e++):N(s,_(s)):(N(s,c),e++)))}else if(t.match(/^-[0-9]$/)&&t.match(g)&&z(t.slice(1),h.bools))s=t.slice(1),N(s,_(s));else{if("--"===t){v=o.slice(e+1);break}if(i["halt-at-non-option"]){v=o.slice(e);break}$(t)}}}function $(e){const t=I("_",e);"string"!=typeof t&&"number"!=typeof t||x._.push(t)}function j(e,t,n,o){let r,s=z(t,h.nargs);if(s="number"!=typeof s||isNaN(s)?1:s,0===s)return F(o)||(b=Error(f("Argument unexpected for: %s",t))),N(t,_(t)),e;let a=F(o)?0:1;if(i["nargs-eats-options"])n.length-(e+1)+a<s&&(b=Error(f("Not enough arguments following: %s",t))),a=s;else{for(r=e+1;r<n.length&&(!n[r].match(/^-[^0-9]/)||n[r].match(g)||R(n[r]));r++)a++;a<s&&(b=Error(f("Not enough arguments following: %s",t)))}let l=Math.min(a,s);for(!F(o)&&l>0&&(N(t,o),l--),r=e+1;r<l+e+1;r++)N(t,n[r]);return e+l}function S(e,t,n,o){let s=[],l=o||n[e+1];const c=z(t,h.nargs);if(z(t,h.bools)&&!/^(true|false)$/.test(l))s.push(!0);else if(F(l)||F(o)&&/^-/.test(l)&&!g.test(l)&&!R(l)){if(void 0!==a[t]){const e=a[t];s=Array.isArray(e)?e:[e]}}else{F(o)||s.push(E(t,o,!0));for(let o=e+1;o<n.length&&!(!i["greedy-arrays"]&&s.length>0||c&&"number"==typeof c&&s.length>=c)&&(l=n[o],!/^-/.test(l)||g.test(l)||R(l));o++)e=o,s.push(E(t,l,r))}return"number"==typeof c&&(c&&s.length<c||isNaN(c)&&0===s.length)&&(b=Error(f("Not enough arguments following: %s",t))),N(t,s),e}function N(e,t,n=r){if(/-/.test(e)&&i["camel-case-expansion"]){const t=e.split(".").map(function(e){return P(e)}).join(".");k(e,t)}const o=E(e,t,n),s=e.split(".");if(M(x,s,o),h.aliases[e]&&h.aliases[e].forEach(function(e){const t=e.split(".");M(x,t,o)}),s.length>1&&i["dot-notation"]&&(h.aliases[s[0]]||[]).forEach(function(t){let n=t.split(".");const r=[].concat(s);r.shift(),n=n.concat(r),(h.aliases[e]||[]).includes(n.join("."))||M(x,n,o)}),z(e,h.normalize)&&!z(e,h.arrays)){[e].concat(h.aliases[e]||[]).forEach(function(e){Object.defineProperty(w,e,{enumerable:!0,get:()=>t,set(e){t="string"==typeof e?W.normalize(e):e}})})}}function k(e,t){h.aliases[e]&&h.aliases[e].length||(h.aliases[e]=[t],m[t]=!0),h.aliases[t]&&h.aliases[t].length||k(t,e)}function E(e,t,n){n&&(t=function(e){return"string"!=typeof e||"'"!==e[0]&&'"'!==e[0]||e[e.length-1]!==e[0]?e:e.substring(1,e.length-1)}(t)),(z(e,h.bools)||z(e,h.counts))&&"string"==typeof t&&(t="true"===t);let o=Array.isArray(t)?t.map(function(t){return I(e,t)}):I(e,t);return z(e,h.counts)&&(F(o)||"boolean"==typeof o)&&(o=J()),z(e,h.normalize)&&z(e,h.arrays)&&(o=Array.isArray(t)?t.map(e=>W.normalize(e)):W.normalize(t)),o}function I(e,t){if(!i["parse-positional-numbers"]&&"_"===e)return t;if(!z(e,h.strings)&&!z(e,h.bools)&&!Array.isArray(t)){(null!=(n=t)&&("number"==typeof n||!!/^0x[0-9a-f]+$/i.test(n)||!/^0[^.]/.test(n)&&/^[-]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(n))&&i["parse-numbers"]&&Number.isSafeInteger(Math.floor(parseFloat(`${t}`)))||!F(t)&&z(e,h.numbers))&&(t=Number(t))}var n;return t}function O(e,t){Object.keys(e).forEach(function(n){const o=e[n],r=t?t+"."+n:n;"object"==typeof o&&null!==o&&!Array.isArray(o)&&i["dot-notation"]?O(o,r):(!L(x,r.split("."))||z(r,h.arrays)&&i["combine-arrays"])&&N(r,o)})}function A(e,t){if(void 0===c)return;const n="string"==typeof c?c:"",o=W.env();Object.keys(o).forEach(function(r){if(""===n||0===r.lastIndexOf(n,0)){const s=r.split("__").map(function(e,t){return 0===t&&(e=e.substring(n.length)),P(e)});(t&&h.configs[s.join(".")]||!t)&&!L(e,s)&&N(s.join("."),o[r])}})}function T(e,t,n,o=!1){Object.keys(n).forEach(function(r){L(e,r.split("."))||(M(e,r.split("."),n[r]),o&&(p[r]=!0),(t[r]||[]).forEach(function(t){L(e,t.split("."))||M(e,t.split("."),n[r])}))})}function L(e,t){let n=e;i["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){n=n[e]||{}});const o=t[t.length-1];return"object"==typeof n&&o in n}function M(e,t,n){let o=e;i["dot-notation"]||(t=[t.join(".")]),t.slice(0,-1).forEach(function(e){e=Z(e),"object"==typeof o&&void 0===o[e]&&(o[e]={}),"object"!=typeof o[e]||Array.isArray(o[e])?(Array.isArray(o[e])?o[e].push({}):o[e]=[o[e],{}],o=o[e][o[e].length-1]):o=o[e]});const r=Z(t[t.length-1]),s=z(t.join("."),h.arrays),a=Array.isArray(n);let l=i["duplicate-arguments-array"];!l&&z(r,h.nargs)&&(l=!0,(!F(o[r])&&1===h.nargs[r]||Array.isArray(o[r])&&o[r].length===h.nargs[r])&&(o[r]=void 0)),n===J()?o[r]=J(o[r]):Array.isArray(o[r])?l&&s&&a?o[r]=i["flatten-duplicate-arrays"]?o[r].concat(n):(Array.isArray(o[r][0])?o[r]:[o[r]]).concat([n]):l||Boolean(s)!==Boolean(a)?o[r]=o[r].concat([n]):o[r]=n:void 0===o[r]&&s?o[r]=a?n:[n]:!l||void 0===o[r]||z(r,h.counts)||z(r,h.bools)?o[r]=n:o[r]=[o[r],n]}function z(e,t){const n=[].concat(h.aliases[e]||[],e),o=Object.keys(t),r=n.find(e=>o.includes(e));return!!r&&t[r]}function C(e){const t=Object.keys(h);return[].concat(t.map(e=>h[e])).some(function(t){return Array.isArray(t)?t.includes(e):t[e]})}function R(e){return i["unknown-options-as-args"]&&function(e){if(e=e.replace(/^-{3,}/,"--"),e.match(g))return!1;if(function(e){if(e.match(g)||!e.match(/^-[^-]+/))return!1;let t,n=!0;const o=e.slice(1).split("");for(let r=0;r<o.length;r++){if(t=e.slice(r+2),!C(o[r])){n=!1;break}if(o[r+1]&&"="===o[r+1]||"-"===t||/[A-Za-z]/.test(o[r])&&/^-?\d+(\.\d*)?(e-?\d+)?$/.test(t)||o[r+1]&&o[r+1].match(/\W/))break}return n}(e))return!1;return!function(e,...t){return[].concat(...t).some(function(t){const n=e.match(t);return n&&C(n[1])})}(e,/^-+([^=]+?)=[\s\S]*$/,y,/^-+([^=]+?)$/,/^-+([^=]+?)-$/,/^-+([^=]+?\d+)$/,/^-+([^=]+?)\W+.*$/)}(e)}function _(e){return z(e,h.bools)||z(e,h.counts)||!(`${e}`in a)?(t=function(e){let t=U.BOOLEAN;return z(e,h.strings)?t=U.STRING:z(e,h.numbers)?t=U.NUMBER:z(e,h.bools)?t=U.BOOLEAN:z(e,h.arrays)&&(t=U.ARRAY),t}(e),{[U.BOOLEAN]:!0,[U.STRING]:"",[U.NUMBER]:void 0,[U.ARRAY]:[]}[t]):a[e];var t}function F(e){return void 0===e}return A(x,!0),A(x,!1),function(e){const t=Object.create(null);T(t,h.aliases,a),Object.keys(h.configs).forEach(function(n){const o=e[n]||t[n];if(o)try{let e=null;const t=W.resolve(W.cwd(),o),r=h.configs[n];if("function"==typeof r){try{e=r(t)}catch(t){e=t}if(e instanceof Error)return void(b=e)}else e=W.require(t);O(e)}catch(t){"PermissionDenied"===t.name?b=t:e[n]&&(b=Error(f("Invalid JSON config file: %s",o)))}})}(x),void 0!==l&&l.forEach(function(e){O(e)}),T(x,h.aliases,a,!0),function(e){let t;const n=new Set;Object.keys(e).forEach(function(o){if(!n.has(o)&&(t=z(o,h.coercions),"function"==typeof t))try{const r=I(o,t(e[o]));[].concat(h.aliases[o]||[],o).forEach(t=>{n.add(t),e[t]=r})}catch(e){b=e}})}(x),i["set-placeholder-key"]&&function(e){h.keys.forEach(t=>{~t.indexOf(".")||void 0===e[t]&&(e[t]=void 0)})}(x),Object.keys(h.counts).forEach(function(e){L(x,e.split("."))||N(e,0)}),d&&v.length&&(x[u]=[]),v.forEach(function(e){x[u].push(e)}),i["camel-case-expansion"]&&i["strip-dashed"]&&Object.keys(x).filter(e=>"--"!==e&&e.includes("-")).forEach(e=>{delete x[e]}),i["strip-aliased"]&&[].concat(...Object.keys(s).map(e=>s[e])).forEach(e=>{i["camel-case-expansion"]&&e.includes("-")&&delete x[e.split(".").map(e=>P(e)).join(".")],delete x[e]}),{aliases:Object.assign({},h.aliases),argv:Object.assign(w,x),configuration:i,defaulted:Object.assign({},p),error:b,newAliases:Object.assign({},m)}}}({cwd:process.cwd,env:()=>K,format:t,normalize:r,resolve:o,require:e=>{if("undefined"!=typeof require)return require(e);if(e.match(/\.json$/))return JSON.parse(i(e,"utf8"));throw Error("only .json config files are supported in ESM")}});var Q={fs:{readFileSync:i,writeFile:a},format:t,resolve:o,exists:e=>{try{return l(e).isFile()}catch(e){return!1}}};let X;class ee{constructor(e){e=e||{},this.directory=e.directory||"./locales",this.updateFiles="boolean"!=typeof e.updateFiles||e.updateFiles,this.locale=e.locale||"en",this.fallbackToLanguage="boolean"!=typeof e.fallbackToLanguage||e.fallbackToLanguage,this.cache=Object.create(null),this.writeQueue=[]}__(...e){if("string"!=typeof arguments[0])return this._taggedLiteral(arguments[0],...arguments);const t=e.shift();let n=function(){};return"function"==typeof e[e.length-1]&&(n=e.pop()),n=n||function(){},this.cache[this.locale]||this._readLocaleFile(),!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]=t,this._enqueueWrite({directory:this.directory,locale:this.locale,cb:n})):n(),X.format.apply(X.format,[this.cache[this.locale][t]||t].concat(e))}__n(){const e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),o=e.shift();let r=function(){};"function"==typeof e[e.length-1]&&(r=e.pop()),this.cache[this.locale]||this._readLocaleFile();let s=1===o?t:n;if(this.cache[this.locale][t]){s=this.cache[this.locale][t][1===o?"one":"other"]}!this.cache[this.locale][t]&&this.updateFiles?(this.cache[this.locale][t]={one:t,other:n},this._enqueueWrite({directory:this.directory,locale:this.locale,cb:r})):r();const i=[s];return~s.indexOf("%d")&&i.push(o),X.format.apply(X.format,i.concat(e))}setLocale(e){this.locale=e}getLocale(){return this.locale}updateLocale(e){this.cache[this.locale]||this._readLocaleFile();for(const t in e)Object.prototype.hasOwnProperty.call(e,t)&&(this.cache[this.locale][t]=e[t])}_taggedLiteral(e,...t){let n="";return e.forEach(function(e,o){const r=t[o+1];n+=e,void 0!==r&&(n+="%s")}),this.__.apply(this,[n].concat([].slice.call(t,1)))}_enqueueWrite(e){this.writeQueue.push(e),1===this.writeQueue.length&&this._processWriteQueue()}_processWriteQueue(){const e=this,t=this.writeQueue[0],n=t.directory,o=t.locale,r=t.cb,s=this._resolveLocaleFile(n,o),i=JSON.stringify(this.cache[o],null,2);X.fs.writeFile(s,i,"utf-8",function(t){e.writeQueue.shift(),e.writeQueue.length>0&&e._processWriteQueue(),r(t)})}_readLocaleFile(){let e={};const t=this._resolveLocaleFile(this.directory,this.locale);try{X.fs.readFileSync&&(e=JSON.parse(X.fs.readFileSync(t,"utf-8")))}catch(n){if(n instanceof SyntaxError&&(n.message="syntax error in "+t),"ENOENT"!==n.code)throw n;e={}}this.cache[this.locale]=e}_resolveLocaleFile(e,t){let n=X.resolve(e,"./",t+".json");if(this.fallbackToLanguage&&!this._fileExistsSync(n)&&~t.lastIndexOf("_")){const o=X.resolve(e,"./",t.split("_")[0]+".json");this._fileExistsSync(o)&&(n=o)}return n}_fileExistsSync(e){return X.exists(e)}}let te;try{te=c(import.meta.url)}catch(e){te=process.cwd()}te.substring(0,te.lastIndexOf("node_modules"))||process.cwd(),process.cwd,process.exit,process.nextTick,void 0!==process.stdout.columns&&process.stdout.columns,function(e,t){X=t;const n=new ee(e);n.__.bind(n),n.__n.bind(n),n.setLocale.bind(n),n.getLocale.bind(n),n.updateLocale.bind(n),n.locale}({directory:o(te,"../../../locales"),updateFiles:!1},Q);const ne=[{name:"capabilities",category:"discovery",summary:"Self-describing manifest of every command an agent can call",examples:["mfn capabilities --json"]},{name:"epoch",category:"time",summary:"Convert between epoch timestamps and dates (auto-detects unit)",examples:["mfn epoch 1622547800 --json","mfn epoch --from 2021-06-01T11:43:20Z --json"]},{name:"date",category:"time",summary:"Convert/format a date across timezones (defaults to now)",examples:["mfn date --json","mfn date 2024-07-04T15:30:30Z --tz America/New_York --json"]},{name:"decode",category:"crypto",summary:"Decode a JWT token (header + payload; signature not verified)",examples:["mfn decode -t <jwt> --json"]},{name:"kill",category:"net",summary:"Kill the process(es) listening on specific ports",examples:["mfn kill -p 3000 8080 -y --json"]},{name:"sc",category:"code",summary:"Find files/folders under the current directory (fuzzy match)",examples:["mfn sc service --json"]},{name:"cts",category:"code",summary:"Print (or export) a tree of the current working directory",examples:["mfn cts --json","mfn cts -t png"]},{name:"update",category:"discovery",summary:"Update the CLI or a specified package to the latest version",examples:["mfn update --json","mfn update <package> --json"]},{name:"id",category:"crypto",summary:"Generate identifiers (UUID v4/v7 or URL-safe nano id)",examples:["mfn id --json","mfn id -t uuid7 -n 3 --json"]},{name:"hash",category:"crypto",summary:"Hash a string, file, or stdin (md5/sha1/sha256/sha512)",examples:["mfn hash hello --json","mfn hash -a md5 -f ./file.txt --json"]},{name:"encode",category:"crypto",summary:"Encode/decode text (base64, base64url, hex, url)",examples:["mfn encode hello --json","mfn encode aGVsbG8= -d --json"]},{name:"random",category:"crypto",summary:"Generate secure random bytes or a password",examples:["mfn random --json","mfn random -p -l 32 --json"]},{name:"port",category:"net",summary:"Find a free port, or check whether a specific port is available",examples:["mfn port --json","mfn port -c 3000 --json"]},{name:"json",category:"data",summary:"Extract one value/keys/length from JSON without reading the whole document",examples:["mfn json scripts.build -f package.json --json","cat d.json | mfn json users[0].name --json"]},{name:"schema",category:"data",summary:"Infer the shape of a JSON document (paths + types) without dumping the data",examples:["mfn schema -f response.json --json","curl -s api/u | mfn schema --json"]},{name:"count",category:"text",summary:"Lines/words/chars/bytes + LLM token estimate of a file, stdin, or text",examples:["mfn count -f big.log --json","git diff | mfn count --json"]},{name:"lines",category:"text",summary:"Read an exact line range of a file (1-based) instead of the whole file",examples:["mfn lines src/app.ts -s 120 -n 30 --json"]},{name:"diff",category:"text",summary:"Line diff of two files as structured hunks (counts first, content optional)",examples:["mfn diff old.json new.json --json","mfn diff a.txt b.txt -s --json"]},{name:"freq",category:"text",summary:"Most frequent lines of a file/stdin (log analysis in one call)",examples:["mfn freq error.log -t 5 --json"]},{name:"case",category:"text",summary:"Convert strings between naming styles (camel, snake, kebab, pascal, …)",examples:["mfn case getUserName -t snake --json","mfn case my-component --json"]},{name:"escape",category:"text",summary:"Escape text exactly for shell, JSON, regex, HTML, or URL contexts",examples:['mfn escape "it\'s done" --json',"mfn escape 1.2.3 -a regex --json"]},{name:"calc",category:"data",summary:"Exact arithmetic — integer math in BigInt, no float drift, no guessing",examples:['mfn calc "2^53 + 1" --json','mfn calc "(3 + 4) * 5" --json']},{name:"semver",category:"data",summary:"Validate, compare, sort, or bump semantic versions per semver.org",examples:["mfn semver 1.10.0 1.9.2 --json","mfn semver 1.2.3 -b minor --json"]},{name:"cron",category:"time",summary:"Validate a cron expression, explain it, and compute the next run times",examples:['mfn cron "*/15 9-17 * * 1-5" --json','mfn cron "@daily" -n 1 --json']},{name:"regex",category:"text",summary:"Test a regular expression against text — verify instead of guessing",examples:['mfn regex "TODO[:!]?" -f src/app.ts --json']},{name:"url",category:"data",summary:"Parse a URL into components with decoded query parameters",examples:['mfn url "https://api.x.com/v2/users?id=42" --json']},{name:"have",category:"system",summary:"Check which tools are installed (path + version) in one call",examples:["mfn have node git docker --json"]},{name:"sys",category:"system",summary:"One-shot system facts: OS, node, CPU, memory, shell, timezone, paths",examples:["mfn sys --json"]},{name:"repo",category:"code",summary:"One-shot git summary: branch, dirty counts, ahead/behind, last commits",examples:["mfn repo --json","mfn repo -n 10 --json"]},{name:"env",category:"system",summary:"Inspect environment variables with automatic secret redaction",examples:["mfn env NODE_ENV PATH --json","mfn env -p NEXT_PUBLIC_ --json"]},{name:"size",category:"code",summary:"Total size + largest files/dirs under a directory in one call",examples:["mfn size --json","mfn size ./src -t 5 --json"]},{name:"ext",category:"code",summary:"File counts and bytes per extension — project composition at a glance",examples:["mfn ext --json"]},{name:"ip",category:"net",summary:"Local network interfaces and addresses (no ifconfig parsing)",examples:["mfn ip --json"]},{name:"outline",category:"code",summary:"Outline a source file: functions/classes/exports with line numbers",examples:["mfn outline src/app.ts --json","mfn outline README.md --json"]},{name:"imports",category:"code",summary:"List a file’s imports, or find every file that imports a module",examples:["mfn imports src/app.ts --json","mfn imports --who utility --json"]},{name:"replace",category:"code",summary:"Literal find/replace across files — dry-run by default, JSON change report",examples:['mfn replace "oldName" "newName" -g "src/**/*.ts" --json','mfn replace "v1" "v2" -g "**/*.md" --write --json']},{name:"recent",category:"code",summary:"Most recently modified files under a directory, with age",examples:["mfn recent --json","mfn recent ./src -t 5 --json"]},{name:"pkg",category:"code",summary:"Declared vs installed dependency versions — drift in one call",examples:["mfn pkg --json","mfn pkg typescript --json"]},{name:"dotenv",category:"system",summary:"Check .env against .env.example — missing/extra keys, values never shown",examples:["mfn dotenv --json","mfn dotenv -f .env.local -e .env.example --json"]},{name:"wait",category:"net",summary:"Block until a port, file, or URL is ready (with timeout) — no sleep loops",examples:["mfn wait -p 3000 -t 30 --json","mfn wait -u http://localhost:3000/health --json"]},{name:"ports",category:"net",summary:"List ALL listening TCP ports with their owning processes",examples:["mfn ports --json"]},{name:"http",category:"net",summary:"Probe a URL: status, headers, timing, capped body preview",examples:["mfn http https://api.github.com --json","mfn http localhost:3000/health --json"]},{name:"base",category:"data",summary:"Convert numbers between bases (hex/dec/bin/oct) exactly, BigInt-safe",examples:["mfn base 0xff --json","mfn base 255 --json"]},{name:"clip",category:"system",summary:"Read or write the system clipboard (pbcopy/xclip/clip.exe handled for you)",examples:["mfn clip --json","git diff | mfn clip --json"]},{name:"notify",category:"system",summary:"Desktop notification — tell the user a long task finished, hands-free",examples:['mfn notify "build finished" --json']},{name:"open",category:"system",summary:"Open a file or URL in the default app/browser (target validated first)",examples:["mfn open coverage/index.html --json"]},{name:"procs",category:"system",summary:"Search running processes by name: pid/cpu/mem in one call",examples:["mfn procs node --json","mfn procs -t 10 --json"]},{name:"disk",category:"system",summary:"Disk usage per mount (total/free/used%) without df parsing",examples:["mfn disk --json"]},{name:"trash",category:"system",summary:"Move files/dirs to the OS trash — reversible delete, never rm -rf",examples:["mfn trash old-build.log --json","mfn trash dist coverage --json"]},{name:"dns",category:"net",summary:"Resolve a hostname: A/AAAA/CNAME/MX/TXT/NS in one call",examples:["mfn dns github.com --json","mfn dns example.com -t mx --json"]}],oe=[...new Set(ne.map(e=>e.category))];var re="@master4n/master-cli",se="3.0.3";const ie=["add --json to any command for clean, machine-readable output","piping a command (no TTY) auto-emits JSON — great for agents & scripts","every command returns a stable exit code: 0 = ok, non-zero = failure","mfn <command> --help shows its flags and copy-paste examples","mfn capabilities --json lists every command an agent can call","mfn kill -p 3000 8080 -y frees stuck ports in one shot"],ae=e=>d.hex(e)("─".repeat(62)),le=()=>(new Date).toISOString();function ce(){return{info:e=>console.error(`${d.blue("INFO")} [${d.magenta(le())}] ${d.white(e)}`),warn:e=>console.error(`${d.yellow("WARN")} [${d.magenta(le())}] ${d.white(e)}`),error:e=>console.error(`${d.red("ERROR")} [${d.magenta(le())}] ${d.white(e)}`),debug:e=>console.error(`${d.cyan("DEBUG")} [${d.magenta(le())}] ${d.white(e)}`)}}function de(){const e=u.homedir();return n.join(e,".mfn","cache")}const ue=e=>d.green(e);async function me(e,t){await f.writeJson(t,e,{spaces:2})}!function(){const e=u.homedir(),t=n.join(e,".mfn","cache");if(!s.existsSync(t))try{s.mkdirSync(t,{recursive:!0,mode:448})}catch{}}(),await(async()=>{if(!(Boolean(process.stdout.isTTY)&&!process.argv.includes("--json")))return;const[{default:e},{default:t}]=await Promise.all([import("figlet"),import("boxen")]),n=await new Promise((t,n)=>{e("M4N-CLI",(e,o)=>e?n(e):t(o??""))}),o=t(d.hex("#27A244").bold(n),{padding:1,margin:{top:1,bottom:0,left:1,right:1},borderStyle:"round",borderColor:"#C1C110",dimBorder:!0}),r=function(){try{return(u.userInfo().username||"").replace(/[^\p{L}\p{N} ._-]/gu,"").slice(0,32)}catch{return""}}(),s=d.dim(" • "),i=[d.hex("#44bcd8").bold(`mfn v${se}`),d.gray(`node ${process.version}`),d.gray(`${process.platform}/${process.arch}`),d.green.bold("AI-friendly")].join(s);let a="";try{const{getEpochNow:e}=await import("@master4n/temporal-transformer"),t=e();a=`${t.iso.replace("T"," ").slice(0,19)} ${d.dim(`(${t.timezone})`)}`}catch{}const l=new Map;for(const e of ne)l.set(e.category,(l.get(e.category)??0)+1);const c=[...l.entries()].map(([e,t])=>`${d.cyan(e)}${d.dim(`(${t})`)}`).join(d.dim(" · "))+d.dim(" → mfn capabilities"),m=ie[Math.floor(Math.random()*ie.length)],p=(e="")=>console.error(e);p(ae("#C1C110")),p(o),p(" "+(r?d.magenta(`👋 Welcome, ${d.bold(r)}`):d.magenta("👋 Welcome"))+s+i),a&&p(" "+d.gray("🕒 ")+d.white(a)),p(""),p(" "+d.yellow.bold("🧰 tools ")+c),p(" "+d.yellow.bold("💡 tip ")+d.white(m)),p(" "+d.yellow.bold("🤖 help ")+d.white("mfn <command> --help")),p(ae("#C1C110"))})();const pe=e(process.argv.slice(B()+1));const fe=d.hex("#44bcd8").bold("mfn");var he=pe.scriptName(fe);const ge=()=>Boolean(process.stdout.isTTY),ye=e=>e.option("json",{type:"boolean",default:!1,describe:"Emit a single machine-readable JSON object on stdout"}),be=e=>Boolean(e?.json)||!ge(),ve=e=>{process.stdout.write(JSON.stringify(e)+"\n")};function xe(e,t,n){be(e)?ve({ok:!0,...t}):n()}function we(e,t,n,o=1){be(e)?ve({ok:!1,error:t,message:n}):console.error(n),process.exit(o)}const $e=e=>ge()&&!e?.json;async function je(){if(process.stdin.isTTY)return"";const e=[];for await(const t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf8")}function Se(e,t,n=2){process.argv.includes("--json")||!ge()?process.stdout.write(JSON.stringify({ok:!1,error:e,message:t})+"\n"):console.error(t),process.exit(n)}const Ne=ce(),ke=n.join(de(),"cts_ignore.json"),Ee=["node_modules",".git",".nx"];function Ie(e,t,o=""){let r,s="";try{r=f.readdirSync(e).filter(e=>!t.has(e)).sort()}catch{return`${o}└── [unreadable]\n`}return r.forEach((i,a)=>{const l=n.join(e,i),c=a===r.length-1;let d;try{d=f.statSync(l).isDirectory()}catch{d=!1}s+=`${o}${c?"└── ":"├── "}${i}\n`,d&&(s+=Ie(l,t,`${o}${c?" ":"│ "}`))}),s}const Oe={command:"cts",describe:"Print (or export) a tree of the current working directory",builder:e=>ye(e).option("type",{alias:"t",describe:"Output format: text (stdout, default) or an image file",type:"string",choices:["text","svg","png","jpeg"],default:"text"}).option("ignore",{alias:"i",describe:"Folder names to ignore",type:"array"}).option("length",{alias:"l",describe:"Image height",type:"number",default:250}).option("breadth",{alias:"b",describe:"Image width",type:"number",default:200}).example("mfn cts","print the tree as text").example("mfn cts --json","tree as JSON").example("mfn cts -t png","export the tree to <dir>.png"),handler:async e=>{let t=e.ignore??[];t.length>0?await me({ignores:t},ke).catch(()=>{}):t=(await async function(){try{return await f.readJson(ke)}catch(e){if("ENOENT"===e.code)return{ignores:[]};throw e}}()).ignores??[];const o=new Set([...Ee,...t]),r=process.cwd(),s=n.basename(r);let i;try{i=s+"\n"+Ie(r,o)}catch(t){return we(e,"TreeError",`Failed to build tree for ${r}: ${t instanceof Error?t.message:String(t)}`)}const a=String(e.type);if("text"===a)return xe(e,{root:s,path:r,format:"text",tree:i},()=>{process.stdout.write(i.endsWith("\n")?i:i+"\n")});if(!function(...e){for(const t of e)if(isNaN(t)||t<1||t>1e3)return!1;return!0}(e.length,e.breadth))return we(e,"InvalidDimensions","Length & breadth must be numbers in 1..1000.",2);const l=`${s}.${a}`;try{const t=function(e,t,n){return`<svg xmlns="http://www.w3.org/2000/svg" width="${n}" height="${t}"><rect width="100%" height="100%" fill="white"/><g fill="black" font-family="monospace" font-size="12">${e.split("\n").map((e,t)=>`<text style="white-space: pre;" x="0" y="${20+20*t}">${e.replace(/&/g,"&").replace(/</g,"<")}</text>`).join("")}</g></svg>`}(i,e.length,e.breadth);if("svg"===a)f.outputFileSync(l,t);else{const{default:e}=await import("sharp");await e(Buffer.from(t))["png"===a?"png":"jpeg"]().toFile(l)}}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,"ExportFailed",`Failed to write ${l}: ${n}`)}xe(e,{root:s,path:r,format:a,file:l},()=>Ne.info(`Tree for ${s} written to ${l}`))}},Ae=ce(),Te=n.join(de(),"sc_ignore.json"),Le=["node_modules",".git","dist","build",".nx","coverage"];function Me(e,t,o){const r=[],s=new Set([...Le,...t]),i=(t,a)=>{if(a>o)return;let l;try{l=f.readdirSync(t,{withFileTypes:!0})}catch{return}for(const o of l){if(s.has(o.name))continue;const l=n.join(t,o.name),c=n.relative(e,l);r.push(o.isDirectory()?c+n.sep:c),o.isDirectory()&&i(l,a+1)}};return i(e,0),r}const ze={command:"sc [pattern]",describe:"Find files/folders under the current directory (fuzzy match)",builder:e=>ye(e).positional("pattern",{describe:"Fuzzy pattern to match against paths (omit to list all)",type:"string"}).option("ignore",{alias:"i",describe:"Additional directory names to ignore",type:"array"}).option("depth",{type:"number",default:6,describe:"Max recursion depth"}).option("limit",{type:"number",default:500,describe:"Max results returned"}).example("mfn sc service --json",'find paths matching "service"'),handler:async e=>{const t=process.cwd(),o=Number(e.depth),r=Number(e.limit);if(!Number.isInteger(o)||o<0)return we(e,"InvalidDepth","--depth must be a non-negative integer.",2);if(!Number.isInteger(r)||r<1)return we(e,"InvalidLimit","--limit must be a positive integer.",2);let s=e.ignore??[];if(s.length>0?await me({ignores:s},Te).catch(()=>{}):s=(await async function(){try{return await f.readJson(Te)}catch(e){if("ENOENT"===e.code)return{ignores:[]};throw e}}()).ignores??[],void 0===e.pattern&&$e(e))return async function(e,t,o,r,s){const{default:i}=await import("inquirer"),a=Me(t,o,r),{pattern:l}=await i.prompt([{type:"input",name:"pattern",message:ue("Filter (fuzzy, blank = all):")}]),c=String(l??"").trim(),d=(c?g.filter(c,a).map(e=>e.original):a).slice(0,s);if(0===d.length)return xe(e,{pattern:c||null,root:t,count:0,matches:[]},()=>Ae.warn("No matches."));const{selected:u}=await i.prompt([{type:"list",name:"selected",message:ue("Select a path:"),choices:d,pageSize:15,loop:!1}]),m=f.statSync(n.join(t,u));xe(e,{path:u,type:m.isDirectory()?"directory":"file"},()=>{Ae.info(`${m.isDirectory()?"Directory":"File"}: ${u}`),m.isDirectory()&&Ae.info(`cd ${u}`)})}(e,t,s,o,r);const i=Me(t,s,o),a=e.pattern?g.filter(String(e.pattern),i).map(e=>e.original):i,l=a.slice(0,r);xe(e,{pattern:e.pattern??null,root:t,count:l.length,truncated:a.length>l.length,matches:l},()=>{Ae.info(`${l.length} match(es) under ${t}`);for(const e of l)console.log(e)})}},Ce=ce();function Re(e){const t=Buffer.from(e,"base64url").toString("utf-8");return JSON.parse(t)}const _e={command:"decode",describe:"Decode a JWT token (header + payload; signature not verified)",builder:e=>ye(e).option("token",{alias:"t",describe:'JWT token to decode (a leading "Bearer " is stripped)',type:"string",demandOption:!0}).example("mfn decode -t <jwt> --json","decode a JWT"),handler:e=>{const t=String(e.token).replace(/^Bearer\s+/i,"").trim().split(".");if(3!==t.length)return we(e,"InvalidJWT","Invalid JWT structure: expected three dot-separated segments.",2);let n,o;try{n=Re(t[0]),o=Re(t[1])}catch(t){return we(e,"DecodeError",`Could not decode JWT: ${t instanceof Error?t.message:String(t)}`,2)}const r=o?.exp;let s;if("number"==typeof r&&Number.isFinite(r)){const e=Math.round(r-Date.now()/1e3);s={exp:r,expired:e<=0,expiresInSeconds:e}}xe(e,{header:n,payload:o,...s?{expiry:s}:{}},()=>{Ce.info("Decoded JWT (signature NOT verified)"),console.log(d.cyanBright.bold("header:")),console.log(d.greenBright(JSON.stringify(n,null,2))),console.log(d.cyanBright.bold("payload:")),console.log(d.greenBright(JSON.stringify(o,null,2))),s&&console.log(d.cyanBright.bold("expiry: ")+(s.expired?d.red(`expired ${-s.expiresInSeconds}s ago`):d.green(`valid for ${s.expiresInSeconds}s`)))})}},Fe=ce(),De="yyyy-MM-dd HH:mm:ss",Be=()=>Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC";function Pe(e){const t=e.format||De,n=e.tz||Be();let o,r,s;try{o=void 0!==e.from?y(String(e.from),e.inFormat,e.inTz).epochInMilliseconds:b().milliseconds}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,t instanceof Error?t.name:"ParseError",n,2)}try{r=v(o,"UTC",t),s=v(o,n,t)}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,t instanceof Error?t.name:"TimezoneError",n,2)}xe(e,{epochInSeconds:Math.floor(o/1e3),epochInMilliseconds:o,iso:new Date(o).toISOString(),utc:r,zoned:s,timezone:n,format:t},()=>{Fe.info("Date conversion"),console.table([{UTC:r,[n]:s,Epoch_ms:o}])})}const Ue={command:"date [from]",describe:"Convert/format a date across timezones (defaults to now)",builder:e=>ye(e).positional("from",{describe:"Date string to convert (ISO 8601 unless --in-format given). Omit for now.",type:"string"}).option("tz",{type:"string",describe:"Target output timezone (IANA; default: local)"}).option("format",{type:"string",describe:`Output format (default: ${De})`}).option("in-format",{type:"string",describe:"Luxon parse format for the input"}).option("in-tz",{type:"string",describe:"Timezone used to interpret the input"}).example("mfn date --json","now, in UTC + local").example("mfn date 2024-07-04T15:30:30Z --tz America/New_York --json","convert to a timezone"),handler:async e=>{const t={from:e.from,inFormat:e["in-format"],inTz:e["in-tz"],tz:e.tz,format:e.format,json:e.json};if(void 0===e.from&&void 0===e.tz&&void 0===e.format&&$e(e))return async function(e){const{default:t}=await import("inquirer"),n=await t.prompt([{type:"input",name:"from",message:ue("Date string (blank = now, ISO 8601):")},{type:"input",name:"tz",message:ue(`Target timezone (blank = ${Be()}):`)},{type:"input",name:"format",message:ue(`Output format (blank = ${De}):`)}]);Pe({...e,from:n.from?.trim()||void 0,tz:n.tz?.trim()||void 0,format:n.format?.trim()||void 0})}(t);Pe(t)}};const We=ce();function Je(e,t){let n;try{n=x(t)}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,t instanceof Error?t.name:"InvalidEpoch",n,2)}const o={seconds:1e3,milliseconds:1,microseconds:.001,nanoseconds:1e-6}[n.epochUnit]??1;xe(e,{epoch:n.epoch,unit:n.epochUnit,iso:new Date(Math.round(n.epoch*o)).toISOString(),utc:n.dateTimeInGMT,local:n.dateTime,timezone:n.timezone,relative:n.relative},()=>{We.info("Epoch → date"),console.table([{Epoch:`${n.epoch} (${n.epochUnit})`,Local:n.dateTime,GMT:n.dateTimeInGMT,Relative:n.relative}])})}function Ze(e,t,n,o){let r,s;try{r=y(t,n,o)}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,t instanceof Error?t.name:"ParseError",n,2)}try{s=x(r.epochInSeconds).relative}catch{s=void 0}xe(e,{epochInSeconds:r.epochInSeconds,epochInMilliseconds:r.epochInMilliseconds,iso:new Date(r.epochInMilliseconds).toISOString(),utc:r.dateTimeInGMT,local:r.dateTime,timezone:r.timezone,relative:s},()=>{We.info("Date → epoch"),console.table([{Seconds:r.epochInSeconds,Milliseconds:r.epochInMilliseconds,Local:r.dateTime,GMT:r.dateTimeInGMT,Timezone:r.timezone}])})}const qe={command:"epoch [value]",describe:"Convert between epoch timestamps and dates (auto-detects unit)",builder:e=>ye(e).positional("value",{describe:"Epoch value to convert to a date (s / ms / µs / ns auto-detected)",type:"string"}).option("from",{type:"string",describe:"A date string to convert TO epoch (ISO 8601 unless --format given)"}).option("format",{type:"string",describe:'Luxon parse format for --from (e.g. "dd/MM/yyyy")'}).option("tz",{type:"string",describe:"IANA timezone used to interpret --from (default: local)"}).example("mfn epoch 1622547800 --json","epoch → date").example("mfn epoch --from 2021-06-01T11:43:20Z --json","date → epoch"),handler:async e=>{if(void 0!==e.from)return Ze(e,String(e.from),e.format,e.tz);if(void 0!==e.value&&null!==e.value){const t=String(e.value).trim();return""===t?we(e,"MissingInput","Epoch value is empty. Provide a numeric epoch.",2):Je(e,Number(t))}if($e(e))return async function(e,t,n){const{default:o}=await import("inquirer"),{operation:r}=await o.prompt([{type:"rawlist",name:"operation",message:ue("What do you want to do?"),choices:[{name:"Convert epoch → human-readable date",value:"epochToDate"},{name:"Convert date string → epoch",value:"dateToEpoch"}]}]);if("epochToDate"===r){const{value:n}=await o.prompt([{type:"input",name:"value",message:ue("Enter epoch value:"),validate:e=>e.trim()&&!isNaN(Number(e))||"Enter a number"}]);t(e,Number(n))}else{const{input:t}=await o.prompt([{type:"input",name:"input",message:ue("Enter a date string (ISO 8601):"),validate:e=>Boolean(e.trim())||"Enter a date string"}]);n(e,t,void 0,e.tz)}}(e,Je,Ze);we(e,"MissingInput","Provide an epoch <value>, or --from <dateString>. See `mfn epoch --help`.",2)}},Ge=ce(),He=w(h),Ye=n.join(de(),"ports.json"),Ve="win32"===$();async function Ke(e){try{if(Ve){const{stdout:t}=await He("netstat",["-ano"]),n=t.split("\n").find(t=>t.includes(`:${e}`)&&/LISTENING/i.test(t)),o=n?n.trim().split(/\s+/).pop():null;return o?{port:e,pid:o}:null}const{stdout:t}=await He("lsof",["-i",`:${e}`]),n=t.split("\n").find(e=>/LISTEN/.test(e)),o=n?n.trim().split(/\s+/)[1]:null;return o?{port:e,pid:o}:null}catch{return null}}async function Qe(e){if(!/^\d+$/.test(e))throw new Error(`Refusing to kill non-numeric PID "${e}"`);if(Number(e)<=1)throw new Error(`Refusing to kill system PID ${e}`);Ve?await He("taskkill",["/PID",e,"/F"]):await He("kill",["-9",e])}const Xe={command:"kill",describe:"Kill the process(es) listening on specific ports",builder:e=>ye(e).option("ports",{alias:"p",describe:"Port number(s) to free",type:"array"}).option("yes",{alias:"y",type:"boolean",default:!1,describe:"Kill all matching processes without the interactive prompt"}).example("mfn kill -p 3000 8080 -y --json","free ports 3000 and 8080"),handler:async e=>{const t=e.ports??[];let n=[];for(const o of t){const t=Number(o);if(!Number.isInteger(t)||t<1||t>65535)return we(e,"InvalidPort",`Invalid port number: ${o} (expected an integer in 1..65535).`,2);n.push(t)}if(0===n.length){const t=$e(e)?await async function(){try{return await f.readJson(Ye)}catch(e){if("ENOENT"===e.code)return{ports:[]};throw e}}():{ports:[]};if(!t.ports?.length)return we(e,"NoPorts","No ports provided. Use -p <port...>. See `mfn kill --help`.",2);n=t.ports,Ge.info(`Using cached ports [${n.join(", ")}]`)}await me({ports:n},Ye).catch(()=>{});const o=(await Promise.all(n.map(Ke))).filter(e=>null!==e),r=n.filter(e=>!o.some(t=>t.port===e));if(0===o.length)return xe(e,{killed:[],failed:[],notFound:r},()=>Ge.info(`No processes listening on [${n.join(", ")}]`));let s=o;if($e(e)&&!e.yes){const{default:e}=await import("inquirer"),{pids:t}=await e.prompt([{type:"checkbox",name:"pids",message:ue("Select the processes to kill:"),choices:o.map(e=>({name:`Port ${e.port} → PID ${e.pid}`,value:e.pid}))}]);s=o.filter(e=>t.includes(e.pid))}const i=[],a=[];for(const e of s)try{await Qe(e.pid),i.push(e)}catch(t){a.push({...e,error:t instanceof Error?t.message:String(t)})}xe(e,{killed:i,failed:a,notFound:r},()=>{for(const e of i)Ge.info(`Killed PID ${e.pid} on port ${e.port}`);for(const e of a)Ge.error(`Failed to kill PID ${e.pid} (port ${e.port}): ${e.error}`);r.length&&Ge.warn(`No process on [${r.join(", ")}]`)}),a.length>0&&process.exit(1)}},et=ce(),tt=w(h);const nt={command:"update [package]",describe:"Update the CLI or a specified package to the latest version",builder:e=>ye(e).positional("package",{describe:"npm package to update globally (default: this CLI)",type:"string",default:"@master4n/master-cli"}).example("mfn update","update master-cli itself to the latest version").example("mfn update typescript --json","update a specific global package"),handler:async e=>{const t=String(e.package??"@master4n/master-cli"),n=$e(e)?(await import("ora")).default():null,o=Date.now();n?.start(d.green(`updating/installing ${t}`));try{await async function(e){await tt("npm",["install","-g",e])}(t);const r=await async function(e){try{const{stdout:t}=await tt("npm",["view",e,"version"]);return t.trim()||null}catch{return null}}(t),s=Date.now()-o;n?.succeed(`${d.green(`updated ${t}`)} ${d.dim(`(${(s/1e3).toFixed(3)}s)`)}`),xe(e,{package:t,version:r,durationMs:s},()=>{et.info(`${t} updated/installed${r?` -> ${d.green(r)}`:""}`)})}catch(o){n?.fail(d.red(`failed updating ${t}`));const r=o instanceof Error?o.message:String(o);we(e,"UpdateFailed",`Failed to update "${t}": ${r}`)}}},ot={command:"capabilities",describe:"List every command an agent can call (self-describing manifest)",builder:e=>ye(e).example("mfn capabilities --json","machine-readable manifest"),handler:e=>{xe(e,{name:re,version:se,bin:"mfn",conventions:{json:"pass --json, or pipe (non-TTY auto-emits) — one {ok,...} object on stdout",exitCodes:{ok:0,error:1,usage:2},logs:"banners and logs go to stderr; stdout carries data only"},docs:{readme:"https://github.com/Master4Novice/master-cli#readme",llmsTxt:"https://raw.githubusercontent.com/Master4Novice/master-cli/master/llms.txt",agentNote:"llms.txt ships inside this npm package too — full agent contract and per-command flags"},categories:oe,commands:ne.map(e=>({name:e.name,category:e.category,summary:e.summary,examples:e.examples}))},()=>{console.log(`${re} v${se} (bin: mfn)`),console.log("Commands an agent can call headlessly:");for(const e of oe){console.log(`\n [${e}]`);for(const t of ne.filter(t=>t.category===e))console.log(` ${t.name.padEnd(14)} ${t.summary}`)}console.log("\nConventions: --json for machine output · exit 0/1/2 · logs on stderr")})}};function rt(e){switch(e){case"uuid":case"uuid4":return S();case"uuid7":return function(){const e=j(16);e.writeUIntBE(Date.now(),0,6),e[6]=15&e[6]|112,e[8]=63&e[8]|128;const t=e.toString("hex");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}();default:return""}}const st=1e5,it={command:"id",describe:"Generate identifiers (UUID v4/v7 or URL-safe nano id)",builder:e=>ye(e).option("type",{alias:"t",describe:"Identifier type",type:"string",choices:["uuid","uuid4","uuid7","nano"],default:"uuid"}).option("count",{alias:"n",describe:"How many to generate",type:"number",default:1}).option("size",{describe:"Length for --type nano",type:"number",default:21}).example("mfn id --json","one UUID v4").example("mfn id -t uuid7 -n 3 --json","three time-ordered UUID v7").example("mfn id -t nano --size 12 --json","a 12-char URL-safe id"),handler:e=>{const t=String(e.type),n=Number(e.count),o=Number(e.size);if(!Number.isInteger(n)||n<1||n>st)return we(e,"InvalidCount","--count must be an integer in 1..100000.",2);if("nano"===t&&(!Number.isInteger(o)||o<1||o>4096))return we(e,"InvalidSize","--size must be an integer in 1..4096.",2);const r=Array.from({length:n},()=>"nano"===t?function(e){let t="";for(;t.length<e;){const n=j(e);for(let o=0;o<n.length&&t.length<e;o++)t+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"[63&n[o]]}return t}(o):rt(t));xe(e,{type:t,count:n,ids:r},()=>r.forEach(e=>console.log(e)))}},at=["md5","sha1","sha256","sha512"],lt={command:"hash [text]",describe:"Hash a string, file, or stdin (md5/sha1/sha256/sha512)",builder:e=>ye(e).positional("text",{describe:"String to hash (or pipe via stdin, or use --file)",type:"string"}).option("algo",{alias:"a",describe:"Hash algorithm",type:"string",choices:at,default:"sha256"}).option("file",{alias:"f",describe:"Hash the contents of this file instead",type:"string"}).option("encoding",{alias:"e",describe:"Digest encoding",type:"string",choices:["hex","base64","base64url"],default:"hex"}).example("mfn hash hello --json",'sha256 of "hello"').example("mfn hash -a md5 -f ./file.txt --json","md5 of a file").example("cat file | mfn hash --json","hash piped stdin"),handler:async e=>{const t=String(e.algo),n=String(e.encoding);let o,r;try{if(void 0!==e.file)o=await E(String(e.file)),r=`file:${e.file}`;else if(void 0!==e.text)o=Buffer.from(String(e.text),"utf8"),r="text";else{const t=await je();if(!t)return we(e,"MissingInput","Provide a string, --file <path>, or pipe stdin.",2);o=Buffer.from(t,"utf8"),r="stdin"}}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}if(!N().includes(t))return we(e,"UnsupportedAlgo",`Algorithm "${t}" is not available.`,2);const s=k(t).update(o).digest(n);xe(e,{algo:t,encoding:n,source:r,bytes:o.length,hash:s},()=>console.log(s))}};const ct={hex:/^[0-9a-fA-F]*$/,base64:/^[A-Za-z0-9+/]*={0,2}$/,base64url:/^[A-Za-z0-9_-]*$/};const dt={command:"encode [text]",describe:"Encode/decode text (base64, base64url, hex, url)",builder:e=>ye(e).positional("text",{describe:"Text to (de/en)code (or pipe via stdin)",type:"string"}).option("as",{alias:"a",describe:"Codec",type:"string",choices:["base64","base64url","hex","url"],default:"base64"}).option("decode",{alias:"d",describe:"Decode instead of encode",type:"boolean",default:!1}).example("mfn encode hello --json",'base64-encode "hello"').example("mfn encode aGVsbG8= -d --json","base64-decode").example('mfn encode "a b&c" --as url --json',"url-encode"),handler:async e=>{const t=String(e.as),n=Boolean(e.decode);let o,r;if(void 0!==e.text)o=String(e.text);else if(o=(await je()).replace(/\n$/,""),!o)return we(e,"MissingInput","Provide text or pipe stdin.",2);try{r=n?function(e,t){if("url"===t)return decodeURIComponent(e);const n=ct[t],o="hex"===t?e:e.trim();if(!n.test(o)||"hex"===t&&o.length%2!=0)throw new Error(`not valid ${t}`);return Buffer.from(o,t).toString("utf8")}(o,t):function(e,t){switch(t){case"base64":return Buffer.from(e,"utf8").toString("base64");case"base64url":return Buffer.from(e,"utf8").toString("base64url");case"hex":return Buffer.from(e,"utf8").toString("hex");case"url":return encodeURIComponent(e)}}(o,t)}catch(o){return we(e,"CodecError",`Could not ${n?"decode":"encode"} as ${t}: ${o instanceof Error?o.message:String(o)}`)}xe(e,{operation:n?"decode":"encode",codec:t,input:o,output:r},()=>console.log(r))}};const ut=1048576,mt={command:"random",describe:"Generate cryptographically secure random bytes or a password",builder:e=>ye(e).option("bytes",{alias:"b",describe:"Number of random bytes",type:"number",default:32}).option("encoding",{alias:"e",describe:"Output encoding for bytes",type:"string",choices:["hex","base64","base64url"],default:"hex"}).option("password",{alias:"p",describe:"Generate a password instead of raw bytes",type:"boolean",default:!1}).option("length",{alias:"l",describe:"Password length",type:"number",default:24}).example("mfn random --json","32 secure random bytes as hex").example("mfn random -b 16 -e base64url --json","16 bytes, base64url").example("mfn random -p -l 32 --json","a 32-char password"),handler:e=>{if(e.password){const t=Number(e.length);if(!Number.isInteger(t)||t<1||t>4096)return we(e,"InvalidLength","--length must be an integer in 1..4096.",2);const n=function(e,t){const n=t.length,o=Math.floor(256/n)*n;let r="";for(;r.length<e;)for(const s of j(2*e))if(s<o&&(r+=t[s%n],r.length===e))break;return r}(t,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*-_=+");return xe(e,{kind:"password",length:t,value:n},()=>console.log(n))}const t=Number(e.bytes);if(!Number.isInteger(t)||t<1||t>ut)return we(e,"InvalidBytes","--bytes must be an integer in 1..1048576.",2);const n=String(e.encoding),o=j(t).toString(n);xe(e,{kind:"bytes",bytes:t,encoding:n,value:o},()=>console.log(o))}};function pt(e,t){return new Promise(n=>{const o=O({port:e,host:t});o.setTimeout(500);const r=e=>{o.destroy(),n(e)};o.once("connect",()=>r(!0)),o.once("timeout",()=>r(!1)),o.once("error",()=>r(!1))})}function ft(){return new Promise((e,t)=>{const n=I();n.unref(),n.on("error",t),n.listen(0,()=>{const t=n.address(),o="object"==typeof t&&t?t.port:0;e({port:o,close:()=>n.close()})})})}const ht={command:"port",describe:"Find a free port, or check whether a specific port is available",builder:e=>ye(e).option("check",{alias:"c",describe:"Check if this specific port is free",type:"number"}).option("count",{alias:"n",describe:"Return this many distinct free ports",type:"number",default:1}).example("mfn port --json","one free port").example("mfn port -n 3 --json","three free ports").example("mfn port -c 3000 --json","is port 3000 free?"),handler:async e=>{if(void 0!==e.check){const t=Number(e.check);if(!Number.isInteger(t)||t<1||t>65535)return we(e,"InvalidPort","--check must be an integer in 1..65535.",2);const n=await async function(e){const[t,n]=await Promise.all([pt(e,"127.0.0.1"),pt(e,"::1")]);return!t&&!n}(t);return xe(e,{port:t,available:n},()=>console.log(`${t} is ${n?"free":"in use"}`))}const t=Number(e.count);if(!Number.isInteger(t)||t<1)return we(e,"InvalidCount","--count must be a positive integer.",2);const n=[];try{for(;n.length<t;){const e=await ft();n.push(e)}}catch(t){n.forEach(e=>e.close());return we(e,"PortError",`Could not allocate a free port: ${t instanceof Error?t.message:String(t)}`)}const o=n.map(e=>e.port);n.forEach(e=>e.close()),xe(e,{count:t,ports:o,port:o[0]},()=>o.forEach(e=>console.log(e)))}},gt=[".ssh",".gnupg",".aws",".kube",".docker",".gcloud",".azure"],yt=[".netrc",".npmrc",".pgpass",".git-credentials","shadow","credentials","otr.private_key"],bt=[/^id_(rsa|dsa|ecdsa|ed25519)(\.|$)/i,/\.(pem|key|p12|pfx|keystore|jks|asc)$/i,/^\.env(\..+)?$/i];function vt(e){const t=A.resolve(e),n=t.split(A.sep).filter(Boolean),o=A.basename(t);return!!n.some(e=>gt.includes(e.toLowerCase()))||(!!yt.includes(o.toLowerCase())||bt.some(e=>e.test(o)))}function xt(e){if(vt(e))return!0;try{const t=T.realpathSync(e);if(t!==A.resolve(e)&&vt(t))return!0}catch{}return!1}const wt=e=>`Refusing to return the contents of "${e}" — it matches a credential/secret location (guardrail, no override; see SECURITY.md).`,$t=[[/-----BEGIN [A-Z ]*PRIVATE KEY-----/,"private key block"],[/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]+/,"JWT"],[/\bAKIA[0-9A-Z]{16}\b/,"AWS access key id"],[/\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/,"GitHub token"],[/\bgithub_pat_[A-Za-z0-9_]{22,}\b/,"GitHub fine-grained token"],[/\bsk-[A-Za-z0-9_-]{20,}\b/,"API secret key (sk-…)"],[/\bxox[abpsr]-[A-Za-z0-9-]{10,}\b/,"Slack token"],[/\bAIza[0-9A-Za-z_-]{35}\b/,"Google API key"],[/\bnpm_[A-Za-z0-9]{36}\b/,"npm token"]];function jt(e){for(const[t,n]of $t)if(t.test(e))return n;return null}function St(e){let t=0,n=e;n=n.replace(/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,()=>(t++,"[redacted: private key block]"));for(const[e,o]of $t)n=n.replace(new RegExp(e,"g"),()=>(t++,`[redacted: ${o}]`));return n=n.split("\n").map(e=>{const n=e.trim();return n.length>=40&&/^[A-Za-z0-9+/_-]+={0,2}$/.test(n)&&!n.includes(" ")?(t++,e.replace(n,"[redacted: key material]")):e}).join("\n"),{text:n,redactedCount:t}}function Nt(e){const t=e.hostname.toLowerCase().replace(/^\[|\]$/g,"");return"metadata.google.internal"===t||"metadata"===t||(!!/^169\.254\.\d{1,3}\.\d{1,3}$/.test(t)||("fd00:ec2::254"===t||"100.100.100.200"===t))}const kt=e=>`Refusing to request "${e}" — cloud metadata endpoints are blocked (credential-theft guardrail, no override; see SECURITY.md).`;const Et={command:"json [query]",describe:"Extract a value from JSON (file or stdin) without reading the whole document",builder:e=>ye(e).positional("query",{describe:"Dot/bracket path, e.g. scripts.build or users[0].name (omit for root)",type:"string"}).option("file",{alias:"f",describe:"Read JSON from this file (default: stdin)",type:"string"}).option("keys",{alias:"k",describe:"List the keys at the path instead of the value",type:"boolean",default:!1}).option("length",{alias:"l",describe:"Report array length / object key count at the path",type:"boolean",default:!1}).example("mfn json scripts.build -f package.json --json","one field from a file").example("cat data.json | mfn json users[0].name --json","one field from stdin").example("mfn json dependencies -f package.json --keys --json","just the keys"),handler:async e=>{let t,n;try{if(void 0!==e.file){if(xt(String(e.file)))return we(e,"SensitivePath",wt(String(e.file)),2);t=await E(String(e.file),"utf8")}else if(t=await je(),!t)return we(e,"MissingInput","Provide --file <path> or pipe JSON via stdin.",2)}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}try{n=JSON.parse(t)}catch(t){return we(e,"InvalidJSON",`Input is not valid JSON: ${t instanceof Error?t.message:String(t)}`)}const o=void 0!==e.query?String(e.query):"",{found:r,value:s}=o?function(e,t){const n=t.replace(/\[(\d+)\]/g,".$1").split(".").filter(e=>""!==e);let o=e;for(const e of n){if(null==o||"object"!=typeof o)return{found:!1,value:void 0};if(!(e in o))return{found:!1,value:void 0};o=o[e]}return{found:!0,value:o}}(n,o):{found:!0,value:n};if(!r)return we(e,"PathNotFound",`No value at path "${o}".`);const i=null===(a=s)?"null":Array.isArray(a)?"array":typeof a;var a;if(e.keys){if("object"!==i&&"array"!==i)return we(e,"NotAnObject",`Path "${o||"."}" is ${i}; --keys needs an object/array.`,2);const t=Object.keys(s);return xe(e,{query:o||null,type:i,count:t.length,keys:t},()=>t.forEach(e=>console.log(e)))}if(e.length){const t="array"===i?s.length:"object"===i?Object.keys(s).length:"string"===i?s.length:null;return null===t?we(e,"NoLength",`Path "${o||"."}" is ${i}; --length needs array/object/string.`,2):xe(e,{query:o||null,type:i,length:t},()=>console.log(t))}const l="string"==typeof s?St(s).text:s;xe(e,{query:o||null,type:i,value:l},()=>console.log("string"==typeof l?l:JSON.stringify(l,null,2)))}},It=e=>Math.ceil(e.length/4),Ot={command:"count [text]",describe:"Count lines/words/chars/bytes + LLM token estimate (file, stdin, or text)",builder:e=>ye(e).positional("text",{describe:"Text to measure (or use --file / pipe stdin)",type:"string"}).option("file",{alias:"f",describe:"Measure the contents of this file",type:"string"}).example("mfn count -f big.log --json","size facts before deciding to read a file").example("git diff | mfn count --json","how big is this diff, in tokens?"),handler:async e=>{let t,n,o;try{if(void 0!==e.file){const r=String(e.file);t=await E(r,"utf8"),o=Buffer.byteLength(t,"utf8"),n=`file:${r}`}else if(void 0!==e.text){const r=String(e.text);try{t=await E(r,"utf8"),n=`file:${r}`}catch{t=r,n="text"}o=Buffer.byteLength(t,"utf8")}else{if(t=await je(),!t)return we(e,"MissingInput","Provide text, --file <path>, or pipe stdin.",2);o=Buffer.byteLength(t,"utf8"),n="stdin"}}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}const r=0===t.length?0:t.split("\n").length-(t.endsWith("\n")?1:0),s=(t.match(/\S+/g)??[]).length,i={source:n,lines:r,words:s,chars:t.length,bytes:o,tokensEstimate:It(t)};xe(e,i,()=>{console.log(`lines ${r} · words ${s} · chars ${t.length} · bytes ${o} · ~${i.tokensEstimate} tokens`)})}},At={command:"lines <file>",describe:"Read an exact line range of a file (1-based, inclusive) — not the whole file",builder:e=>ye(e).positional("file",{describe:"File to read from",type:"string"}).option("start",{alias:"s",describe:"First line (1-based)",type:"number",default:1}).option("end",{alias:"e",describe:"Last line (inclusive; default start+99)",type:"number"}).option("count",{alias:"n",describe:"Number of lines from --start (alternative to --end)",type:"number"}).example("mfn lines src/app.ts -s 120 -n 30 --json","30 lines starting at line 120").example("mfn lines error.log -s 1 -e 50 --json","first 50 lines"),handler:async e=>{const t=Number(e.start);if(!Number.isInteger(t)||t<1)return we(e,"InvalidStart","--start must be a positive integer (1-based).",2);if(void 0!==e.end&&void 0!==e.count)return we(e,"ConflictingFlags","Use --end OR --count, not both.",2);let n;if(void 0!==e.end){if(n=Number(e.end),!Number.isInteger(n)||n<t)return we(e,"InvalidEnd","--end must be an integer >= --start.",2)}else if(void 0!==e.count){const o=Number(e.count);if(!Number.isInteger(o)||o<1)return we(e,"InvalidCount","--count must be a positive integer.",2);n=t+o-1}else n=t+99;if(n-t+1>2e3)return we(e,"RangeTooLarge",`Range spans ${n-t+1} lines; max is 2000.`,2);const o=String(e.file);if(xt(o))return we(e,"SensitivePath",wt(o),2);let r;try{r=await E(o,"utf8")}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}const s=r.split("\n"),i=r.endsWith("\n")?s.length-1:s.length;if(t>i)return we(e,"OutOfRange",`--start ${t} is beyond the file (${i} lines).`,2);const a=Math.min(n,i),l=s.slice(t-1,a).map(e=>St(e).text);xe(e,{file:String(e.file),start:t,end:a,requestedEnd:n,totalLines:i,lineCount:l.length,content:l.join("\n")},()=>l.forEach((e,n)=>console.log(`${t+n}\t${e}`)))}},Tt=w(h),Lt="win32"===m(),Mt=/^[A-Za-z0-9][A-Za-z0-9_.+-]*$/;async function zt(e){try{const{stdout:t,stderr:n}=await Tt(e,["--version"],{timeout:3e3}),o=(t||n).split("\n")[0]?.trim();return o||null}catch{return null}}const Ct={command:"have <tools...>",describe:"Check which tools are installed (path + version) in one call",builder:e=>ye(e).positional("tools",{describe:"Command names to look up, e.g. node git docker",type:"string"}).example("mfn have node git docker --json","availability + versions in one shot").example("mfn have rg jq gh --json","check optional tooling before using it"),handler:async e=>{const t=e.tools.map(String);for(const n of t)if(!Mt.test(n))return we(e,"InvalidToolName",`"${n}" is not a plain command name.`,2);const n=await Promise.all(t.map(async e=>{const t=await async function(e){try{const{stdout:t}=await Tt(Lt?"where":"which",[e]),n=t.split("\n")[0]?.trim();return n||null}catch{return null}}(e);return t?{name:e,found:!0,path:t,version:await zt(e)}:{name:e,found:!1,path:null,version:null}})),o=n.filter(e=>!e.found).map(e=>e.name);xe(e,{count:n.length,allFound:0===o.length,missing:o,tools:n},()=>{for(const e of n)console.log(e.found?`✔ ${e.name} ${e.version??""} (${e.path})`:`✘ ${e.name} not found`)})}},Rt={command:"sys",describe:"One-shot system facts (OS, node, CPU, memory, shell, timezone, paths)",builder:e=>ye(e).example("mfn sys --json","everything an agent usually probes with 5+ separate commands"),handler:e=>{const t=u.cpus(),n={platform:process.platform,arch:process.arch,osRelease:u.release(),osVersion:u.version(),hostname:u.hostname(),node:process.version,cpu:{model:t[0]?.model??"unknown",cores:t.length},memory:{totalBytes:u.totalmem(),freeBytes:u.freemem(),totalGB:Math.round(u.totalmem()/1024**3*10)/10,freeGB:Math.round(u.freemem()/1024**3*10)/10},user:u.userInfo().username,shell:process.env.SHELL||process.env.ComSpec||null,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,locale:Intl.DateTimeFormat().resolvedOptions().locale,homedir:u.homedir(),tmpdir:u.tmpdir(),cwd:process.cwd(),uptimeSeconds:Math.round(u.uptime())};xe(e,n,()=>{console.log(`${n.platform}/${n.arch} · ${n.osVersion}`),console.log(`node ${n.node} · ${n.cpu.cores}× ${n.cpu.model}`),console.log(`memory ${n.memory.freeGB}/${n.memory.totalGB} GB free`),console.log(`user ${n.user} · shell ${n.shell??"?"} · tz ${n.timezone}`),console.log(`cwd ${n.cwd}`)})}},_t=w(h);async function Ft(...e){try{const{stdout:t}=await _t("git",e,{timeout:1e4});return t.trimEnd()}catch{return null}}const Dt={command:"repo",describe:"One-shot git repo summary (branch, dirty counts, ahead/behind, last commits)",builder:e=>ye(e).option("commits",{alias:"n",describe:"How many recent commits to include",type:"number",default:5}).example("mfn repo --json","replaces git status + git log + git branch + git remote"),handler:async e=>{const t=Number(e.commits);if(!Number.isInteger(t)||t<0||t>100)return we(e,"InvalidCount","--commits must be an integer in 0..100.",2);if("true"!==await Ft("rev-parse","--is-inside-work-tree"))return we(e,"NotARepo",`Not inside a git repository: ${process.cwd()}`);const[n,o,r,s,i,a]=await Promise.all([Ft("rev-parse","--show-toplevel"),Ft("rev-parse","--abbrev-ref","HEAD"),Ft("status","--porcelain"),Ft("rev-list","--left-right","--count","@{upstream}...HEAD"),Ft("remote","-v"),t>0?Ft("log",`-${t}`,"--pretty=format:%h%x09%an%x09%ad%x09%s","--date=short"):Promise.resolve("")]),l=(r??"").split("\n").filter(Boolean),c=l.filter(e=>e.startsWith("??")).length,d=l.filter(e=>!e.startsWith("??")&&" "!==e[0]).length,u=l.filter(e=>!e.startsWith("??")&&" "!==e[1]).length;let m=null,p=null;if(s){const[e,t]=s.split("\t").map(Number);p=Number.isFinite(e)?e:null,m=Number.isFinite(t)?t:null}const f=Array.from(new Map((i??"").split("\n").filter(Boolean).map(e=>{const[t,n]=e.split(/\s+/);return[t,{name:t,url:n}]})).values()),h=(a??"").split("\n").filter(Boolean).map(e=>{const[t,n,o,...r]=e.split("\t");return{hash:t,author:n,date:o,subject:r.join("\t")}}),g=0===l.length;xe(e,{root:n,branch:o,clean:g,staged:d,unstaged:u,untracked:c,ahead:m,behind:p,hasUpstream:null!==s,remotes:f,commits:h},()=>{console.log(`${n} (${o})`),console.log(g?"clean":`staged ${d} · unstaged ${u} · untracked ${c}`),null!==m&&console.log(`ahead ${m} · behind ${p}`);for(const e of h)console.log(`${e.hash} ${e.date} ${e.subject}`)})}};class Bt{s;i=0;constructor(e){this.s=e}parse(){const e=this.expr();if(this.skipWs(),this.i<this.s.length)throw new Error(`Unexpected "${this.s[this.i]}" at position ${this.i}`);return e}skipWs(){for(;" "===this.s[this.i];)this.i++}peek(){return this.skipWs(),this.s[this.i]??""}expr(){let e=this.term();for(let t=this.peek();"+"===t||"-"===t;t=this.peek())this.i++,e=Pt(e,this.term(),t);return e}term(){let e=this.factor();for(let t=this.peek();"*"===t||"/"===t||"%"===t;t=this.peek())this.i++,e=Pt(e,this.factor(),t);return e}factor(){const e=this.unary();return"^"===this.peek()?(this.i++,Pt(e,this.factor(),"^")):e}unary(){if("-"===this.peek()){this.i++;const e=this.unary();return{big:null===e.big?null:-e.big,float:-e.float}}return this.atom()}atom(){if("("===this.peek()){this.i++;const e=this.expr();if(")"!==this.peek())throw new Error("Missing closing parenthesis");return this.i++,e}this.skipWs();const e=/^\d+(\.\d+)?([eE][+-]?\d+)?/.exec(this.s.slice(this.i));if(!e)throw new Error(`Expected a number at position ${this.i}`);this.i+=e[0].length;return{big:!e[1]&&!e[2]?BigInt(e[0]):null,float:Number(e[0])}}}function Pt(e,t,n){const o="+"===n?e.float+t.float:"-"===n?e.float-t.float:"*"===n?e.float*t.float:"/"===n?e.float/t.float:"%"===n?e.float%t.float:Math.pow(e.float,t.float);if("/"===n&&0===t.float)throw new Error("Division by zero");if(null===e.big||null===t.big||"/"===n)return{big:null,float:o};if("^"===n){if(t.big<0n)return{big:null,float:o};if(t.big>4096n)throw new Error("Exponent too large (max 4096)");return{big:e.big**t.big,float:o}}if("%"===n&&0n===t.big)throw new Error("Modulo by zero");return{big:"+"===n?e.big+t.big:"-"===n?e.big-t.big:"*"===n?e.big*t.big:e.big%t.big,float:o}}const Ut={command:"calc <expression>",describe:"Exact arithmetic (+ - * / % ^, parens; integers use BigInt — no float drift)",builder:e=>ye(e).positional("expression",{describe:'Expression, e.g. "2^64 - 1" or "(3 + 4) * 5"',type:"string"}).example('mfn calc "2^53 + 1" --json',"exact: 9007199254740993 (floats get this wrong)").example('mfn calc "1729 * 4096 % 7" --json',"integer arithmetic stays exact"),handler:e=>{const t=String(e.expression).trim();if(!t)return we(e,"MissingInput","Provide an arithmetic expression.",2);if(t.length>1e3)return we(e,"ExpressionTooLong","Expression exceeds 1000 characters.",2);let n;try{n=new Bt(t).parse()}catch(n){return we(e,"ParseError",`Could not evaluate "${t}": ${n instanceof Error?n.message:String(n)}`,2)}const o=null!==n.big,r=o?n.big.toString():String(n.float);xe(e,{expression:t,result:r,exact:o,float:n.float},()=>console.log(r))}},Wt=/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;function Jt(e){const t=Wt.exec(e.trim());return t?{raw:e.trim(),major:Number(t[1]),minor:Number(t[2]),patch:Number(t[3]),prerelease:t[4]?t[4].split("."):[],build:t[5]??null}:null}function Zt(e,t){for(const n of["major","minor","patch"])if(e[n]!==t[n])return e[n]<t[n]?-1:1;if(0===e.prerelease.length&&0===t.prerelease.length)return 0;if(0===e.prerelease.length)return 1;if(0===t.prerelease.length)return-1;const n=Math.max(e.prerelease.length,t.prerelease.length);for(let o=0;o<n;o++){const n=e.prerelease[o],r=t.prerelease[o];if(void 0===n)return-1;if(void 0===r)return 1;const s=/^\d+$/.test(n),i=/^\d+$/.test(r);if(s&&i){if(Number(n)!==Number(r))return Number(n)<Number(r)?-1:1}else{if(s!==i)return s?-1:1;if(n!==r)return n<r?-1:1}}return 0}const qt={command:"semver <versions...>",describe:"Validate, compare, sort, or bump semantic versions (exact, per semver.org)",builder:e=>ye(e).positional("versions",{describe:"One or more versions",type:"string"}).option("bump",{alias:"b",describe:"Bump the (single) version",type:"string",choices:["major","minor","patch"]}).option("sort",{alias:"s",describe:"Sort all given versions ascending",type:"boolean",default:!1}).example("mfn semver 1.2.3 --json","validate + parse one version").example("mfn semver 1.10.0 1.9.2 --json","compare two (1.10.0 > 1.9.2 — string sort lies)").example("mfn semver 2.0.0-rc.1 2.0.0 --sort --json","prerelease ordering done right").example("mfn semver 1.2.3 -b minor --json","bump → 1.3.0"),handler:e=>{const t=e.versions.map(String),n=[];for(const o of t){const t=Jt(o);if(!t)return we(e,"InvalidVersion",`"${o}" is not a valid semantic version.`,2);n.push(t)}if(e.bump){if(1!==n.length)return we(e,"TooManyVersions","--bump takes exactly one version.",2);const t=function(e,t){return"major"===t?`${e.major+1}.0.0`:"minor"===t?`${e.major}.${e.minor+1}.0`:`${e.major}.${e.minor}.${e.patch+1}`}(n[0],String(e.bump));return xe(e,{input:n[0].raw,bump:e.bump,result:t},()=>console.log(t))}if(e.sort||n.length>2){const t=[...n].sort(Zt).map(e=>e.raw);return xe(e,{count:t.length,sorted:t,latest:t[t.length-1]},()=>t.forEach(e=>console.log(e)))}if(2===n.length){const t=Zt(n[0],n[1]);return xe(e,{a:n[0].raw,b:n[1].raw,comparison:t,relation:0===t?"equal":t<0?"a < b":"a > b",greater:t>=0?n[0].raw:n[1].raw},()=>console.log(0===t?"equal":t<0?`${n[1].raw} is greater`:`${n[0].raw} is greater`))}const o=n[0];xe(e,{version:o.raw,valid:!0,major:o.major,minor:o.minor,patch:o.patch,prerelease:o.prerelease.length?o.prerelease.join("."):null,build:o.build,isPrerelease:o.prerelease.length>0},()=>console.log(`${o.major}.${o.minor}.${o.patch} valid`))}};const Gt=e=>e.charAt(0).toUpperCase()+e.slice(1),Ht={camel:e=>e.map((e,t)=>0===t?e:Gt(e)).join(""),pascal:e=>e.map(Gt).join(""),snake:e=>e.join("_"),kebab:e=>e.join("-"),constant:e=>e.join("_").toUpperCase(),dot:e=>e.join("."),path:e=>e.join("/"),title:e=>e.map(Gt).join(" "),sentence:e=>Gt(e.join(" ")),lower:e=>e.join(" "),upper:e=>e.join(" ").toUpperCase()},Yt=Object.keys(Ht),Vt=1e5,Kt={command:"case [text]",describe:"Convert a string between naming styles (camel, snake, kebab, pascal, …)",builder:e=>ye(e).positional("text",{describe:"Text to convert (or pipe via stdin)",type:"string"}).option("to",{alias:"t",describe:"Target style (omit for all styles at once)",type:"string",choices:Yt}).example('mfn case "user profile id" -t camel --json',"→ userProfileId").example("mfn case getUserName -t snake --json","→ get_user_name").example("mfn case my-component --json","all styles in one call"),handler:async e=>{let t;if(void 0!==e.text)t=String(e.text);else if(t=(await je()).replace(/\n$/,""),!t)return we(e,"MissingInput","Provide text or pipe stdin.",2);if(t.length>Vt)return we(e,"InputTooLarge","Input exceeds 100000 characters.",2);const n=function(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").split(/[\s_\-./]+/).filter(Boolean).map(e=>e.toLowerCase())}(t);if(0===n.length)return we(e,"NoWords","Input contains no convertible words.",2);if(e.to){const o=String(e.to),r=Ht[o](n);return xe(e,{input:t,style:o,output:r},()=>console.log(r))}const o=Object.fromEntries(Yt.map(e=>[e,Ht[e](n)]));xe(e,{input:t,words:n,styles:o},()=>{for(const[e,t]of Object.entries(o))console.log(`${e.padEnd(9)} ${t}`)})}},Qt=[[0,59],[0,23],[1,31],[1,12],[0,6]],Xt="JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC".split(" "),en="SUN MON TUE WED THU FRI SAT".split(" ");function tn(e,t){const n=e.toUpperCase();if(3===t){const e=Xt.indexOf(n);if(e>=0)return String(e+1)}if(4===t){const e=en.indexOf(n);if(e>=0)return String(e)}return e}function nn(e,t){const[n,o]=Qt[t],r=new Set;for(const s of e.split(",")){const[e,i]=s.split("/"),a=void 0===i?1:Number(i);if(!Number.isInteger(a)||a<1)throw new Error(`Invalid step "${i}" in "${s}"`);let l,c;if("*"===e||""===e)l=n,c=o;else if(e.includes("-")){const[n,o]=e.split("-").map(e=>Number(tn(e,t)));l=n,c=o}else l=c=Number(tn(e,t)),void 0!==i&&(c=o);if(!Number.isInteger(l)||!Number.isInteger(c))throw new Error(`Invalid value in "${s}"`);if(4===t&&(7===l&&(l=0),7===c&&(c=0)),l<n||c>o||l>c)throw new Error(`"${s}" out of range ${n}-${o}`);for(let e=l;e<=c;e+=a)r.add(e)}return r}const on={"@yearly":"0 0 1 1 *","@annually":"0 0 1 1 *","@monthly":"0 0 1 * *","@weekly":"0 0 * * 0","@daily":"0 0 * * *","@midnight":"0 0 * * *","@hourly":"0 * * * *"};function rn(e,t){if(!e.month.has(t.getMonth()+1))return!1;const n=e.dayOfMonth.has(t.getDate()),o=e.dayOfWeek.has(t.getDay());return e.domRestricted&&e.dowRestricted?n||o:n&&o}const sn={command:"cron <expression>",describe:"Validate a cron expression, explain it, and compute the next run times",builder:e=>ye(e).positional("expression",{describe:"5-field cron (minute hour dom month dow) or @daily/@hourly/@weekly/…",type:"string"}).option("next",{alias:"n",describe:"How many upcoming run times to compute",type:"number",default:3}).example('mfn cron "*/15 9-17 * * 1-5" --json',"validate + explain + next runs").example('mfn cron "@daily" -n 1 --json',"when does @daily fire next?"),handler:e=>{const t=String(e.expression).trim(),n=Number(e.next);if(!Number.isInteger(n)||n<0||n>100)return we(e,"InvalidCount","--next must be an integer in 0..100.",2);let o;try{o=function(e){const t=(on[e.trim().toLowerCase()]??e.trim()).split(/\s+/);if(5!==t.length)throw new Error(`Expected 5 fields (minute hour dom month dow), got ${t.length}`);return{minute:nn(t[0],0),hour:nn(t[1],1),dayOfMonth:nn(t[2],2),month:nn(t[3],3),dayOfWeek:nn(t[4],4),domRestricted:"*"!==t[2],dowRestricted:"*"!==t[4]}}(t)}catch(n){const o=n instanceof Error?n.message:String(n);return we(e,"InvalidCron",`"${t}" is not valid cron: ${o}`,2)}const r=function(e,t,n){const o=[],r=new Date(t);r.setSeconds(0,0),r.setMinutes(r.getMinutes()+1);const s=new Date(t);for(s.setFullYear(s.getFullYear()+5);o.length<n&&r<=s;)rn(e,r)?e.hour.has(r.getHours())?e.minute.has(r.getMinutes())?(o.push(new Date(r)),r.setMinutes(r.getMinutes()+1)):r.setMinutes(r.getMinutes()+1):(r.setMinutes(0),r.setHours(r.getHours()+1)):(r.setHours(0,0,0,0),r.setDate(r.getDate()+1));return o}(o,new Date,n),s=function(e){const t=(e,t)=>e.size>t?"several values":[...e].sort((e,t)=>e-t).join(","),n=60===e.minute.size?"every minute":1===e.minute.size?`at minute ${t(e.minute,5)}`:`at minutes ${t(e.minute,8)}`,o=24===e.hour.size?"of every hour":1===e.hour.size?`past hour ${t(e.hour,5)}`:`past hours ${t(e.hour,8)}`,r=e.domRestricted?`on day-of-month ${t(e.dayOfMonth,8)}`:"",s=12===e.month.size?"":`in month ${t(e.month,6)}`,i=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];return[n,o,r,s,e.dowRestricted?`on ${[...e.dayOfWeek].sort((e,t)=>e-t).map(e=>i[e]).join(",")}`:""].filter(Boolean).join(" ")}(o),i=e=>{const t=(e,t=2)=>String(e).padStart(t,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:00`};xe(e,{expression:t,valid:!0,description:s,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,next:r.map(e=>({local:i(e),iso:e.toISOString(),epochMs:e.getTime()}))},()=>{console.log(`${t} → ${s}`);for(const e of r)console.log(i(e))})}};const an=2e4,ln={command:"diff <fileA> <fileB>",describe:"Line diff of two files as structured hunks (summary first, not a wall of text)",builder:e=>ye(e).positional("fileA",{describe:"Old file",type:"string"}).positional("fileB",{describe:"New file",type:"string"}).option("summary",{alias:"s",describe:"Only counts + hunk locations (no line content)",type:"boolean",default:!1}).example("mfn diff old.json new.json --json","structured hunks").example("mfn diff a.txt b.txt -s --json","just how much changed, and where"),handler:async e=>{for(const t of[e.fileA,e.fileB])if(xt(String(t)))return we(e,"SensitivePath",wt(String(t)),2);let t,n;try{[t,n]=await Promise.all([E(String(e.fileA),"utf8"),E(String(e.fileB),"utf8")])}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,"ReadError",n)}const o=t.split("\n"),r=n.split("\n");if(o.length>an||r.length>an)return we(e,"FileTooLarge","diff is capped at 20000 lines per file.",2);const s=t===n,i=s?[]:function(e,t){const n=e.length,o=t.length,r=Array.from({length:n+1},()=>new Array(o+1).fill(0));for(let s=n-1;s>=0;s--)for(let n=o-1;n>=0;n--)r[s][n]=e[s]===t[n]?r[s+1][n+1]+1:Math.max(r[s+1][n],r[s][n+1]);const s=[];let i=0,a=0;for(;i<n||a<o;){if(i<n&&a<o&&e[i]===t[a]){i++,a++;continue}const l={aStart:i+1,aLines:0,bStart:a+1,bLines:0,removed:[],added:[]};for(;i<n&&(a>=o||r[i+1][a]>=r[i][a+1])&&(l.removed.push(e[i++]),l.aLines++,!(i<n&&a<o&&e[i]===t[a])););for(;a<o&&(i>=n||r[i+1][a]<r[i][a+1]||void 0===e[i]||e[i]!==t[a])&&!(i<n&&e[i]===t[a]);)l.added.push(t[a++]),l.bLines++;s.push(l)}return s}(o,r),a=i.reduce((e,t)=>e+t.removed.length,0),l=i.reduce((e,t)=>e+t.added.length,0),c=i.map(t=>e.summary?{aStart:t.aStart,aLines:t.aLines,bStart:t.bStart,bLines:t.bLines}:t);xe(e,{fileA:String(e.fileA),fileB:String(e.fileB),identical:s,hunkCount:i.length,linesAdded:l,linesRemoved:a,hunks:c},()=>{if(s)return console.log("files are identical");console.log(`${i.length} hunk(s) · +${l} −${a}`);for(const t of i)console.log(`@@ -${t.aStart},${t.aLines} +${t.bStart},${t.bLines} @@`),e.summary||(t.removed.forEach(e=>console.log(`- ${e}`)),t.added.forEach(e=>console.log(`+ ${e}`)))})}},cn=/(key|token|secret|password|passwd|credential|auth|cookie|session|private|api)/i,dn=e=>e.length<=8?"••••":`${e.slice(0,3)}…${e.slice(-2)} (${e.length} chars, redacted)`,un=(e,t)=>cn.test(e)||null!==jt(t),mn={command:"env [names...]",describe:"Inspect environment variables with automatic secret redaction",builder:e=>ye(e).positional("names",{describe:"Variable names to read (omit to list all names)",type:"string"}).option("prefix",{alias:"p",describe:"Only variables starting with this prefix",type:"string"}).example("mfn env NODE_ENV PATH --json","specific variables (secrets auto-redacted)").example("mfn env -p NEXT_PUBLIC_ --json","all NEXT_PUBLIC_* variables").example("mfn env --json","just the names — values omitted"),handler:e=>{const t=(e.names??[]).map(String),n=void 0!==e.prefix?String(e.prefix):null;if(t.length>0){const n=t.map(e=>{const t=process.env[e];if(void 0===t)return{name:e,set:!1,value:null,redacted:!1};const n=un(e,t);return{name:e,set:!0,value:n?dn(t):t,redacted:n}}),o=n.filter(e=>!e.set).map(e=>e.name);return xe(e,{count:n.length,missing:o,vars:n},()=>{for(const e of n)console.log(e.set?`${e.name}=${e.value}`:`${e.name} (not set)`)})}const o=Object.keys(process.env).filter(e=>!n||e.startsWith(n)).sort();if(n){const t=o.map(e=>{const t=process.env[e]??"",n=un(e,t);return{name:e,set:!0,value:n?dn(t):t,redacted:n}});return xe(e,{prefix:n,count:t.length,vars:t},()=>{for(const e of t)console.log(`${e.name}=${e.value}`)})}if(0===o.length)return we(e,"NoMatch","No environment variables found.");xe(e,{count:o.length,names:o},()=>o.forEach(e=>console.log(e)))}},pn=new Set(["node_modules",".git",".nx","dist","build","coverage"]);const fn=e=>e>=1024**3?`${(e/1024**3).toFixed(1)}G`:e>=1048576?`${(e/1048576).toFixed(1)}M`:e>=1024?`${(e/1024).toFixed(1)}K`:`${e}B`,hn={command:"size [dir]",describe:"Total size + largest files/dirs under a directory (one call, not du|sort|head)",builder:e=>ye(e).positional("dir",{describe:"Directory to analyse (default: cwd)",type:"string"}).option("top",{alias:"t",describe:"How many largest files/dirs to list",type:"number",default:10}).option("ignore",{alias:"i",describe:"Additional directory names to ignore",type:"array"}).example("mfn size --json","where is the disk going in this project?").example("mfn size ./src -t 5 --json","five largest files under src"),handler:e=>{const t=Number(e.top);if(!Number.isInteger(t)||t<1||t>1e3)return we(e,"InvalidTop","--top must be an integer in 1..1000.",2);const n=A.resolve(String(e.dir??process.cwd()));let o;try{o=T.statSync(n)}catch{return we(e,"NotFound",`Directory not found: ${n}`,2)}if(!o.isDirectory())return we(e,"NotADirectory",`${n} is not a directory.`,2);const{files:r,truncated:s}=function(e,t){const n=new Set([...pn,...t]),o=[];let r=!1;const s=t=>{if(o.length>=2e5)return void(r=!0);let i;try{i=T.readdirSync(t,{withFileTypes:!0})}catch{return}for(const r of i){if(n.has(r.name))continue;const i=A.join(t,r.name);if(r.isDirectory())s(i);else if(r.isFile())try{o.push({path:A.relative(e,i),bytes:T.statSync(i).size})}catch{}}};return s(e),{files:o,truncated:r}}(n,(e.ignore??[]).map(String)),i=r.reduce((e,t)=>e+t.bytes,0),a=new Map;for(const e of r){const t=e.path.split(A.sep)[0];a.set(t,(a.get(t)??0)+e.bytes)}const l=[...a.entries()].sort((e,t)=>t[1]-e[1]).slice(0,t).map(([e,t])=>({name:e,bytes:t,human:fn(t)})),c=[...r].sort((e,t)=>t.bytes-e.bytes).slice(0,t).map(e=>({path:e.path,bytes:e.bytes,human:fn(e.bytes)}));xe(e,{root:n,fileCount:r.length,totalBytes:i,totalHuman:fn(i),truncated:s,largestFiles:c,byTopLevel:l},()=>{console.log(`${n}: ${fn(i)} across ${r.length} files`);for(const e of l)console.log(` ${e.human.padStart(8)} ${e.name}/`);console.log("largest files:");for(const e of c)console.log(` ${e.human.padStart(8)} ${e.path}`)})}},gn=new Set(["node_modules",".git",".nx","dist","build","coverage"]);const yn={command:"ext [dir]",describe:'File counts and bytes per extension — "what kind of project is this?" in one call',builder:e=>ye(e).positional("dir",{describe:"Directory to analyse (default: cwd)",type:"string"}).option("ignore",{alias:"i",describe:"Additional directory names to ignore",type:"array"}).example("mfn ext --json","project composition by file type"),handler:e=>{const t=A.resolve(String(e.dir??process.cwd()));let n;try{n=T.statSync(t)}catch{return we(e,"NotFound",`Directory not found: ${t}`,2)}if(!n.isDirectory())return we(e,"NotADirectory",`${t} is not a directory.`,2);const{byExt:o,total:r,truncated:s}=function(e,t){const n=new Set([...gn,...t]),o=new Map;let r=0,s=!1;const i=e=>{if(r>=2e5)return void(s=!0);let t;try{t=T.readdirSync(e,{withFileTypes:!0})}catch{return}for(const s of t){if(n.has(s.name))continue;const t=A.join(e,s.name);if(s.isDirectory())i(t);else if(s.isFile()){const e=A.extname(s.name).toLowerCase()||"(none)";let n=0;try{n=T.statSync(t).size}catch{}const i=o.get(e)??{count:0,bytes:0};i.count++,i.bytes+=n,o.set(e,i),r++}}};return i(e),{byExt:o,total:r,truncated:s}}(t,(e.ignore??[]).map(String)),i=[...o.entries()].sort((e,t)=>t[1].count-e[1].count).map(([e,t])=>({ext:e,count:t.count,bytes:t.bytes}));xe(e,{root:t,fileCount:r,truncated:s,extensions:i},()=>{console.log(`${r} files under ${t}`);for(const e of i.slice(0,20))console.log(` ${String(e.count).padStart(6)} ${e.ext}`)})}},bn={command:"freq [file]",describe:"Most frequent lines of a file/stdin (log analysis without sort|uniq -c|sort|head)",builder:e=>ye(e).positional("file",{describe:"File to analyse (or pipe via stdin)",type:"string"}).option("top",{alias:"t",describe:"How many entries to return",type:"number",default:10}).option("min",{alias:"m",describe:"Only lines occurring at least this often",type:"number",default:1}).option("trim",{describe:"Trim whitespace before counting (default true)",type:"boolean",default:!0}).example("mfn freq error.log -t 5 --json","the 5 most repeated log lines").example("grep ERROR app.log | mfn freq --json","most frequent error messages"),handler:async e=>{const t=Number(e.top),n=Number(e.min);if(!Number.isInteger(t)||t<1||t>1e4)return we(e,"InvalidTop","--top must be an integer in 1..10000.",2);if(!Number.isInteger(n)||n<1)return we(e,"InvalidMin","--min must be a positive integer.",2);let o,r;try{if(void 0!==e.file){if(xt(String(e.file)))return we(e,"SensitivePath",wt(String(e.file)),2);o=await E(String(e.file),"utf8"),r=`file:${e.file}`}else{if(o=await je(),!o)return we(e,"MissingInput","Provide a file or pipe stdin.",2);r="stdin"}}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}const s=new Map;let i=0;for(const t of o.split("\n")){const n=e.trim?t.trim():t;""!==n&&(i++,s.set(n,(s.get(n)??0)+1))}const a=[...s.entries()].filter(([,e])=>e>=n).sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).slice(0,t).map(([e,t])=>({count:t,line:St(e).text}));xe(e,{source:r,totalLines:i,uniqueLines:s.size,returned:a.length,entries:a},()=>{for(const e of a)console.log(`${String(e.count).padStart(7)} ${e.line}`)})}},vn={command:"regex <pattern> [text]",describe:"Test a regular expression against text — verify instead of guessing",builder:e=>ye(e).positional("pattern",{describe:"Regular expression (without surrounding slashes)",type:"string"}).positional("text",{describe:"Text to test (or --file / stdin)",type:"string"}).option("file",{alias:"f",describe:"Test against the contents of this file",type:"string"}).option("flags",{describe:"Regex flags (g is always added)",type:"string",default:""}).example('mfn regex "^v\\\\d+\\\\.\\\\d+" "v1.22.0" --json',"does it match?").example('mfn regex "TODO[:!]?" -f src/app.ts --json',"all matches with positions and groups"),handler:async e=>{const t=String(e.pattern);if(t.length>1e3)return we(e,"PatternTooLong","Pattern exceeds 1000 characters.",2);const n=String(e.flags??"");if(!/^[imsuvy]*$/.test(n))return we(e,"InvalidFlags","Flags may only contain i m s u v y (g is implicit).",2);let o,r,s;try{o=new RegExp(t,n.includes("g")?n:n+"g")}catch(t){return we(e,"InvalidRegex",t instanceof Error?t.message:String(t),2)}try{if(void 0!==e.file){if(xt(String(e.file)))return we(e,"SensitivePath",wt(String(e.file)),2);r=await E(String(e.file),"utf8"),s=`file:${e.file}`}else if(void 0!==e.text)r=String(e.text),s="text";else{if(r=await je(),!r)return we(e,"MissingInput","Provide text, --file <path>, or pipe stdin.",2);s="stdin"}}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}const i=[];let a=!1;for(const e of r.matchAll(o)){if(i.length>=1e3){a=!0;break}const t=r.slice(0,e.index).split("\n").length;if(i.push({match:St(e[0]).text,index:e.index,line:t,groups:e.slice(1).map(e=>void 0===e?e:St(e).text)}),""===e[0])break}xe(e,{pattern:t,flags:o.flags,source:s,matched:i.length>0,count:i.length,truncated:a,matches:i},()=>{if(0===i.length)return console.log("no match");for(const e of i)console.log(`line ${e.line} @${e.index}: ${e.match}`)})}},xn={command:"url <value>",describe:"Parse a URL into components with decoded query parameters",builder:e=>ye(e).positional("value",{describe:"URL to parse",type:"string"}).example('mfn url "https://api.x.com/v2/users?id=42&fields=name,bio" --json',"all components at once"),handler:e=>{const t=String(e.value);let n;try{n=new URL(t)}catch{return we(e,"InvalidURL",`"${t}" is not a valid absolute URL (include the scheme).`,2)}const o={};for(const[e,t]of n.searchParams){const n=o[e];void 0===n?o[e]=t:Array.isArray(n)?n.push(t):o[e]=[n,t]}const r={href:n.href,protocol:n.protocol.replace(/:$/,""),username:n.username||null,host:n.host,hostname:n.hostname,port:n.port?Number(n.port):null,path:n.pathname,pathSegments:n.pathname.split("/").filter(Boolean),query:o,queryCount:[...n.searchParams.keys()].length,hash:n.hash?n.hash.slice(1):null,origin:n.origin};xe(e,r,()=>{console.log(`${r.protocol}://${r.host}${r.path}`);for(const[e,t]of Object.entries(o))console.log(` ?${e} = ${JSON.stringify(t)}`);r.hash&&console.log(` #${r.hash}`)})}},wn={command:"ip",describe:"Local network interfaces and addresses (no network calls, no ifconfig parsing)",builder:e=>ye(e).option("all",{alias:"a",describe:"Include internal/loopback interfaces",type:"boolean",default:!1}).example("mfn ip --json","external-facing local addresses").example("mfn ip -a --json","every interface including loopback"),handler:e=>{const t=u.networkInterfaces(),n=Object.entries(t).map(([t,n])=>({name:t,addresses:(n??[]).filter(t=>e.all||!t.internal).map(e=>({address:e.address,family:e.family,internal:e.internal,mac:e.mac,cidr:e.cidr}))})).filter(e=>e.addresses.length>0),o=n.flatMap(e=>e.addresses).find(e=>"IPv4"===e.family&&!e.internal)?.address??null;xe(e,{primaryIPv4:o,count:n.length,interfaces:n},()=>{o&&console.log(`primary IPv4: ${o}`);for(const e of n)for(const t of e.addresses)console.log(`${e.name.padEnd(10)} ${t.family.padEnd(5)} ${t.address}`)})}},$n={shell:e=>`'${e.replace(/'/g,"'\\''")}'`,json:e=>JSON.stringify(e),regex:e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),html:e=>e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"),url:e=>encodeURIComponent(e),string:e=>JSON.stringify(e).slice(1,-1)},jn=Object.keys($n),Sn=1e6,Nn={command:"escape [text]",describe:"Escape text exactly for shell, JSON, regex, HTML, or URL contexts",builder:e=>ye(e).positional("text",{describe:"Text to escape (or pipe via stdin)",type:"string"}).option("as",{alias:"a",describe:"Target context",type:"string",choices:jn,default:"shell"}).example('mfn escape "it\'s done" --json',"safe single-quoted shell string").example('mfn escape "1.2.3" -a regex --json',"regex-literal: 1\\.2\\.3").example("mfn escape 'line1\nline2' -a json --json","paste-ready JSON string"),handler:async e=>{let t;if(void 0!==e.text)t=String(e.text);else if(t=(await je()).replace(/\n$/,""),!t)return we(e,"MissingInput","Provide text or pipe stdin.",2);if(t.length>Sn)return we(e,"InputTooLarge","Input exceeds 1000000 characters.",2);const n=String(e.as),o=$n[n](t);xe(e,{mode:n,input:t,output:o},()=>console.log(o))}};function kn(e,t,n){if(n.size>=500)return;const o=null===(r=e)?"null":Array.isArray(r)?"array":typeof r;var r;const s=""===t?".":t;if(n.has(s)||n.set(s,new Set),n.get(s).add(o),"object"===o)for(const[o,r]of Object.entries(e))kn(r,""===t?o:`${t}.${o}`,n);else if("array"===o){const o=e;n.get(s).delete("array"),n.get(s).add(`array(${o.length})`);for(const e of o.slice(0,50))kn(e,`${t}[]`,n)}}const En={command:"schema [query]",describe:"Infer the shape of a JSON document (paths + types) without dumping the data",builder:e=>ye(e).positional("query",{describe:"Optional dot-path to start from (see `mfn json`)",type:"string"}).option("file",{alias:"f",describe:"Read JSON from this file (default: stdin)",type:"string"}).example("mfn schema -f response.json --json","shape of a big API payload, not its content").example("curl -s api/users | mfn schema --json","what fields does this API return?"),handler:async e=>{let t,n;try{if(void 0!==e.file){if(xt(String(e.file)))return we(e,"SensitivePath",wt(String(e.file)),2);t=await E(String(e.file),"utf8")}else if(t=await je(),!t)return we(e,"MissingInput","Provide --file <path> or pipe JSON via stdin.",2)}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}try{n=JSON.parse(t)}catch(t){return we(e,"InvalidJSON",`Input is not valid JSON: ${t instanceof Error?t.message:String(t)}`)}if(e.query){const t=String(e.query).replace(/\[(\d+)\]/g,".$1").split(".").filter(Boolean);for(const o of t){if(null===n||"object"!=typeof n||!(o in n))return we(e,"PathNotFound",`No value at path "${e.query}".`);n=n[o]}}const o=new Map;kn(n,"",o);const r=[...o.entries()].map(([e,t])=>({path:e,type:[...t].sort().join(" | ")}));xe(e,{source:e.file?`file:${e.file}`:"stdin",bytes:t.length,pathCount:r.length,truncated:o.size>=500,paths:r},()=>{for(const e of r)console.log(`${e.path.padEnd(40)} ${e.type}`)})}},In=[{kind:"function",re:/^(?<exp>export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s*(?<name>[A-Za-z_$][\w$]*)/},{kind:"class",re:/^(?<exp>export\s+)?(?:default\s+)?(?:abstract\s+)?class\s+(?<name>[A-Za-z_$][\w$]*)/},{kind:"interface",re:/^(?<exp>export\s+)?interface\s+(?<name>[A-Za-z_$][\w$]*)/},{kind:"type",re:/^(?<exp>export\s+)?type\s+(?<name>[A-Za-z_$][\w$]*)\s*=/},{kind:"enum",re:/^(?<exp>export\s+)?(?:const\s+)?enum\s+(?<name>[A-Za-z_$][\w$]*)/},{kind:"const",re:/^(?<exp>export\s+)?const\s+(?<name>[A-Za-z_$][\w$]*)\s*(?::[^=]+)?=\s*(?:async\s*)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*(?::[^=]+)?=>/},{kind:"variable",re:/^(?<exp>export\s+)(?:const|let|var)\s+(?<name>[A-Za-z_$][\w$]*)/}],On=[{kind:"function",re:/^(?:async\s+)?def\s+(?<name>[A-Za-z_][\w]*)/},{kind:"class",re:/^class\s+(?<name>[A-Za-z_][\w]*)/}],An=[{kind:"heading",re:/^(?<name>#{1,6}\s+.+)$/}],Tn={".ts":In,".tsx":In,".js":In,".jsx":In,".mjs":In,".cjs":In,".py":On,".go":[{kind:"function",re:/^func\s+(?:\([^)]+\)\s+)?(?<name>[A-Za-z_][\w]*)/},{kind:"type",re:/^type\s+(?<name>[A-Za-z_][\w]*)/}],".md":An,".markdown":An},Ln=Object.keys(Tn);const Mn={command:"outline <file>",describe:"Outline a source file — symbols + line numbers, not the whole file",builder:e=>ye(e).positional("file",{describe:"Source file (.ts .js .tsx .py .go .md …)",type:"string"}).option("kind",{alias:"k",describe:"Only symbols of this kind (function, class, …)",type:"string"}).option("exported",{alias:"e",describe:"Only exported symbols (TS/JS)",type:"boolean",default:!1}).example("mfn outline src/app.ts --json","structure of a file in ~50 tokens").example("mfn outline src/app.ts -k function -e --json","just the exported functions"),handler:async e=>{const t=String(e.file),n=A.extname(t).toLowerCase();if(!Ln.includes(n))return we(e,"UnsupportedType",`"${n||t}" is not outlineable. Supported: ${Ln.join(" ")}`,2);let o;try{o=await E(t,"utf8")}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,"ReadError",n)}let r=function(e,t){const n=Tn[t.toLowerCase()];if(!n)return[];const o=[],r=e.split("\n");for(let e=0;e<r.length;e++){const t=r[e],s=n===On?t.trimStart():t;for(const t of n){const r=t.re.exec(s);if(r?.groups?.name){o.push({line:e+1,kind:t.kind,name:r.groups.name.trim(),exported:Boolean(r.groups.exp)||n!==In});break}}}return o}(o,n);e.kind&&(r=r.filter(t=>t.kind===String(e.kind))),e.exported&&(r=r.filter(e=>e.exported));const s=o.split("\n").length;xe(e,{file:t,totalLines:s,count:r.length,symbols:r},()=>{for(const e of r)console.log(`${String(e.line).padStart(5)} ${e.kind.padEnd(9)} ${e.name}`)})}},zn=/(?:import\s[\s\S]*?from\s*|import\s*\(\s*|require\s*\(\s*|export\s[\s\S]*?from\s*)['"]([^'"]+)['"]/g,Cn=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs"]),Rn=new Set(["node_modules",".git","dist","build","coverage",".nx"]);function _n(e){const t=new Set;for(const n of e.matchAll(zn))t.add(n[1]);return[...t]}const Fn={command:"imports [file]",describe:"List a file’s imports, or (--who <module>) every file importing a module",builder:e=>ye(e).positional("file",{describe:"Source file to list imports of",type:"string"}).option("who",{alias:"w",describe:"Reverse mode: find files under cwd whose imports contain this string",type:"string"}).example("mfn imports src/app.ts --json","what does this file depend on?").example("mfn imports --who ../utility --json","who imports the utility module?"),handler:async e=>{if(void 0!==e.who){const t=String(e.who);if(!t)return we(e,"MissingInput","--who needs a module name/substring.",2);const n=process.cwd(),o=[];for(const e of function(e){const t=[],n=e=>{if(t.length>=2e4)return;let o;try{o=T.readdirSync(e,{withFileTypes:!0})}catch{return}for(const r of o){if(Rn.has(r.name))continue;const o=A.join(e,r.name);r.isDirectory()?n(o):r.isFile()&&Cn.has(A.extname(r.name))&&t.push(o)}};return n(e),t}(n)){let r;try{r=T.readFileSync(e,"utf8")}catch{continue}const s=_n(r).filter(e=>e.includes(t));s.length>0&&o.push({file:A.relative(n,e),specifiers:s})}return xe(e,{module:t,root:n,count:o.length,importers:o},()=>{for(const e of o)console.log(`${e.file} ← ${e.specifiers.join(", ")}`)})}if(void 0===e.file)return we(e,"MissingInput","Provide a <file>, or use --who <module>.",2);const t=String(e.file);let n;try{n=await E(t,"utf8")}catch(t){return we(e,"ReadError",t instanceof Error?t.message:String(t))}const o=_n(n),r={relative:o.filter(e=>e.startsWith(".")),packages:o.filter(e=>!e.startsWith(".")&&!e.startsWith("node:")),builtin:o.filter(e=>e.startsWith("node:"))};xe(e,{file:t,count:o.length,...r},()=>{for(const e of o)console.log(e)})}},Dn=new Set(["node_modules",".git","dist","build","coverage",".nx"]);const Bn={command:"replace <search> <replacement>",describe:"Literal find/replace across files — DRY-RUN by default, --write to apply",builder:e=>ye(e).positional("search",{describe:"Literal text to find (not a regex)",type:"string"}).positional("replacement",{describe:"Literal replacement text",type:"string"}).option("glob",{alias:"g",describe:'File glob relative to cwd (e.g. "src/**/*.ts")',type:"string",demandOption:!0}).option("write",{alias:"w",describe:"Actually modify files (default: dry-run report)",type:"boolean",default:!1}).example('mfn replace oldName newName -g "src/**/*.ts" --json',"dry-run: where + how many").example('mfn replace oldName newName -g "src/**/*.ts" -w --json',"apply the replacement"),handler:e=>{const t=String(e.search),n=String(e.replacement);if(""===t)return we(e,"MissingInput","Search text must not be empty.",2);if(t===n)return we(e,"NoOp","Search and replacement are identical.",2);const o=process.cwd(),r=function(e){let t="",n=0;for(;n<e.length;){const o=e[n];if("*"===o)if("*"===e[n+1]){const o="/"===e[n+2];t+=o?"(?:.*/)?":".*",n+=o?3:2}else t+="[^/]*",n++;else"?"===o?(t+="[^/]",n++):(t+=/[.+^${}()|[\]\\]/.test(o)?"\\"+o:o,n++)}return new RegExp(`^${t}$`)}(String(e.glob).replace(/^\.\//,"")),s=new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"g");const i=[];let a=0;const l=[];for(const c of function(e){const t=[],n=e=>{if(t.length>=1e4)return;let o;try{o=T.readdirSync(e,{withFileTypes:!0})}catch{return}for(const r of o){if(Dn.has(r.name))continue;const o=A.join(e,r.name);r.isDirectory()?n(o):r.isFile()&&t.push(o)}};return n(e),t}(o)){const d=A.relative(o,c).split(A.sep).join("/");if(!r.test(d))continue;let u;try{u=T.openSync(c,e.write?"r+":"r")}catch{continue}try{if(T.fstatSync(u).size>5242880)continue;const o=T.readFileSync(u,"utf8"),r=(o.match(s)??[]).length;if(0===r)continue;if(e.write){const e=o.split(t).join(n);T.ftruncateSync(u,0),T.writeSync(u,e,0,"utf8")}i.push({file:d,count:r}),a+=r}catch(t){e.write&&l.push({file:d,error:t instanceof Error?t.message:String(t)})}finally{T.closeSync(u)}}xe(e,{search:t,replacement:n,glob:String(e.glob),mode:e.write?"written":"dry-run",fileCount:i.length,totalReplacements:a,changes:i,errors:l},()=>{console.log(`${e.write?"replaced":"would replace"} ${a} occurrence(s) in ${i.length} file(s)`);for(const e of i)console.log(` ${e.count}× ${e.file}`);!e.write&&i.length&&console.log("re-run with --write to apply")}),l.length>0&&process.exit(1)}},Pn=new Set(["node_modules",".git","dist","build","coverage",".nx"]);function Un(e){const t=Math.round(e/1e3);return t<60?`${t}s ago`:t<3600?`${Math.round(t/60)}m ago`:t<86400?`${Math.round(t/3600)}h ago`:`${Math.round(t/86400)}d ago`}const Wn={command:"recent [dir]",describe:"Most recently modified files under a directory, with age",builder:e=>ye(e).positional("dir",{describe:"Directory to scan (default: cwd)",type:"string"}).option("top",{alias:"t",describe:"How many files to return",type:"number",default:10}).option("ignore",{alias:"i",describe:"Additional directory names to ignore",type:"array"}).example("mfn recent --json","what changed last in this project?").example("mfn recent ./src -t 5 --json","five most recent under src"),handler:e=>{const t=Number(e.top);if(!Number.isInteger(t)||t<1||t>1e3)return we(e,"InvalidTop","--top must be an integer in 1..1000.",2);const n=A.resolve(String(e.dir??process.cwd()));let o;try{o=T.statSync(n)}catch{return we(e,"NotFound",`Directory not found: ${n}`,2)}if(!o.isDirectory())return we(e,"NotADirectory",`${n} is not a directory.`,2);const r=new Set([...Pn,...(e.ignore??[]).map(String)]),s=[];let i=!1;const a=e=>{if(s.length>=2e5)return void(i=!0);let t;try{t=T.readdirSync(e,{withFileTypes:!0})}catch{return}for(const o of t){if(r.has(o.name))continue;const t=A.join(e,o.name);if(o.isDirectory())a(t);else if(o.isFile())try{const e=T.statSync(t);s.push({path:A.relative(n,t),mtimeMs:e.mtimeMs,bytes:e.size})}catch{}}};a(n);const l=Date.now(),c=s.sort((e,t)=>t.mtimeMs-e.mtimeMs).slice(0,t).map(e=>({path:e.path,bytes:e.bytes,modified:new Date(e.mtimeMs).toISOString(),age:Un(l-e.mtimeMs)}));xe(e,{root:n,fileCount:s.length,truncated:i,files:c},()=>{for(const e of c)console.log(`${e.age.padStart(8)} ${e.path}`)})}};function Jn(e){try{return JSON.parse(T.readFileSync(e,"utf8"))}catch{return null}}function Zn(e,t){const n=A.join(e,"node_modules",...t.split("/"),"package.json");return Jn(n)?.version??null}function qn(e,t){if(null===t)return!1;const n=e.replace(/^[\^~>=<]+/,"");return e===t||(!(!/^\d/.test(n)||n!==t)||null)}const Gn={command:"pkg [name]",describe:"Declared vs installed dependency versions — drift and missing installs",builder:e=>ye(e).positional("name",{describe:"One dependency to inspect (omit for all)",type:"string"}).example("mfn pkg --json","is node_modules in sync with package.json?").example("mfn pkg typescript --json","one dependency, declared vs actually installed"),handler:e=>{const t=process.cwd(),n=Jn(A.join(t,"package.json"));if(!n)return we(e,"NoPackageJson",`No readable package.json in ${t}`);const o=["dependencies","devDependencies","optionalDependencies","peerDependencies"],r=[];for(const s of o)for(const[o,i]of Object.entries(n[s]??{})){if(void 0!==e.name&&o!==String(e.name))continue;const n=Zn(t,o);r.push({name:o,declared:String(i),section:s,installed:n,satisfiesExact:qn(String(i),n)})}if(void 0!==e.name&&0===r.length)return we(e,"NotDeclared",`"${e.name}" is not declared in package.json.`);const s=r.filter(e=>null===e.installed).map(e=>e.name);xe(e,{package:n.name??null,version:n.version??null,depCount:r.length,missing:s,allInstalled:0===s.length,deps:r},()=>{for(const e of r){const t=null===e.installed?"✘ missing":e.installed;console.log(`${e.name.padEnd(40)} ${e.declared.padEnd(12)} → ${t}`)}s.length&&console.log(`\n${s.length} not installed — run your installer`)})}};function Hn(e){const t=[];for(const n of e.split("\n")){const e=n.trim();if(!e||e.startsWith("#"))continue;const o=/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(e);o&&t.push(o[1])}return t}const Yn={command:"dotenv",describe:"Check .env against .env.example — missing/extra keys, values never shown",builder:e=>ye(e).option("file",{alias:"f",describe:"Env file to check",type:"string",default:".env"}).option("example",{alias:"e",describe:"Reference file",type:"string",default:".env.example"}).example("mfn dotenv --json","is .env complete vs .env.example?").example("mfn dotenv -f .env.local -e .env.example --json","check a specific pair"),handler:e=>{const t=String(e.file),n=String(e.example);let o=null,r=null;try{o=T.readFileSync(t,"utf8")}catch{}try{r=T.readFileSync(n,"utf8")}catch{}if(null===o&&null===r)return we(e,"NotFound",`Neither ${t} nor ${n} is readable in ${process.cwd()}.`);const s=null!==o?Hn(o):[],i=null!==r?Hn(r):[],a=new Set(s),l=new Set(i),c=i.filter(e=>!a.has(e)),d=s.filter(e=>!l.has(e)),u=null===r?null:0===c.length;xe(e,{file:t,fileExists:null!==o,example:n,exampleExists:null!==r,fileKeyCount:s.length,exampleKeyCount:i.length,missing:c,extra:d,complete:u,note:"values are intentionally never read or returned"},()=>{null===o&&console.log(`${t} does not exist`),null===r&&console.log(`${n} does not exist`),!0===u&&console.log(`✔ ${t} has all ${i.length} keys from ${n}`),c.length&&console.log(`missing: ${c.join(", ")}`),d.length&&console.log(`extra (undocumented): ${d.join(", ")}`)})}},Vn=e=>new Promise(t=>setTimeout(t,e));const Kn={command:"wait",describe:"Block until a port, file, or URL is ready (or timeout) — replaces sleep loops",builder:e=>ye(e).option("port",{alias:"p",describe:"TCP port to wait for (on 127.0.0.1)",type:"number"}).option("url",{alias:"u",describe:"Wait until this URL responds 2xx/3xx",type:"string"}).option("file",{alias:"f",describe:"Wait until this file exists",type:"string"}).option("timeout",{alias:"t",describe:"Max seconds to wait",type:"number",default:30}).option("interval",{describe:"Poll interval in ms",type:"number",default:250}).example("mfn wait -p 3000 -t 30 --json","dev server is accepting connections").example("mfn wait -u http://localhost:3000/health --json","health endpoint is green").example("mfn wait -f dist/bin/index.js --json","build artifact exists"),handler:async e=>{if(1!==[e.port,e.url,e.file].filter(e=>void 0!==e).length)return we(e,"InvalidTarget","Provide exactly one of --port, --url, or --file.",2);const t=Number(e.timeout);if(!Number.isFinite(t)||t<=0||t>600)return we(e,"InvalidTimeout","--timeout must be 1..600 seconds.",2);const n=Number(e.interval);if(!Number.isInteger(n)||n<50||n>1e4)return we(e,"InvalidInterval","--interval must be 50..10000 ms.",2);let o,r;if(void 0!==e.port){const t=Number(e.port);if(!Number.isInteger(t)||t<1||t>65535)return we(e,"InvalidPort","--port must be an integer in 1..65535.",2);o=`port:${t}`,r=()=>function(e,t="127.0.0.1"){return new Promise(n=>{const o=O({port:e,host:t});o.setTimeout(1e3);const r=e=>{o.destroy(),n(e)};o.once("connect",()=>r(!0)),o.once("timeout",()=>r(!1)),o.once("error",()=>r(!1))})}(t)}else if(void 0!==e.url){const t=String(e.url);if(!/^https?:\/\//.test(t))return we(e,"InvalidURL","--url must start with http:// or https://.",2);try{if(Nt(new URL(t)))return we(e,"BlockedTarget",kt(t),2)}catch{return we(e,"InvalidURL",`"${t}" is not a valid URL.`,2)}o=`url:${t}`,r=()=>async function(e){try{return(await fetch(e,{method:"GET",signal:AbortSignal.timeout(3e3)})).ok}catch{return!1}}(t)}else{const t=String(e.file);o=`file:${t}`,r=async()=>L(t)}const s=Date.now(),i=s+1e3*t;let a=0;for(;Date.now()<i;){if(a++,await r()){const t=Date.now()-s;return xe(e,{target:o,ready:!0,waitedMs:t,attempts:a},()=>console.log(`${o} ready after ${t}ms (${a} checks)`))}await Vn(n)}we(e,"Timeout",`${o} was not ready within ${t}s (${a} checks).`)}},Qn=w(h),Xn="win32"===m();const eo={command:"ports",describe:"List ALL listening TCP ports with their owning processes",builder:e=>ye(e).option("min",{describe:"Only ports >= this value",type:"number",default:1}).example("mfn ports --json","every listener — which dev servers are running?").example("mfn ports --min 3000 --json","just the app-range ports"),handler:async e=>{const t=Number(e.min);if(!Number.isInteger(t)||t<1||t>65535)return we(e,"InvalidMin","--min must be an integer in 1..65535.",2);let n;try{n=Xn?await async function(){const{stdout:e}=await Qn("netstat",["-ano"],{timeout:1e4}),t=[];for(const n of e.split("\n")){if(!/LISTENING/i.test(n))continue;const e=n.trim().split(/\s+/),o=/^(.*):(\d+)$/.exec(e[1]??"");o&&t.push({port:Number(o[2]),pid:Number(e[e.length-1]),command:null,address:o[1]})}return t}():await async function(){let e;try{({stdout:e}=await Qn("lsof",["-iTCP","-sTCP:LISTEN","-P","-n"],{timeout:1e4}))}catch(e){if(1===e?.code&&!String(e?.stdout??"").trim())return[];throw e}const t=[];for(const n of e.split("\n").slice(1)){const e=n.trim().split(/\s+/);if(e.length<9)continue;const o=e[e.length-2].includes(":")?e[e.length-2]:e[8],r=/^(.*):(\d+)$/.exec(o);r&&t.push({port:Number(r[2]),pid:Number(e[1]),command:e[0],address:r[1]})}return t}()}catch(t){return we(e,"ListError",`Could not list listeners: ${t instanceof Error?t.message:String(t)}`)}const o=new Map;for(const e of n){if(e.port<t)continue;const n=`${e.port}:${e.pid}`;o.has(n)||o.set(n,e)}const r=[...o.values()].sort((e,t)=>e.port-t.port);xe(e,{count:r.length,listeners:r},()=>{for(const e of r)console.log(`${String(e.port).padStart(6)} pid ${String(e.pid).padEnd(8)} ${e.command??""}`)})}},to={command:"http <url>",describe:"Probe a URL: status, headers, timing, capped body preview (never a full dump)",builder:e=>ye(e).positional("url",{describe:"URL to probe (scheme optional — http:// assumed)",type:"string"}).option("method",{alias:"m",describe:"HTTP method",type:"string",choices:["GET","HEAD"],default:"GET"}).option("timeout",{alias:"t",describe:"Timeout in seconds",type:"number",default:10}).option("header",{alias:"H",describe:'Request header(s), "Name: value"',type:"array"}).example("mfn http https://api.github.com --json","status + headers + timing").example("mfn http localhost:3000/health --json","is my dev server healthy?"),handler:async e=>{let t,n=String(e.url);/^https?:\/\//.test(n)||(n=`http://${n}`);try{t=new URL(n)}catch{return we(e,"InvalidURL",`"${e.url}" is not a valid URL.`,2)}if(Nt(t))return we(e,"BlockedTarget",kt(String(t)),2);const o=Number(e.timeout);if(!Number.isFinite(o)||o<=0||o>120)return we(e,"InvalidTimeout","--timeout must be 1..120 seconds.",2);const r={};for(const t of(e.header??[]).map(String)){const n=t.indexOf(":");if(n<1)return we(e,"InvalidHeader",`Header "${t}" must be "Name: value".`,2);r[t.slice(0,n).trim()]=t.slice(n+1).trim()}const s=Date.now();let i;try{i=await fetch(t,{method:String(e.method),headers:r,redirect:"follow",signal:AbortSignal.timeout(1e3*o)})}catch(n){return we(e,"RequestFailed",`${t}: ${n instanceof Error?n.cause?.message||n.message:String(n)}`)}const a=Date.now()-s;let l=null,c=null;if("HEAD"!==String(e.method))try{const e=await i.text();c=Buffer.byteLength(e,"utf8"),l=e.slice(0,2048)}catch{}const d={};i.headers.forEach((e,t)=>{d[t]="set-cookie"===t.toLowerCase()?"[redacted: session cookie]":e}),xe(e,{url:i.url,method:String(e.method),status:i.status,statusText:i.statusText,ok:i.ok,redirected:i.redirected,timeMs:a,headers:d,bodyBytes:c,bodyPreview:l,bodyTruncated:null!==c&&c>2048},()=>{console.log(`${i.status} ${i.statusText} (${a}ms) ${i.url}`),console.log(`content-type: ${d["content-type"]??"?"}`),l&&console.log(l.slice(0,500))}),i.ok||process.exit(1)}};const no={command:"base <value>",describe:"Convert a number between bases (hex/dec/bin/oct) exactly — BigInt, no rounding",builder:e=>ye(e).positional("value",{describe:"Number: 0xff, 0b1010, 0o755, or decimal",type:"string"}).option("from",{alias:"f",describe:"Base of an unprefixed input",type:"string",choices:["hex","dec","bin","oct"]}).example("mfn base 0xff --json","hex → all bases").example("mfn base 255 --json","decimal → all bases").example("mfn base ff -f hex --json","unprefixed hex"),handler:e=>{const t=String(e.value);if(t.length>4096)return we(e,"InputTooLarge","Input exceeds 4096 characters.",2);let n;try{n=function(e,t){const n=e.trim().toLowerCase().replace(/_/g,""),o=n.startsWith("-"),r=o?n.slice(1):n;let s,i;if(r.startsWith("0x")?(s=16,i=r.slice(2)):r.startsWith("0b")?(s=2,i=r.slice(2)):r.startsWith("0o")?(s=8,i=r.slice(2)):(s=t?{hex:16,dec:10,bin:2,oct:8}[t]:10,i=r),!i||!{2:/^[01]+$/,8:/^[0-7]+$/,10:/^[0-9]+$/,16:/^[0-9a-f]+$/}[s].test(i))throw new Error(`"${e}" is not a valid base-${s} number`);let a=0n;const l=BigInt(s);for(const e of i)a=a*l+BigInt(parseInt(e,16));return{value:o?-a:a,detectedBase:s}}(t,e.from?String(e.from):void 0)}catch(t){return we(e,"InvalidNumber",t instanceof Error?t.message:String(t),2)}const o=n.value,r=o<0n?-o:o,s=o<0n?"-":"";xe(e,{input:t,inputBase:n.detectedBase,dec:o.toString(10),hex:`${s}0x${r.toString(16)}`,bin:`${s}0b${r.toString(2)}`,oct:`${s}0o${r.toString(8)}`,bits:r.toString(2).length,exact:!0},()=>{console.log(`dec ${o.toString(10)}`),console.log(`hex ${s}0x${r.toString(16)}`),console.log(`bin ${s}0b${r.toString(2)}`),console.log(`oct ${s}0o${r.toString(8)}`)})}},oo=m(),ro=1e6;function so(e,t,n){return new Promise((o,r)=>{const s=h(e,t,{timeout:5e3,maxBuffer:10485760},(e,t)=>e?r(e):o(t));void 0!==n&&s.stdin?.end(n)})}const io={command:"clip [text]",describe:"Read or write the system clipboard (macOS/Windows/Linux)",builder:e=>ye(e).positional("text",{describe:"Text to copy (or pipe stdin); omit to read",type:"string"}).option("read",{alias:"r",describe:"Force read mode even when stdin is piped",type:"boolean",default:!1}).example("mfn clip --json","read the clipboard").example('mfn clip "deploy done" --json',"copy text to the clipboard").example("git diff | mfn clip --json","copy a diff for the user to paste"),handler:async e=>{let t;if(!e.read)if(void 0!==e.text)t=String(e.text);else{const e=await je();e&&(t=e)}try{if(void 0!==t)return t.length>ro?we(e,"InputTooLarge","Clipboard writes are capped at 1000000 chars.",2):(await async function(e){if("darwin"===oo)await so("pbcopy",[],e);else if("win32"===oo)await so("clip.exe",[],e);else try{await so("xclip",["-selection","clipboard"],e)}catch{await so("wl-copy",[],e)}}(t),xe(e,{action:"write",chars:t.length},()=>console.log(`copied ${t.length} chars`)));const n=await async function(){if("darwin"===oo)return so("pbpaste",[]);if("win32"===oo)return so("powershell",["-NoProfile","-Command","Get-Clipboard -Raw"]);try{return await so("xclip",["-selection","clipboard","-o"])}catch{return so("wl-paste",["--no-newline"])}}(),o=jt(n);if(o)return xe(e,{action:"read",chars:n.length,text:null,redacted:!0,reason:`clipboard contains a ${o} — content withheld (guardrail)`},()=>console.log(`[redacted: clipboard contains a ${o}]`));xe(e,{action:"read",chars:n.length,text:n,redacted:!1},()=>console.log(n))}catch(t){return we(e,"ClipboardUnavailable",`Clipboard tool failed (headless session? missing xclip/wl-clipboard?): ${t instanceof Error?t.message:String(t)}`)}}},ao=w(h),lo=m(),co=e=>e.replace(/\\/g,"\\\\").replace(/"/g,'\\"');const uo=2e3,mo={command:"notify <message>",describe:"Send a desktop notification (macOS/Windows/Linux) — ping the user, hands-free",builder:e=>ye(e).positional("message",{describe:"Notification body",type:"string"}).option("title",{alias:"t",describe:"Notification title",type:"string",default:"mfn"}).example('mfn notify "build finished" --json',"tell the user a long task is done").example('mfn notify "3 tests failing" -t "CI watch" --json',"titled notification"),handler:async e=>{const t=String(e.message),n=String(e.title);if(t.length>uo||n.length>uo)return we(e,"InputTooLarge","Title/message are capped at 2000 chars.",2);try{await async function(e,t){if("darwin"===lo){const n=`display notification "${co(t)}" with title "${co(e)}"`;await ao("osascript",["-e",n],{timeout:5e3})}else if("win32"===lo){const n='$ErrorActionPreference=\'Stop\';[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null;$t=[Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02);$n=$t.GetElementsByTagName("text");$n.Item(0).AppendChild($t.CreateTextNode($env:MFN_NOTIFY_TITLE))|Out-Null;$n.Item(1).AppendChild($t.CreateTextNode($env:MFN_NOTIFY_MESSAGE))|Out-Null;[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("mfn").Show([Windows.UI.Notifications.ToastNotification]::new($t))';await ao("powershell",["-NoProfile","-Command",n],{timeout:1e4,env:{...process.env,MFN_NOTIFY_TITLE:e,MFN_NOTIFY_MESSAGE:t}})}else await ao("notify-send",[e,t],{timeout:5e3})}(n,t)}catch(t){return we(e,"NotifyFailed",`Could not send a notification (headless session? missing notify-send?): ${t instanceof Error?t.message:String(t)}`)}xe(e,{sent:!0,title:n,message:t},()=>console.log("notification sent"))}},po=w(h),fo=m();const ho={command:"open <target>",describe:"Open a file or URL in the default app/browser (validated first)",builder:e=>ye(e).positional("target",{describe:"http(s) URL, or an existing file/directory",type:"string"}).example("mfn open https://github.com/Master4Novice/master-cli --json","show the user a page").example("mfn open coverage/index.html --json","open a report you just generated"),handler:async e=>{const t=String(e.target);let n,o=t;if(/^https?:\/\//i.test(t)){try{new URL(t)}catch{return we(e,"InvalidURL",`"${t}" is not a valid URL.`,2)}n="url"}else{if(/^[a-z][a-z0-9+.-]*:/i.test(t))return we(e,"UnsupportedScheme","Only http(s) URLs or local paths are allowed.",2);if(o=A.resolve(t),!L(o))return we(e,"NotFound",`No such file or directory: ${o}`,2);n="file"}try{const t=await async function(e){return"darwin"===fo?(await po("open",[e],{timeout:1e4}),"open"):"win32"===fo?(await po("rundll32",["url.dll,FileProtocolHandler",e],{timeout:1e4}),"rundll32"):(await po("xdg-open",[e],{timeout:1e4}),"xdg-open")}(o);xe(e,{opened:!0,kind:n,target:o,opener:t},()=>console.log(`opened ${o}`))}catch(t){const n=t instanceof Error?t.message:String(t);return we(e,"OpenFailed",`Could not open ${o}: ${n}`)}}},go=w(h),yo="win32"===m();const bo={command:"procs [pattern]",describe:"Search running processes by name — pid/cpu/mem without ps|grep gymnastics",builder:e=>ye(e).positional("pattern",{describe:"Case-insensitive substring of the command name",type:"string"}).option("top",{alias:"t",describe:"Max results (sorted by cpu, then mem)",type:"number",default:25}).example("mfn procs node --json","every node process with pid/cpu/mem").example("mfn procs --json","top 25 by cpu — what is this machine doing?"),handler:async e=>{const t=Number(e.top);if(!Number.isInteger(t)||t<1||t>5e3)return we(e,"InvalidTop","--top must be an integer in 1..5000.",2);let n;try{n=yo?await async function(){const{stdout:e}=await go("tasklist",["/FO","CSV","/NH"],{timeout:1e4,maxBuffer:20971520}),t=[];for(const n of e.split("\n")){const e=n.match(/"([^"]*)"/g)?.map(e=>e.slice(1,-1));if(!e||e.length<5)continue;const o=Number(e[4].replace(/[^\d]/g,""));t.push({pid:Number(e[1]),cpu:null,memMB:Number.isFinite(o)?Math.round(o/1024*10)/10:null,command:e[0]})}return t}():await async function(){const{stdout:e}=await go("ps",["axo","pid=,pcpu=,rss=,comm="],{timeout:1e4,maxBuffer:20971520}),t=[];for(const n of e.split("\n")){const e=/^\s*(\d+)\s+([\d.]+)\s+(\d+)\s+(.+)$/.exec(n);e&&t.push({pid:Number(e[1]),cpu:Number(e[2]),memMB:Math.round(Number(e[3])/1024*10)/10,command:e[4].trim()})}return t}()}catch(t){return we(e,"ListError",`Could not list processes: ${t instanceof Error?t.message:String(t)}`)}const o=void 0!==e.pattern?String(e.pattern).toLowerCase():null,r=o?n.filter(e=>e.command.toLowerCase().includes(o)):n,s=r.sort((e,t)=>(t.cpu??0)-(e.cpu??0)||(t.memMB??0)-(e.memMB??0)).slice(0,t);xe(e,{pattern:o,total:n.length,matched:r.length,processes:s},()=>{for(const e of s){const t=null===e.cpu?" -":`${e.cpu.toFixed(1)}%`.padStart(6);console.log(`${String(e.pid).padStart(7)} ${t} ${String(e.memMB??"-").padStart(8)}M ${e.command}`)}})}},vo=w(h),xo="win32"===m();const wo=e=>e>=1024**4?`${(e/1024**4).toFixed(1)}T`:`${(e/1024**3).toFixed(1)}G`,$o={command:"disk",describe:"Disk usage per mount (total/free/used%) — df parsing done for you",builder:e=>ye(e).option("all",{alias:"a",describe:"Include pseudo/small filesystems (< 1GB)",type:"boolean",default:!1}).example("mfn disk --json","is there room for this build?"),handler:async e=>{let t;try{t=xo?await async function(){const{stdout:e}=await vo("powershell",["-NoProfile","-Command","Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID,Size,FreeSpace | ConvertTo-Json"],{timeout:15e3}),t=JSON.parse(e);return(Array.isArray(t)?t:[t]).filter(e=>Number(e.Size)>0).map(e=>({mount:String(e.DeviceID),filesystem:null,totalBytes:Number(e.Size),freeBytes:Number(e.FreeSpace),usedPercent:Math.round((Number(e.Size)-Number(e.FreeSpace))/Number(e.Size)*100)}))}():await async function(){const{stdout:e}=await vo("df",["-kP"],{timeout:1e4}),t=[];for(const n of e.split("\n").slice(1)){const e=n.trim().split(/\s+/);if(e.length<6)continue;const o=1024*Number(e[1]),r=1024*Number(e[3]);Number.isFinite(o)&&0!==o&&t.push({mount:e.slice(5).join(" "),filesystem:e[0],totalBytes:o,freeBytes:r,usedPercent:Math.round((o-r)/o*100)})}return t}()}catch(t){return we(e,"DiskError",`Could not read disk usage: ${t instanceof Error?t.message:String(t)}`)}e.all||(t=t.filter(e=>e.totalBytes>=1024**3&&!/^\/(dev|proc|sys|run)/.test(e.mount))),t.sort((e,t)=>t.totalBytes-e.totalBytes),xe(e,{count:t.length,mounts:t},()=>{for(const e of t)console.log(`${wo(e.totalBytes).padStart(8)} total ${wo(e.freeBytes).padStart(8)} free ${String(e.usedPercent).padStart(3)}% ${e.mount}`)})}},jo=w(h),So=m();function No(e,t){if(!T.existsSync(A.join(e,t)))return t;const n=A.extname(t),o=t.slice(0,t.length-n.length);for(let t=1;;t++){const r=`${o} ${t}${n}`;if(!T.existsSync(A.join(e,r)))return r}}function ko(e){const t=A.join(p(),".Trash"),n=A.join(t,No(t,A.basename(e)));return T.renameSync(e,n),n}function Eo(e){const t=A.join(p(),".local","share","Trash");T.mkdirSync(A.join(t,"files"),{recursive:!0}),T.mkdirSync(A.join(t,"info"),{recursive:!0});const n=No(A.join(t,"files"),A.basename(e)),o=(new Date).toISOString().slice(0,19);T.writeFileSync(A.join(t,"info",`${n}.trashinfo`),`[Trash Info]\nPath=${encodeURI(e)}\nDeletionDate=${o}\n`);const r=A.join(t,"files",n);return T.renameSync(e,r),r}async function Io(e){if(await jo("powershell",["-NoProfile","-Command",'$ErrorActionPreference=\'Stop\';Add-Type -AssemblyName Microsoft.VisualBasic;$p=$env:MFN_TRASH_PATH;if (Test-Path -LiteralPath $p -PathType Container) {[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteDirectory($p,"OnlyErrorDialogs","SendToRecycleBin")} else {[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($p,"OnlyErrorDialogs","SendToRecycleBin")}'],{timeout:15e3,env:{...process.env,MFN_TRASH_PATH:e}}),T.existsSync(e))throw new Error("Recycle Bin reported success but the path still exists");return"Recycle Bin"}const Oo={command:"trash <paths...>",describe:"Move files/dirs to the OS trash — reversible, never rm -rf",builder:e=>ye(e).positional("paths",{describe:"Files or directories to trash",type:"string"}).example("mfn trash build-old.log --json","recoverable delete").example("mfn trash dist coverage --json","trash multiple paths in one call"),handler:async e=>{const t=e.paths.map(String),n=[],o=[];for(const e of t){const t=A.resolve(e);if(!T.existsSync(t)){o.push({path:t,error:"does not exist"});continue}let r,s,i;try{r=T.realpathSync(t),s=T.realpathSync(process.cwd()),i=T.realpathSync(p())}catch{r=t,s=process.cwd(),i=p()}if(r===A.parse(r).root||r===i||r===s||s.startsWith(r+A.sep))o.push({path:t,error:"refusing to trash root/home/cwd (or a parent of cwd)"});else try{const e="darwin"===So?ko(t):"win32"===So?await Io(t):Eo(t);n.push({path:t,movedTo:e})}catch(e){o.push({path:t,error:e instanceof Error?e.message:String(e)})}}if(0===n.length&&o.length>0)return we(e,"TrashFailed",o.map(e=>`${e.path}: ${e.error}`).join("; "));xe(e,{trashed:n,failed:o,count:n.length},()=>{for(const e of n)console.log(`trashed ${e.path}`);for(const e of o)console.error(`failed ${e.path}: ${e.error}`)}),o.length>0&&process.exit(1)}},Ao=async e=>{try{return await e}catch{return null}},To={command:"dns <hostname>",describe:"Resolve a hostname: A/AAAA/CNAME/MX/TXT/NS in one call (no dig parsing)",builder:e=>ye(e).positional("hostname",{describe:"Hostname to resolve",type:"string"}).option("type",{alias:"t",describe:"Single record type instead of the full sweep",type:"string",choices:["a","aaaa","cname","mx","txt","ns"]}).example("mfn dns github.com --json","all common records at once").example("mfn dns example.com -t mx --json","just the MX records"),handler:async e=>{const t=String(e.hostname).trim().toLowerCase();if(!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/.test(t))return we(e,"InvalidHostname",`"${e.hostname}" is not a valid hostname.`,2);if(e.type){const n=String(e.type),o={a:()=>z(t),aaaa:()=>C(t),cname:()=>R(t),mx:()=>_(t),txt:()=>F(t),ns:()=>D(t)};try{const r=await o[n]();return xe(e,{hostname:t,type:n,records:r},()=>console.log(JSON.stringify(r,null,2)))}catch(o){const r=o instanceof Error?o.message:String(o);return we(e,"ResolveFailed",`${n.toUpperCase()} lookup for ${t}: ${r}`)}}const[n,o,r,s,i,a,l]=await Promise.all([Ao(M(t)),Ao(z(t)),Ao(C(t)),Ao(R(t)),Ao(_(t)),Ao(F(t)),Ao(D(t))]);if(!(n||o||r||s))return we(e,"ResolveFailed",`${t} did not resolve (no A/AAAA/CNAME).`);xe(e,{hostname:t,resolved:n?{address:n.address,family:`IPv${n.family}`}:null,a:o,aaaa:r,cname:s,mx:i,txt:a?a.map(e=>e.join("")):null,ns:l},()=>{n&&console.log(`${t} → ${n.address}`),o&&console.log(`A ${o.join(", ")}`),r&&console.log(`AAAA ${r.join(", ")}`),i&&console.log(`MX ${i.map(e=>`${e.priority} ${e.exchange}`).join(", ")}`),l&&console.log(`NS ${l.join(", ")}`)})}};function Lo(e,t,n){if(Math.abs(e.length-t.length)>n)return n+1;let o=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){const s=[r];let i=r;for(let n=1;n<=t.length;n++)s[n]=Math.min(o[n]+1,s[n-1]+1,o[n-1]+(e[r-1]===t[n-1]?0:1)),i=Math.min(i,s[n]);if(i>n)return n+1;o=s}return o[t.length]}const Mo=e=>function(e){return{add:(t,n,o,r)=>{e.command({command:t,describe:n,builder:o,handler:r})}}}(he).add(e.command,e.describe,e.builder,e.handler);Mo(ot),Mo(it),Mo(lt),Mo(dt),Mo(mt),Mo(qe),Mo(Ue),Mo(_e),Mo(Et),Mo(En),Mo(Ot),Mo(At),Mo(ln),Mo(bn),Mo(Kt),Mo(Nn),Mo(Ut),Mo(qt),Mo(sn),Mo(vn),Mo(xn),Mo(Mn),Mo(Fn),Mo(Bn),Mo(Wn),Mo(Gn),Mo(Yn),Mo(no),Mo(ht),Mo(eo),Mo(Xe),Mo(Kn),Mo(to),Mo(ze),Mo(Oe),Mo(Ct),Mo(Rt),Mo(Dt),Mo(mn),Mo(hn),Mo(yn),Mo(wn),Mo(io),Mo(mo),Mo(ho),Mo(bo),Mo($o),Mo(Oo),Mo(To),Mo(nt),he.usage("mfn <command> [options]\n\nMaster CLI for developers and AI agents — headless, JSON-first commands that\nreplace boilerplate agents regenerate on every machine. Every command supports\n--json (machine output) and -h/--help (this text).").version(se).alias("version","v").help().alias("help","h").epilogue("Discover every command (machine-readable): mfn capabilities --json\nAgent contract & examples: see llms.txt in this package.\nDocs: https://github.com/Master4Novice/master-cli#readme").wrap(null).strict().demandCommand(1,"No command given. Run `mfn capabilities` to list commands.").fail((e,t)=>{t&&Se("CommandError",t.message||String(t),1),Se("UsageError",function(e){const t=/^Unknown arguments?: (.+)$/.exec(e);if(!t)return e;const n=t[1].split(",").map(e=>e.trim()),o=process.argv.slice(2).find(e=>!e.startsWith("-")),r=n.find(e=>e===o);if(!r)return e;let s=null,i=3;for(const e of ne){const t=Lo(r,e.name,i);t<i&&(i=t,s=e.name)}return`Unknown command: ${r}.${s?` Did you mean "${s}"?`:""} Run \`mfn capabilities\` to list commands.`}(e||"Invalid command invocation."),2)}).parse();
|
|
36
36
|
//# sourceMappingURL=index.js.map
|