@photon-ai/cli 2.2.0 → 2.3.0-staging.42732570043.1
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 +7 -1
- package/dist/photon.js +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -332,4 +332,10 @@ See [`docs/cli-design.md`](docs/cli-design.md) and [`docs/cli-build-plan.md`](do
|
|
|
332
332
|
|
|
333
333
|
## Releases
|
|
334
334
|
|
|
335
|
-
|
|
335
|
+
Every push to `main` runs the [Release workflow](.github/workflows/release.yaml) to verify and publish a staging candidate through the pinned [Buildspace package workflows](https://github.com/photon-hq/buildspace/tree/c1fb06e4ae457a8e053642a914bd37b8f5ce9e1b/.github/workflows). Manual dispatch defaults to `dry-run`, which verifies and packs without publishing or creating tags or Releases. To release, dispatch `promote` from `main` with the staging version and obtain approval in the `production` environment; promotion publishes the stored candidate under npm's stable `latest` tag without rebuilding or committing a source version bump. A successful new promotion calls [`release-binaries.yaml`](.github/workflows/release-binaries.yaml) and [`docs-reference.yml`](.github/workflows/docs-reference.yml) with that exact stable version.
|
|
336
|
+
|
|
337
|
+
The pack script builds each channel in a temporary copy with its release version, checks that the archive contains the declared package entry points and binaries, and runs the packed CLI's `--version`. The source manifest and lockfile stay unchanged.
|
|
338
|
+
|
|
339
|
+
Before the first npm publication, an npm administrator must [configure trusted publishing](https://docs.npmjs.com/trusted-publishers/) for `photon-hq/cli`, caller workflow `release.yaml`, and two environment-specific entries: `staging` and `production`, each allowing `npm publish` and `npm dist-tag`. Publishing uses GitHub OIDC; these workflows do not use `NPM_TOKEN`. Keep any legacy token until the first real promotion succeeds and no active legacy consumer or documented rollback needs it.
|
|
340
|
+
|
|
341
|
+
The first staging run can create `staging` automatically. Before the first production promotion, a repository administrator must run the [Buildspace environment setup command](https://github.com/photon-hq/buildspace/blob/main/README.md#package-stage-and-promote). The command restricts both environments to `main` and requires at least one production reviewer, using CODEOWNERS by default; append `@USER` or `@ORG/TEAM` after the repository argument if CODEOWNERS supplies no reviewers. Without reviewers, the command exits before changing either environment. [Required reviewers in private repositories need GitHub Enterprise](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments). Production binary and documentation jobs also need the existing release and docs-app permissions.
|
package/dist/photon.js
CHANGED
|
@@ -30,7 +30,7 @@ Expecting one of '${B.join("', '")}'`);if(this._lifeCycleHooks[D])this._lifeCycl
|
|
|
30
30
|
`),this.outputHelp({error:!0});let B=F||{},Z=B.exitCode||1,E=B.code||"commander.error";this._exit(Z,E,D)}_parseOptionsEnv(){this.options.forEach((D)=>{if(D.envVar&&D.envVar in c.env){let F=D.attributeName();if(this.getOptionValue(F)===void 0||["default","config","env"].includes(this.getOptionValueSource(F)))if(D.required||D.optional)this.emit(`optionEnv:${D.name()}`,c.env[D.envVar]);else this.emit(`optionEnv:${D.name()}`)}})}_parseOptionsImplied(){let D=new P5(this.options),F=(B)=>{return this.getOptionValue(B)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(B))};this.options.filter((B)=>B.implied!==void 0&&F(B.attributeName())&&D.valueFromOption(this.getOptionValue(B.attributeName()),B)).forEach((B)=>{Object.keys(B.implied).filter((Z)=>!F(Z)).forEach((Z)=>{this.setOptionValueWithSource(Z,B.implied[Z],"implied")})})}missingArgument(D){let F=`error: missing required argument '${D}'`;this.error(F,{code:"commander.missingArgument"})}optionMissingArgument(D){let F=`error: option '${D.flags}' argument missing`;this.error(F,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(D){let F=`error: required option '${D.flags}' not specified`;this.error(F,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(D,F){let B=(Y)=>{let J=Y.attributeName(),X=this.getOptionValue(J),H=this.options.find((G)=>G.negate&&J===G.attributeName()),Q=this.options.find((G)=>!G.negate&&J===G.attributeName());if(H&&(H.presetArg===void 0&&X===!1||H.presetArg!==void 0&&X===H.presetArg))return H;return Q||Y},Z=(Y)=>{let J=B(Y),X=J.attributeName();if(this.getOptionValueSource(X)==="env")return`environment variable '${J.envVar}'`;return`option '${J.flags}'`},E=`error: ${Z(D)} cannot be used with ${Z(F)}`;this.error(E,{code:"commander.conflictingOption"})}unknownOption(D){if(this._allowUnknownOption)return;let F="";if(D.startsWith("--")&&this._showSuggestionAfterError){let Z=[],E=this;do{let Y=E.createHelp().visibleOptions(E).filter((J)=>J.long).map((J)=>J.long);Z=Z.concat(Y),E=E.parent}while(E&&!E._enablePositionalOptions);F=J8(D,Z)}let B=`error: unknown option '${D}'${F}`;this.error(B,{code:"commander.unknownOption"})}_excessArguments(D){if(this._allowExcessArguments)return;let F=this.registeredArguments.length,B=F===1?"":"s",E=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${F} argument${B} but got ${D.length}.`;this.error(E,{code:"commander.excessArguments"})}unknownCommand(){let D=this.args[0],F="";if(this._showSuggestionAfterError){let Z=[];this.createHelp().visibleCommands(this).forEach((E)=>{if(Z.push(E.name()),E.alias())Z.push(E.alias())}),F=J8(D,Z)}let B=`error: unknown command '${D}'${F}`;this.error(B,{code:"commander.unknownCommand"})}version(D,F,B){if(D===void 0)return this._version;this._version=D,F=F||"-V, --version",B=B||"output the version number";let Z=this.createOption(F,B);return this._versionOptionName=Z.attributeName(),this._registerOption(Z),this.on("option:"+Z.name(),()=>{this._outputConfiguration.writeOut(`${D}
|
|
31
31
|
`),this._exit(0,"commander.version",D)}),this}description(D,F){if(D===void 0&&F===void 0)return this._description;if(this._description=D,F)this._argsDescription=F;return this}summary(D){if(D===void 0)return this._summary;return this._summary=D,this}alias(D){if(D===void 0)return this._aliases[0];let F=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)F=this.commands[this.commands.length-1];if(D===F._name)throw Error("Command alias can't be the same as its name");let B=this.parent?._findCommand(D);if(B){let Z=[B.name()].concat(B.aliases()).join("|");throw Error(`cannot add alias '${D}' to command '${this.name()}' as already have command '${Z}'`)}return F._aliases.push(D),this}aliases(D){if(D===void 0)return this._aliases;return D.forEach((F)=>this.alias(F)),this}usage(D){if(D===void 0){if(this._usage)return this._usage;let F=this.registeredArguments.map((B)=>{return k5(B)});return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?F:[]).join(" ")}return this._usage=D,this}name(D){if(D===void 0)return this._name;return this._name=D,this}helpGroup(D){if(D===void 0)return this._helpGroupHeading??"";return this._helpGroupHeading=D,this}commandsGroup(D){if(D===void 0)return this._defaultCommandGroup??"";return this._defaultCommandGroup=D,this}optionsGroup(D){if(D===void 0)return this._defaultOptionGroup??"";return this._defaultOptionGroup=D,this}_initOptionGroup(D){if(this._defaultOptionGroup&&!D.helpGroupHeading)D.helpGroup(this._defaultOptionGroup)}_initCommandGroup(D){if(this._defaultCommandGroup&&!D.helpGroup())D.helpGroup(this._defaultCommandGroup)}nameFromFilename(D){return this._name=SD.basename(D,SD.extname(D)),this}executableDir(D){if(D===void 0)return this._executableDir;return this._executableDir=D,this}helpInformation(D){let F=this.createHelp(),B=this._getOutputContext(D);F.prepareContext({error:B.error,helpWidth:B.helpWidth,outputHasColors:B.hasColors});let Z=F.formatHelp(this,F);if(B.hasColors)return Z;return this._outputConfiguration.stripColor(Z)}_getOutputContext(D){D=D||{};let F=!!D.error,B,Z,E;if(F)B=(J)=>this._outputConfiguration.writeErr(J),Z=this._outputConfiguration.getErrHasColors(),E=this._outputConfiguration.getErrHelpWidth();else B=(J)=>this._outputConfiguration.writeOut(J),Z=this._outputConfiguration.getOutHasColors(),E=this._outputConfiguration.getOutHelpWidth();return{error:F,write:(J)=>{if(!Z)J=this._outputConfiguration.stripColor(J);return B(J)},hasColors:Z,helpWidth:E}}outputHelp(D){let F;if(typeof D==="function")F=D,D=void 0;let B=this._getOutputContext(D),Z={error:B.error,write:B.write,command:this};this._getCommandAndAncestors().reverse().forEach((Y)=>Y.emit("beforeAllHelp",Z)),this.emit("beforeHelp",Z);let E=this.helpInformation({error:B.error});if(F){if(E=F(E),typeof E!=="string"&&!Buffer.isBuffer(E))throw Error("outputHelp callback must return a string or a Buffer")}if(B.write(E),this._getHelpOption()?.long)this.emit(this._getHelpOption().long);this.emit("afterHelp",Z),this._getCommandAndAncestors().forEach((Y)=>Y.emit("afterAllHelp",Z))}helpOption(D,F){if(typeof D==="boolean"){if(D){if(this._helpOption===null)this._helpOption=void 0;if(this._defaultOptionGroup)this._initOptionGroup(this._getHelpOption())}else this._helpOption=null;return this}if(this._helpOption=this.createOption(D??"-h, --help",F??"display help for command"),D||F)this._initOptionGroup(this._helpOption);return this}_getHelpOption(){if(this._helpOption===void 0)this.helpOption(void 0,void 0);return this._helpOption}addHelpOption(D){return this._helpOption=D,this._initOptionGroup(D),this}help(D){this.outputHelp(D);let F=Number(c.exitCode??0);if(F===0&&D&&typeof D!=="function"&&D.error)F=1;this._exit(F,"commander.help","(outputHelp)")}addHelpText(D,F){let B=["beforeAll","before","after","afterAll"];if(!B.includes(D))throw Error(`Unexpected value for position to addHelpText.
|
|
32
32
|
Expecting one of '${B.join("', '")}'`);let Z=`${D}Help`;return this.on(Z,(E)=>{let Y;if(typeof F==="function")Y=F({error:E.error,command:E.command});else Y=F;if(Y)E.write(`${Y}
|
|
33
|
-
`)}),this}_outputHelpIfRequested(D){let F=this._getHelpOption();if(F&&D.find((Z)=>F.is(Z)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function X8(D){return D.map((F)=>{if(!F.startsWith("--inspect"))return F;let B,Z="127.0.0.1",E="9229",Y;if((Y=F.match(/^(--inspect(-brk)?)$/))!==null)B=Y[1];else if((Y=F.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(B=Y[1],/^\d+$/.test(Y[3]))E=Y[3];else Z=Y[3];else if((Y=F.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)B=Y[1],Z=Y[3],E=Y[4];if(B&&E!=="0")return`${B}=${Z}:${parseInt(E)+1}`;return F})}function KF(){if(c.env.NO_COLOR||c.env.FORCE_COLOR==="0"||c.env.FORCE_COLOR==="false")return!1;if(c.env.FORCE_COLOR||c.env.CLICOLOR_FORCE!==void 0)return!0;return}y5.Command=zF;y5.useColor=KF});var qF=x((h5)=>{var{Argument:H8}=h0(),{Command:CF}=Q8(),{CommanderError:b5,InvalidArgumentError:G8}=H0(),{Help:v5}=XF(),{Option:K8}=QF();h5.program=new CF;h5.createCommand=(D)=>new CF(D);h5.createOption=(D,F)=>new K8(D,F);h5.createArgument=(D,F)=>new H8(D,F);h5.Command=CF;h5.Option=K8;h5.Argument=H8;h5.Help=v5;h5.CommanderError=b5;h5.InvalidArgumentError=G8;h5.InvalidOptionArgumentError=G8});var C8=x((HD,z8)=>{var WD=qF();HD=z8.exports={};HD.program=new WD.Command;HD.Argument=WD.Argument;HD.Command=WD.Command;HD.CommanderError=WD.CommanderError;HD.Help=WD.Help;HD.InvalidArgumentError=WD.InvalidArgumentError;HD.InvalidOptionArgumentError=WD.InvalidArgumentError;HD.Option=WD.Option;HD.createCommand=(D)=>new WD.Command(D);HD.createOption=(D,F)=>new WD.Option(D,F);HD.createArgument=(D,F)=>new WD.Argument(D,F)});var SF=x((dJ,c8)=>{var RF={to(D,F){if(!F)return`\x1B[${D+1}G`;return`\x1B[${F+1};${D+1}H`},move(D,F){let B="";if(D<0)B+=`\x1B[${-D}D`;else if(D>0)B+=`\x1B[${D}C`;if(F<0)B+=`\x1B[${-F}A`;else if(F>0)B+=`\x1B[${F}B`;return B},up:(D=1)=>`\x1B[${D}A`,down:(D=1)=>`\x1B[${D}B`,forward:(D=1)=>`\x1B[${D}C`,backward:(D=1)=>`\x1B[${D}D`,nextLine:(D=1)=>"\x1B[E".repeat(D),prevLine:(D=1)=>"\x1B[F".repeat(D),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},_7={up:(D=1)=>"\x1B[S".repeat(D),down:(D=1)=>"\x1B[T".repeat(D)},k7={screen:"\x1B[2J",up:(D=1)=>"\x1B[1J".repeat(D),down:(D=1)=>"\x1B[J".repeat(D),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(D){let F="";for(let B=0;B<D;B++)F+=this.line+(B<D-1?RF.up():"");if(D)F+=RF.left;return F}};c8.exports={cursor:RF,scroll:_7,erase:k7,beep:"\x07"}});class Y0 extends Error{envName;constructor(D){super(`Not authenticated for backend "${D}".`);this.envName=D;this.name="NotAuthenticatedError"}}class nD extends Error{constructor(){super("Authorization was denied.");this.name="DeviceFlowDenied"}}class gD extends Error{constructor(){super("Device code expired.");this.name="DeviceFlowExpired"}}class f extends Error{envName;constructor(D){super(`Session expired for "${D}".`);this.envName=D;this.name="SessionExpiredError"}}var u3=ID(M3(),1),s=ID(s2(),1),z={bold:s.default.bold,dim:s.default.dim,italic:s.default.italic,underline:s.default.underline,cyan:s.default.cyan,green:s.default.green,yellow:s.default.yellow,red:s.default.red,gray:s.default.gray,blue:s.default.blue,magenta:s.default.magenta,success:(D)=>s.default.green(`✓ ${D}`),error:(D)=>s.default.red(`✗ ${D}`),info:(D)=>s.default.cyan(`◆ ${D}`),warn:(D)=>s.default.yellow(`! ${D}`),hint:(D)=>s.default.dim(D)};function zD(D,F){let B=new u3.default({head:D.map((Z)=>z.bold(Z)),style:{head:[],border:["gray"]}});for(let Z of F)B.push(Z);console.log(B.toString())}function w(D){console.log(JSON.stringify(D,null,2))}function k(D){if(D instanceof Error)return D.message;if(typeof D==="string")return D;if(typeof D==="object"&&D!==null){let F=D,B=F.status?` [${F.status}]`:"";if(typeof F.value==="string")return F.value+B;if(typeof F.value==="object"&&F.value!==null){let Z=F.value;if(Z.error)return String(Z.error)+B;if(Z.message)return String(Z.message)+B}return JSON.stringify(F.value??D)+B}return String(D)}function $(D,F={}){if(console.error(z.error(D)),F.hint)console.error(z.hint(` Hint: ${F.hint}`));if(F.context)console.error(z.dim(` ${F.context}`));process.exit(F.code??1)}import L9 from"update-notifier";var A9=()=>Boolean(process.stdout.isTTY),j9=()=>Boolean(process.stdin.isTTY),T9=()=>Boolean(process.env.CI||process.env.GITHUB_ACTIONS||process.env.GITLAB_CI||process.env.CIRCLECI||process.env.BUILDKITE||process.env.TF_BUILD);var QD=()=>A9()&&j9()&&!T9();var ZD={name:"@photon-ai/cli",version:"2.2.0",description:"Photon CLI — typed terminal UI for the Photon Dashboard. Binary: `photon` (alias `pho`).",keywords:["photon","cli","dashboard","spectrum","messaging","imessage","developer-tools"],author:"Photon",license:"MIT",homepage:"https://github.com/photon-hq/cli#readme",repository:{type:"git",url:"git+https://github.com/photon-hq/cli.git"},bugs:{url:"https://github.com/photon-hq/cli/issues"},type:"module",bin:{photon:"./dist/photon.js",pho:"./dist/photon.js"},files:["dist","README.md"],publishConfig:{access:"public"},engines:{bun:">=1.3.0",node:">=18.0.0"},scripts:{start:"bun run src/index.ts",dev:"bun run --watch src/index.ts",build:"bun build ./src/index.ts --outfile dist/photon.js --target node --minify --external update-notifier && chmod +x dist/photon.js",compile:"bun build ./src/index.ts --compile --outfile dist/photon",typecheck:"tsc --noEmit",test:"bun test",check:"bun run typecheck && bun test && bun run build",manifest:"bun run scripts/generate-route-manifest.ts",prepublishOnly:"bun run typecheck && bun run build"},devDependencies:{"@photon-ai/dashboard-api":"1.6.12","@types/bun":"latest","@types/node":"^25.6.2","@types/semver":"^7.7.1","@types/update-notifier":"^6.0.8",elysia:"1.4.28",typescript:"^5"},dependencies:{"@clack/prompts":"^1.2.0","@commander-js/extra-typings":"^14.0.0","@elysiajs/eden":"1.4.9","better-auth":"1.4.18","cli-table3":"^0.6.5",commander:"^14.0.3",open:"^11.0.0",picocolors:"^1.1.1",semver:"^7.8.5","update-notifier":"^7.3.1"}};function A3(D={}){if(!(D.interactive??QD)())return;if(process.env.PHOTON_NO_UPDATE_NOTIFIER==="1")return;(D.createNotifier??L9)({pkg:{name:ZD.name,version:ZD.version},updateCheckInterval:86400000}).notify({defer:!0,isGlobal:!0})}var i3=ID(h3(),1),v0=ID(l3(),1);import{spawn as a3}from"node:child_process";import{createHash as o9}from"node:crypto";import RD from"node:fs";import ZF from"node:path";import t9 from"update-notifier";var EF=["npm","pnpm","yarn","bun"];async function e9(){let D=process.env.NO_UPDATE_NOTIFIER;process.env.NO_UPDATE_NOTIFIER="1";let F;try{({latest:F}=await t9({pkg:{name:ZD.name,version:ZD.version}}).fetchInfo())}catch(B){throw Error("Could not reach the Photon update registry.",{cause:B})}finally{if(D===void 0)delete process.env.NO_UPDATE_NOTIFIER;else process.env.NO_UPDATE_NOTIFIER=D}if(!v0.default(F))throw Error("The Photon update registry returned an invalid version.");return F}function YF(D){try{return RD.realpathSync.native(D)}catch{return ZF.resolve(D)}}function D5(D=process.argv[1]??"",F=process.execPath,B=process.env){if(!D)return{kind:"unknown",entryPath:D};let Z=ZF.resolve(D),E=YF(D),Y=YF(F),J=D.replaceAll("\\","/");if(E===Y||J.startsWith("/$bunfs/root/"))return{kind:"standalone",entryPath:ZF.resolve(F)};let X=E.replaceAll("\\","/").toLowerCase();if(X.includes("/.npm/_npx/")||X.includes("/.bun/install/cache/@photon-ai/cli@")||X.includes("/node_modules/.cache/bunx-")||X.includes("/tmp/dlx-")&&X.includes("/node_modules/"))return{kind:"ephemeral",entryPath:Z};if(X.includes("/.bun/install/global/"))return{kind:"bun",entryPath:Z};if(X.includes("/pnpm/global/")||X.includes("/.pnpm/global/"))return{kind:"pnpm",entryPath:Z};if(X.includes("/.config/yarn/global/")||X.includes("/yarn/global/"))return{kind:"yarn",entryPath:Z};if(X.includes("/lib/node_modules/@photon-ai/cli/")||X.includes("/npm/node_modules/@photon-ai/cli/"))return{kind:"npm",entryPath:Z};let H=/^yarn\/(\d+)(?:\.|\s|$)/i.exec(B.npm_config_user_agent??"")?.[1];if(H&&Number(H)>=2){let Q=(B.INIT_CWD??"").replaceAll("\\","/"),G=/\/dlx-[^/]+(?:\/|$)/i;if(G.test(J)&&(J.includes("/.yarn/")||G.test(Q)))return{kind:"yarn-dlx",entryPath:Z};return{kind:"yarn-berry",entryPath:Z}}if(!X.includes("/node_modules/@photon-ai/cli/"))return{kind:"development",entryPath:Z};return{kind:"unknown",entryPath:Z}}function n3(D){if(EF.includes(D))return D;throw Error(`Unknown installer "${D}". Expected one of: ${EF.join(", ")}.`)}function F5(D,F,B=!1){let Z=`${ZD.name}@${F}`,E=B?["--force"]:[];if(D==="npm")return{command:D,args:["install","--global",...E,Z]};if(D==="yarn")return{command:D,args:["global","add",...E,Z]};return{command:D,args:["add","--global",...E,Z]}}async function B5(D,F){await new Promise((B,Z)=>{let E=a3(D.command,D.args,{shell:!1,stdio:F?["ignore","ignore","pipe"]:"inherit"}),Y="";E.stderr?.on("data",(J)=>{Y=(Y+String(J)).slice(-8192)}),E.on("error",(J)=>{Z(Error(`Could not start ${D.command}. Make sure it is installed and on PATH.`,{cause:J}))}),E.on("close",(J,X)=>{if(J===0){B();return}let H=Y.trim(),Q=X?`signal ${X}`:`exit code ${J??"unknown"}`;Z(Error(`The ${D.command} updater failed with ${Q}.${H?` ${H}`:""}`))})})}async function Z5(D,F){let B=await new Promise((Z,E)=>{let Y=a3(process.execPath,[D,"--version"],{shell:!1,stdio:["ignore","pipe","pipe"],env:{...process.env,PHOTON_NO_UPDATE_NOTIFIER:"1"}}),J="",X="";Y.stdout.on("data",(H)=>{J=(J+String(H)).slice(-8192)}),Y.stderr.on("data",(H)=>{X=(X+String(H)).slice(-8192)}),Y.on("error",(H)=>{E(Error("Could not launch the updated Photon executable.",{cause:H}))}),Y.on("close",(H,Q)=>{if(H===0){Z(J.trim());return}let G=Q?`signal ${Q}`:`exit code ${H??"unknown"}`;E(Error(`The updated Photon executable failed with ${G}.${X.trim()?` ${X.trim()}`:""}`))})});if(B!==F)throw Error(`The installer completed, but ${D} reports ${B||"no version"} instead of ${F}.`)}function E5(){let D=process.platform==="darwin"?"darwin":process.platform;if(D!=="darwin"&&D!=="linux")throw Error(`Standalone updates are not supported on ${process.platform}.`);if(process.arch!=="arm64"&&process.arch!=="x64")throw Error(`Standalone updates are not supported on ${process.arch}.`);return`photon-${D}-${process.arch}`}async function Y5(D,F,B={}){let Z=E5(),Y=`${(B.releaseBase??"https://github.com/photon-hq/cli/releases/download").replace(/\/$/,"")}/v${F}/${Z}`,J={signal:AbortSignal.timeout(60000)},X,H;try{[X,H]=await Promise.all([fetch(Y,J),fetch(`${Y}.sha256`,J)])}catch(C){throw Error("Could not reach the Photon release downloads.",{cause:C})}if(!X.ok||!H.ok)throw Error(`Could not download Photon ${F} (${X.status}/${H.status}).`);let Q;try{Q=await H.text()}catch(C){throw Error("Could not read the Photon release checksum.",{cause:C})}let G=Q.trim().split(/\s+/,1)[0]?.toLowerCase();if(!G||!/^[a-f0-9]{64}$/.test(G))throw Error("The standalone checksum file is invalid.");let K=YF(D),W=`${K}.update-${process.pid}-${Date.now()}`,q;try{if(!X.body)throw Error("The standalone download returned an empty body.");let C;try{let U=RD.statSync(K).mode&511;q=RD.openSync(W,"wx",U||493);let V=o9("sha256"),I=X.body.getReader();while(!0){let{done:u,value:N}=await I.read();if(u)break;V.update(N);let M=0;while(M<N.byteLength){let L=RD.writeSync(q,N,M,N.byteLength-M);if(L===0)throw Error("Writing the update made no progress.");M+=L}}RD.fsyncSync(q),RD.closeSync(q),q=void 0,C=V.digest("hex")}catch(U){throw Error(`Could not stage the Photon update beside ${K}. Check the download and file permissions.`,{cause:U})}if(C!==G)throw Error("The downloaded Photon binary failed checksum verification.");try{RD.renameSync(W,K)}catch(U){throw Error(`Could not replace ${K}. Check that the file is writable.`,{cause:U})}}finally{if(q!==void 0)try{RD.closeSync(q)}catch{}try{RD.rmSync(W,{force:!0})}catch{}}}function r3(D){return D.slice(2).find((B)=>!B.startsWith("-"))==="update"}function p3(D){if(D.kind==="npm"||D.kind==="pnpm"||D.kind==="yarn"||D.kind==="bun"||D.kind==="standalone")return D.kind;if(D.kind==="ephemeral")throw Error(`A one-off Photon invocation cannot update itself. Run your package runner with ${ZD.name}@latest instead.`);if(D.kind==="development")throw Error("A development checkout cannot update itself. Update the checkout with Git instead.");if(D.kind==="yarn-dlx")throw Error(`A Yarn dlx invocation cannot update itself. Run \`yarn dlx --package ${ZD.name}@latest photon\` instead.`);if(D.kind==="yarn-berry")throw Error(`Yarn 2+ does not provide global installs. Run \`yarn up ${ZD.name}\` from the project that owns this dependency.`);throw Error(`Cannot detect this Photon installation automatically. Re-run with --installer ${EF.join("|")}.`)}function J5(D,F){if(!F)return p3(D);if(D.kind==="unknown")return F;if(D.kind===F)return F;if(D.kind==="development"||D.kind==="ephemeral")return p3(D);throw Error(`This Photon invocation was detected as ${D.kind}; refusing to update a different ${F} installation.`)}async function s3(D={},F={}){let B=F.currentVersion??ZD.version,Z=await(F.latestVersion??e9)();if(!v0.default(B)||!v0.default(Z))throw Error("Cannot compare invalid Photon release versions.");let E=i3.default(Z,B);if(!E&&!D.force)return{status:"up-to-date",currentVersion:B,latestVersion:Z,installer:null};if(D.check)return{status:E?"update-available":"up-to-date",currentVersion:B,latestVersion:Z,installer:null};let Y=F.installation??D5(),J=J5(Y,D.installer),X=E?Z:B;if(J==="standalone")await(F.replaceStandalone??Y5)(Y.entryPath,X);else await(F.runInstaller??B5)(F5(J,X,D.force),D.quiet??!1),await(F.verifyInstalled??Z5)(Y.entryPath,X);return{status:E?"updated":"reinstalled",currentVersion:B,latestVersion:Z,installer:J}}var q8=ID(C8(),1),{program:bY,createCommand:vY,createArgument:hY,createOption:gY,CommanderError:mY,InvalidArgumentError:cY,InvalidOptionArgumentError:dY,Command:W8,Argument:lY,Option:pY,Help:aY}=q8.default;import{existsSync as $8,renameSync as o5}from"node:fs";import U8 from"node:os";import oD from"node:path";var M8="https://app.photon.codes";function t5(D){return D??process.env.PHOTON_API_HOST??M8}function WF(D){try{return new URL(D).origin}catch{throw Error(`Invalid API host URL: "${D}". Must include scheme — e.g. https://your.host.tld.`)}}function N8(D){let F=WF(t5(D));return{name:e5(F),url:F}}function e5(D){let F;try{F=new URL(D)}catch{throw Error(`Invalid API host URL: "${D}". Must include scheme — e.g. https://your.host.tld.`)}if(F.origin===M8)return"production";let B=F.hostname.toLowerCase().replace(/[[\]]/g,"").replace(/[.:%]/g,"_"),Z=F.port?`_${F.port}`:"",E=`${B}${Z}`;if(E.length>64)throw Error(`API host "${D}" produces a key longer than 64 characters (got ${E.length}). Use a shorter hostname or alias the host in your local hosts file / DNS.`);return E}var D7=/^[a-z0-9_][a-z0-9_-]{0,63}$/;function F7(D){if(!D7.test(D))throw Error(`Invalid environment key "${D}" — must be 1-64 chars, `+"start with a-z, 0-9, or '_', and only contain a-z, 0-9, '-', '_'.")}function m0(){let D=process.env.PHOTON_CONFIG_DIR??process.env.DASHBOARD_CONFIG_DIR;if(D)return D;let F=process.env.XDG_CONFIG_HOME,B=F?oD.join(F,"photon"):oD.join(U8.homedir(),".config","photon"),Z=F?oD.join(F,"photon-dashboard"):oD.join(U8.homedir(),".config","photon-dashboard"),E=B;if(!$8(B)&&$8(Z))try{o5(Z,B)}catch{E=Z}return E}var $F=()=>oD.join(m0(),"credentials"),c0=(D)=>{return F7(D),oD.join($F(),`${D}.json`)};async function YD(D){return N8(D)}import{chmod as B7,mkdir as Z7,readdir as E7,readFile as Y7,unlink as J7,writeFile as X7}from"node:fs/promises";import{dirname as Q7}from"node:path";async function tD(D){try{let F=await Y7(c0(D),"utf-8");return JSON.parse(F)}catch{return null}}async function V8(D){let F=c0(D.envName);await Z7(Q7(F),{recursive:!0}),await X7(F,JSON.stringify(D,null,2)+`
|
|
33
|
+
`)}),this}_outputHelpIfRequested(D){let F=this._getHelpOption();if(F&&D.find((Z)=>F.is(Z)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function X8(D){return D.map((F)=>{if(!F.startsWith("--inspect"))return F;let B,Z="127.0.0.1",E="9229",Y;if((Y=F.match(/^(--inspect(-brk)?)$/))!==null)B=Y[1];else if((Y=F.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(B=Y[1],/^\d+$/.test(Y[3]))E=Y[3];else Z=Y[3];else if((Y=F.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)B=Y[1],Z=Y[3],E=Y[4];if(B&&E!=="0")return`${B}=${Z}:${parseInt(E)+1}`;return F})}function KF(){if(c.env.NO_COLOR||c.env.FORCE_COLOR==="0"||c.env.FORCE_COLOR==="false")return!1;if(c.env.FORCE_COLOR||c.env.CLICOLOR_FORCE!==void 0)return!0;return}y5.Command=zF;y5.useColor=KF});var qF=x((h5)=>{var{Argument:H8}=h0(),{Command:CF}=Q8(),{CommanderError:b5,InvalidArgumentError:G8}=H0(),{Help:v5}=XF(),{Option:K8}=QF();h5.program=new CF;h5.createCommand=(D)=>new CF(D);h5.createOption=(D,F)=>new K8(D,F);h5.createArgument=(D,F)=>new H8(D,F);h5.Command=CF;h5.Option=K8;h5.Argument=H8;h5.Help=v5;h5.CommanderError=b5;h5.InvalidArgumentError=G8;h5.InvalidOptionArgumentError=G8});var C8=x((HD,z8)=>{var WD=qF();HD=z8.exports={};HD.program=new WD.Command;HD.Argument=WD.Argument;HD.Command=WD.Command;HD.CommanderError=WD.CommanderError;HD.Help=WD.Help;HD.InvalidArgumentError=WD.InvalidArgumentError;HD.InvalidOptionArgumentError=WD.InvalidArgumentError;HD.Option=WD.Option;HD.createCommand=(D)=>new WD.Command(D);HD.createOption=(D,F)=>new WD.Option(D,F);HD.createArgument=(D,F)=>new WD.Argument(D,F)});var SF=x((dJ,c8)=>{var RF={to(D,F){if(!F)return`\x1B[${D+1}G`;return`\x1B[${F+1};${D+1}H`},move(D,F){let B="";if(D<0)B+=`\x1B[${-D}D`;else if(D>0)B+=`\x1B[${D}C`;if(F<0)B+=`\x1B[${-F}A`;else if(F>0)B+=`\x1B[${F}B`;return B},up:(D=1)=>`\x1B[${D}A`,down:(D=1)=>`\x1B[${D}B`,forward:(D=1)=>`\x1B[${D}C`,backward:(D=1)=>`\x1B[${D}D`,nextLine:(D=1)=>"\x1B[E".repeat(D),prevLine:(D=1)=>"\x1B[F".repeat(D),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},_7={up:(D=1)=>"\x1B[S".repeat(D),down:(D=1)=>"\x1B[T".repeat(D)},k7={screen:"\x1B[2J",up:(D=1)=>"\x1B[1J".repeat(D),down:(D=1)=>"\x1B[J".repeat(D),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(D){let F="";for(let B=0;B<D;B++)F+=this.line+(B<D-1?RF.up():"");if(D)F+=RF.left;return F}};c8.exports={cursor:RF,scroll:_7,erase:k7,beep:"\x07"}});class Y0 extends Error{envName;constructor(D){super(`Not authenticated for backend "${D}".`);this.envName=D;this.name="NotAuthenticatedError"}}class nD extends Error{constructor(){super("Authorization was denied.");this.name="DeviceFlowDenied"}}class gD extends Error{constructor(){super("Device code expired.");this.name="DeviceFlowExpired"}}class f extends Error{envName;constructor(D){super(`Session expired for "${D}".`);this.envName=D;this.name="SessionExpiredError"}}var u3=ID(M3(),1),s=ID(s2(),1),z={bold:s.default.bold,dim:s.default.dim,italic:s.default.italic,underline:s.default.underline,cyan:s.default.cyan,green:s.default.green,yellow:s.default.yellow,red:s.default.red,gray:s.default.gray,blue:s.default.blue,magenta:s.default.magenta,success:(D)=>s.default.green(`✓ ${D}`),error:(D)=>s.default.red(`✗ ${D}`),info:(D)=>s.default.cyan(`◆ ${D}`),warn:(D)=>s.default.yellow(`! ${D}`),hint:(D)=>s.default.dim(D)};function zD(D,F){let B=new u3.default({head:D.map((Z)=>z.bold(Z)),style:{head:[],border:["gray"]}});for(let Z of F)B.push(Z);console.log(B.toString())}function w(D){console.log(JSON.stringify(D,null,2))}function k(D){if(D instanceof Error)return D.message;if(typeof D==="string")return D;if(typeof D==="object"&&D!==null){let F=D,B=F.status?` [${F.status}]`:"";if(typeof F.value==="string")return F.value+B;if(typeof F.value==="object"&&F.value!==null){let Z=F.value;if(Z.error)return String(Z.error)+B;if(Z.message)return String(Z.message)+B}return JSON.stringify(F.value??D)+B}return String(D)}function $(D,F={}){if(console.error(z.error(D)),F.hint)console.error(z.hint(` Hint: ${F.hint}`));if(F.context)console.error(z.dim(` ${F.context}`));process.exit(F.code??1)}import L9 from"update-notifier";var A9=()=>Boolean(process.stdout.isTTY),j9=()=>Boolean(process.stdin.isTTY),T9=()=>Boolean(process.env.CI||process.env.GITHUB_ACTIONS||process.env.GITLAB_CI||process.env.CIRCLECI||process.env.BUILDKITE||process.env.TF_BUILD);var QD=()=>A9()&&j9()&&!T9();var ZD={name:"@photon-ai/cli",version:"2.3.0-staging.42732570043.1",description:"Photon CLI — typed terminal UI for the Photon Dashboard. Binary: `photon` (alias `pho`).",keywords:["photon","cli","dashboard","spectrum","messaging","imessage","developer-tools"],author:"Photon",license:"MIT",homepage:"https://github.com/photon-hq/cli#readme",repository:{type:"git",url:"git+https://github.com/photon-hq/cli.git"},bugs:{url:"https://github.com/photon-hq/cli/issues"},type:"module",bin:{photon:"./dist/photon.js",pho:"./dist/photon.js"},files:["dist","README.md"],publishConfig:{access:"public"},engines:{bun:">=1.3.0",node:">=18.0.0"},scripts:{start:"bun run src/index.ts",dev:"bun run --watch src/index.ts",build:"bun build ./src/index.ts --outfile dist/photon.js --target node --minify --external update-notifier && chmod +x dist/photon.js",compile:"bun build ./src/index.ts --compile --outfile dist/photon",typecheck:"tsc --noEmit",test:"bun test",check:"bun run typecheck && bun test && bun run build",manifest:"bun run scripts/generate-route-manifest.ts",prepublishOnly:"bun run typecheck && bun run build","docs:reference":"bun run scripts/export-docs.ts"},devDependencies:{"@photon-ai/dashboard-api":"1.6.12","@types/bun":"latest","@types/node":"^25.6.2","@types/semver":"^7.7.1","@types/update-notifier":"^6.0.8",elysia:"1.4.28",typescript:"^5"},dependencies:{"@clack/prompts":"^1.2.0","@commander-js/extra-typings":"^14.0.0","@elysiajs/eden":"1.4.9","better-auth":"1.4.18","cli-table3":"^0.6.5",commander:"^14.0.3",open:"^11.0.0",picocolors:"^1.1.1",semver:"^7.8.5","update-notifier":"^7.3.1"}};function A3(D={}){if(!(D.interactive??QD)())return;if(process.env.PHOTON_NO_UPDATE_NOTIFIER==="1")return;(D.createNotifier??L9)({pkg:{name:ZD.name,version:ZD.version},updateCheckInterval:86400000}).notify({defer:!0,isGlobal:!0})}var i3=ID(h3(),1),v0=ID(l3(),1);import{spawn as a3}from"node:child_process";import{createHash as o9}from"node:crypto";import RD from"node:fs";import ZF from"node:path";import t9 from"update-notifier";var EF=["npm","pnpm","yarn","bun"];async function e9(){let D=process.env.NO_UPDATE_NOTIFIER;process.env.NO_UPDATE_NOTIFIER="1";let F;try{({latest:F}=await t9({pkg:{name:ZD.name,version:ZD.version}}).fetchInfo())}catch(B){throw Error("Could not reach the Photon update registry.",{cause:B})}finally{if(D===void 0)delete process.env.NO_UPDATE_NOTIFIER;else process.env.NO_UPDATE_NOTIFIER=D}if(!v0.default(F))throw Error("The Photon update registry returned an invalid version.");return F}function YF(D){try{return RD.realpathSync.native(D)}catch{return ZF.resolve(D)}}function D5(D=process.argv[1]??"",F=process.execPath,B=process.env){if(!D)return{kind:"unknown",entryPath:D};let Z=ZF.resolve(D),E=YF(D),Y=YF(F),J=D.replaceAll("\\","/");if(E===Y||J.startsWith("/$bunfs/root/"))return{kind:"standalone",entryPath:ZF.resolve(F)};let X=E.replaceAll("\\","/").toLowerCase();if(X.includes("/.npm/_npx/")||X.includes("/.bun/install/cache/@photon-ai/cli@")||X.includes("/node_modules/.cache/bunx-")||X.includes("/tmp/dlx-")&&X.includes("/node_modules/"))return{kind:"ephemeral",entryPath:Z};if(X.includes("/.bun/install/global/"))return{kind:"bun",entryPath:Z};if(X.includes("/pnpm/global/")||X.includes("/.pnpm/global/"))return{kind:"pnpm",entryPath:Z};if(X.includes("/.config/yarn/global/")||X.includes("/yarn/global/"))return{kind:"yarn",entryPath:Z};if(X.includes("/lib/node_modules/@photon-ai/cli/")||X.includes("/npm/node_modules/@photon-ai/cli/"))return{kind:"npm",entryPath:Z};let H=/^yarn\/(\d+)(?:\.|\s|$)/i.exec(B.npm_config_user_agent??"")?.[1];if(H&&Number(H)>=2){let Q=(B.INIT_CWD??"").replaceAll("\\","/"),G=/\/dlx-[^/]+(?:\/|$)/i;if(G.test(J)&&(J.includes("/.yarn/")||G.test(Q)))return{kind:"yarn-dlx",entryPath:Z};return{kind:"yarn-berry",entryPath:Z}}if(!X.includes("/node_modules/@photon-ai/cli/"))return{kind:"development",entryPath:Z};return{kind:"unknown",entryPath:Z}}function n3(D){if(EF.includes(D))return D;throw Error(`Unknown installer "${D}". Expected one of: ${EF.join(", ")}.`)}function F5(D,F,B=!1){let Z=`${ZD.name}@${F}`,E=B?["--force"]:[];if(D==="npm")return{command:D,args:["install","--global",...E,Z]};if(D==="yarn")return{command:D,args:["global","add",...E,Z]};return{command:D,args:["add","--global",...E,Z]}}async function B5(D,F){await new Promise((B,Z)=>{let E=a3(D.command,D.args,{shell:!1,stdio:F?["ignore","ignore","pipe"]:"inherit"}),Y="";E.stderr?.on("data",(J)=>{Y=(Y+String(J)).slice(-8192)}),E.on("error",(J)=>{Z(Error(`Could not start ${D.command}. Make sure it is installed and on PATH.`,{cause:J}))}),E.on("close",(J,X)=>{if(J===0){B();return}let H=Y.trim(),Q=X?`signal ${X}`:`exit code ${J??"unknown"}`;Z(Error(`The ${D.command} updater failed with ${Q}.${H?` ${H}`:""}`))})})}async function Z5(D,F){let B=await new Promise((Z,E)=>{let Y=a3(process.execPath,[D,"--version"],{shell:!1,stdio:["ignore","pipe","pipe"],env:{...process.env,PHOTON_NO_UPDATE_NOTIFIER:"1"}}),J="",X="";Y.stdout.on("data",(H)=>{J=(J+String(H)).slice(-8192)}),Y.stderr.on("data",(H)=>{X=(X+String(H)).slice(-8192)}),Y.on("error",(H)=>{E(Error("Could not launch the updated Photon executable.",{cause:H}))}),Y.on("close",(H,Q)=>{if(H===0){Z(J.trim());return}let G=Q?`signal ${Q}`:`exit code ${H??"unknown"}`;E(Error(`The updated Photon executable failed with ${G}.${X.trim()?` ${X.trim()}`:""}`))})});if(B!==F)throw Error(`The installer completed, but ${D} reports ${B||"no version"} instead of ${F}.`)}function E5(){let D=process.platform==="darwin"?"darwin":process.platform;if(D!=="darwin"&&D!=="linux")throw Error(`Standalone updates are not supported on ${process.platform}.`);if(process.arch!=="arm64"&&process.arch!=="x64")throw Error(`Standalone updates are not supported on ${process.arch}.`);return`photon-${D}-${process.arch}`}async function Y5(D,F,B={}){let Z=E5(),Y=`${(B.releaseBase??"https://github.com/photon-hq/cli/releases/download").replace(/\/$/,"")}/v${F}/${Z}`,J={signal:AbortSignal.timeout(60000)},X,H;try{[X,H]=await Promise.all([fetch(Y,J),fetch(`${Y}.sha256`,J)])}catch(C){throw Error("Could not reach the Photon release downloads.",{cause:C})}if(!X.ok||!H.ok)throw Error(`Could not download Photon ${F} (${X.status}/${H.status}).`);let Q;try{Q=await H.text()}catch(C){throw Error("Could not read the Photon release checksum.",{cause:C})}let G=Q.trim().split(/\s+/,1)[0]?.toLowerCase();if(!G||!/^[a-f0-9]{64}$/.test(G))throw Error("The standalone checksum file is invalid.");let K=YF(D),W=`${K}.update-${process.pid}-${Date.now()}`,q;try{if(!X.body)throw Error("The standalone download returned an empty body.");let C;try{let U=RD.statSync(K).mode&511;q=RD.openSync(W,"wx",U||493);let V=o9("sha256"),I=X.body.getReader();while(!0){let{done:u,value:N}=await I.read();if(u)break;V.update(N);let M=0;while(M<N.byteLength){let L=RD.writeSync(q,N,M,N.byteLength-M);if(L===0)throw Error("Writing the update made no progress.");M+=L}}RD.fsyncSync(q),RD.closeSync(q),q=void 0,C=V.digest("hex")}catch(U){throw Error(`Could not stage the Photon update beside ${K}. Check the download and file permissions.`,{cause:U})}if(C!==G)throw Error("The downloaded Photon binary failed checksum verification.");try{RD.renameSync(W,K)}catch(U){throw Error(`Could not replace ${K}. Check that the file is writable.`,{cause:U})}}finally{if(q!==void 0)try{RD.closeSync(q)}catch{}try{RD.rmSync(W,{force:!0})}catch{}}}function r3(D){return D.slice(2).find((B)=>!B.startsWith("-"))==="update"}function p3(D){if(D.kind==="npm"||D.kind==="pnpm"||D.kind==="yarn"||D.kind==="bun"||D.kind==="standalone")return D.kind;if(D.kind==="ephemeral")throw Error(`A one-off Photon invocation cannot update itself. Run your package runner with ${ZD.name}@latest instead.`);if(D.kind==="development")throw Error("A development checkout cannot update itself. Update the checkout with Git instead.");if(D.kind==="yarn-dlx")throw Error(`A Yarn dlx invocation cannot update itself. Run \`yarn dlx --package ${ZD.name}@latest photon\` instead.`);if(D.kind==="yarn-berry")throw Error(`Yarn 2+ does not provide global installs. Run \`yarn up ${ZD.name}\` from the project that owns this dependency.`);throw Error(`Cannot detect this Photon installation automatically. Re-run with --installer ${EF.join("|")}.`)}function J5(D,F){if(!F)return p3(D);if(D.kind==="unknown")return F;if(D.kind===F)return F;if(D.kind==="development"||D.kind==="ephemeral")return p3(D);throw Error(`This Photon invocation was detected as ${D.kind}; refusing to update a different ${F} installation.`)}async function s3(D={},F={}){let B=F.currentVersion??ZD.version,Z=await(F.latestVersion??e9)();if(!v0.default(B)||!v0.default(Z))throw Error("Cannot compare invalid Photon release versions.");let E=i3.default(Z,B);if(!E&&!D.force)return{status:"up-to-date",currentVersion:B,latestVersion:Z,installer:null};if(D.check)return{status:E?"update-available":"up-to-date",currentVersion:B,latestVersion:Z,installer:null};let Y=F.installation??D5(),J=J5(Y,D.installer),X=E?Z:B;if(J==="standalone")await(F.replaceStandalone??Y5)(Y.entryPath,X);else await(F.runInstaller??B5)(F5(J,X,D.force),D.quiet??!1),await(F.verifyInstalled??Z5)(Y.entryPath,X);return{status:E?"updated":"reinstalled",currentVersion:B,latestVersion:Z,installer:J}}var q8=ID(C8(),1),{program:bY,createCommand:vY,createArgument:hY,createOption:gY,CommanderError:mY,InvalidArgumentError:cY,InvalidOptionArgumentError:dY,Command:W8,Argument:lY,Option:pY,Help:aY}=q8.default;import{existsSync as $8,renameSync as o5}from"node:fs";import U8 from"node:os";import oD from"node:path";var M8="https://app.photon.codes";function t5(D){return D??process.env.PHOTON_API_HOST??M8}function WF(D){try{return new URL(D).origin}catch{throw Error(`Invalid API host URL: "${D}". Must include scheme — e.g. https://your.host.tld.`)}}function N8(D){let F=WF(t5(D));return{name:e5(F),url:F}}function e5(D){let F;try{F=new URL(D)}catch{throw Error(`Invalid API host URL: "${D}". Must include scheme — e.g. https://your.host.tld.`)}if(F.origin===M8)return"production";let B=F.hostname.toLowerCase().replace(/[[\]]/g,"").replace(/[.:%]/g,"_"),Z=F.port?`_${F.port}`:"",E=`${B}${Z}`;if(E.length>64)throw Error(`API host "${D}" produces a key longer than 64 characters (got ${E.length}). Use a shorter hostname or alias the host in your local hosts file / DNS.`);return E}var D7=/^[a-z0-9_][a-z0-9_-]{0,63}$/;function F7(D){if(!D7.test(D))throw Error(`Invalid environment key "${D}" — must be 1-64 chars, `+"start with a-z, 0-9, or '_', and only contain a-z, 0-9, '-', '_'.")}function m0(){let D=process.env.PHOTON_CONFIG_DIR??process.env.DASHBOARD_CONFIG_DIR;if(D)return D;let F=process.env.XDG_CONFIG_HOME,B=F?oD.join(F,"photon"):oD.join(U8.homedir(),".config","photon"),Z=F?oD.join(F,"photon-dashboard"):oD.join(U8.homedir(),".config","photon-dashboard"),E=B;if(!$8(B)&&$8(Z))try{o5(Z,B)}catch{E=Z}return E}var $F=()=>oD.join(m0(),"credentials"),c0=(D)=>{return F7(D),oD.join($F(),`${D}.json`)};async function YD(D){return N8(D)}import{chmod as B7,mkdir as Z7,readdir as E7,readFile as Y7,unlink as J7,writeFile as X7}from"node:fs/promises";import{dirname as Q7}from"node:path";async function tD(D){try{let F=await Y7(c0(D),"utf-8");return JSON.parse(F)}catch{return null}}async function V8(D){let F=c0(D.envName);await Z7(Q7(F),{recursive:!0}),await X7(F,JSON.stringify(D,null,2)+`
|
|
34
34
|
`,"utf-8"),await B7(F,384)}async function u8(D){let F=c0(D);try{await J7(F)}catch(B){if(B.code!=="ENOENT")throw B}}async function d0(){try{return(await E7($F())).filter((F)=>F.endsWith(".json")).map((F)=>F.slice(0,-5)).sort()}catch(D){if(D.code==="ENOENT")return[];throw D}}function A8(D){D.command("auth").description("inspect authentication state across backends").command("status").description("show login status for every backend you've authenticated against").option("--json","output JSON").action(async(B)=>{let Z=await YD(),E=await d0(),Y=Array.from(new Set([Z.name,...E])).sort(),J=await Promise.all(Y.map(async(Q)=>{let G=await tD(Q);if(!G)return{name:Q,url:Q===Z.name?Z.url:null,loggedIn:!1,user:null,issuedAt:null,corrupt:E.includes(Q)};return{name:Q,url:G.apiUrl,loggedIn:!0,user:G.user,issuedAt:G.issuedAt,corrupt:!1}}));if(B.json)return w(J);let X=J.map((Q)=>[Q.name===Z.name?z.green("●"):" ",Q.name,Q.url??z.dim("—"),Q.loggedIn?z.green(Q.user?.email??"yes"):Q.corrupt?z.yellow("corrupt"):z.dim("no"),Q.issuedAt?new Date(Q.issuedAt).toLocaleDateString():z.dim("—")]);zD(["","key","url","logged in","since"],X);let H=J.filter((Q)=>Q.corrupt).map((Q)=>Q.name);if(H.length>0)console.log(),console.log(z.warn(`Credentials file for ${H.join(", ")} is unreadable. Re-login with \`photon login --api-host <url>\`.`))})}var fD=class extends Error{constructor(D,F){super(F+"");this.status=D,this.value=F}},H7=/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/,G7=/(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{2}\s\d{4}\s\d{2}:\d{2}:\d{2}\sGMT(?:\+|-)\d{4}\s\([^)]+\)/,K7=/^(?:(?:(?:(?:0?[1-9]|[12][0-9]|3[01])[/\s-](?:0?[1-9]|1[0-2])[/\s-](?:19|20)\d{2})|(?:(?:19|20)\d{2}[/\s-](?:0?[1-9]|1[0-2])[/\s-](?:0?[1-9]|[12][0-9]|3[01]))))(?:\s(?:1[012]|0?[1-9]):[0-5][0-9](?::[0-5][0-9])?(?:\s[AP]M)?)?$/,z7=(D)=>D.trim().length!==0&&!Number.isNaN(Number(D)),l0=(D,F)=>{if(typeof D!="string"||F?.parseDate===!1)return null;let B=D.replace(/"/g,"");if(H7.test(B)||G7.test(B)||K7.test(B)){let Z=new Date(B);if(!Number.isNaN(Z.getTime()))return Z}return null},C7=(D)=>{let F=D.charCodeAt(0),B=D.charCodeAt(D.length-1);return F===123&&B===125||F===91&&B===93},q7=(D,F)=>JSON.parse(D,(B,Z)=>{return l0(Z,F)||Z}),cD=(D,F)=>{if(!D)return D;if(z7(D))return+D;if(D==="true")return!0;if(D==="false")return!1;if(F?.parseDate!==!1){let B=l0(D,F);if(B)return B}if(C7(D))try{return q7(D,F)}catch{}return D},UF=(D,F)=>{let B=D.data.toString();return B==="null"?null:cD(B,F)};var W7=class{constructor(D){this.url=D,this.ws=new WebSocket(D)}ws;send(D){return Array.isArray(D)?(D.forEach((F)=>this.send(F)),this):(this.ws.send(typeof D=="object"?JSON.stringify(D):D.toString()),this)}on(D,F,B){return this.addEventListener(D,F,B)}off(D,F,B){return this.ws.removeEventListener(D,F,B),this}subscribe(D,F){return this.addEventListener("message",D,F)}addEventListener(D,F,B){return this.ws.addEventListener(D,(Z)=>{if(D==="message"){let E=UF(Z);F({...Z,data:E})}else F(Z)},B),this}removeEventListener(D,F,B){return this.off(D,F,B),this}close(){return this.ws.close(),this}},$7=["get","post","put","delete","patch","options","head","connect","subscribe"],j8=(D,F)=>typeof F=="function"?F(D):F===!0,L8=["localhost","127.0.0.1","0.0.0.0"],NF=typeof FileList>"u",p0=(D)=>NF?D instanceof Blob:D instanceof FileList||D instanceof File,U7=(D)=>{if(!D)return!1;for(let F in D)if(p0(D[F])||Array.isArray(D[F])&&D[F].find(p0))return!0;return!1},MF=(D)=>NF?D:new Promise((F)=>{let B=new FileReader;B.onload=()=>{let Z=new File([B.result],D.name,{lastModified:D.lastModified,type:D.type});F(Z)},B.readAsArrayBuffer(D)}),dD=async(D,F,B={},Z={})=>{if(Array.isArray(D)){for(let E of D)if(!Array.isArray(E))Z=await dD(E,F,B,Z);else{let Y=E[0];if(typeof Y=="string")Z[Y.toLowerCase()]=E[1];else for(let[J,X]of Y)Z[J.toLowerCase()]=X}return Z}if(!D)return Z;switch(typeof D){case"function":if(D instanceof Headers)return dD(D,F,B,Z);let E=await D(F,B);return E?dD(E,F,B,Z):Z;case"object":if(D instanceof Headers)return D.forEach((Y,J)=>{Z[J.toLowerCase()]=Y}),Z;for(let[Y,J]of Object.entries(D))Z[Y.toLowerCase()]=J;return Z;default:return Z}};function R8(D,F){let B=D.split(`
|
|
35
35
|
`),Z={};for(let E of B){if(!E||E.startsWith(":"))continue;let Y=E.indexOf(":");if(Y>0){let J=E.slice(0,Y).trim(),X=E.slice(Y+1).replace(/^ /,"");Z[J]=X&&cD(X,F)}}return Object.keys(Z).length>0?Z:null}function*T8(D,F){let B;for(;(B=D.value.indexOf(`
|
|
36
36
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@photon-ai/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0-staging.42732570043.1",
|
|
4
4
|
"description": "Photon CLI — typed terminal UI for the Photon Dashboard. Binary: `photon` (alias `pho`).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"photon",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"test": "bun test",
|
|
47
47
|
"check": "bun run typecheck && bun test && bun run build",
|
|
48
48
|
"manifest": "bun run scripts/generate-route-manifest.ts",
|
|
49
|
-
"prepublishOnly": "bun run typecheck && bun run build"
|
|
49
|
+
"prepublishOnly": "bun run typecheck && bun run build",
|
|
50
|
+
"docs:reference": "bun run scripts/export-docs.ts"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@photon-ai/dashboard-api": "1.6.12",
|