Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ photon spectrum users ls
photon billing show
```

`pho` is an alias for `photon` for high-frequency commands:
`pho` is an alias for `photon` for high-frequency commands. It's created
automatically the first time you run `photon` after installing:

```sh
pho ls # photon projects ls
Expand Down
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@
"url": "https://github.com/photon-hq/cli/issues"
},
"type": "module",
"bin": {
"photon": "./dist/photon.js",
"pho": "./dist/photon.js"
},
"bin": "./dist/photon.js",
"files": [
"dist",
"README.md"
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import {
UnknownEnvError,
} from '~/lib/errors.ts';
import { die } from '~/lib/output.ts';
import { ensurePhoAlias } from '~/lib/pho-alias.ts';
import { startUpdateNotifier } from '~/lib/update-check.ts';
import pkg from '../package.json' with { type: 'json' };

ensurePhoAlias();
startUpdateNotifier();

const program = new Command()
Expand Down
48 changes: 48 additions & 0 deletions src/lib/pho-alias.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { existsSync, symlinkSync } from "node:fs";
import { join, resolve } from "node:path";

/**
* Lazily install `pho` as a sibling of `photon` in whichever bin directory
* we were launched from.
*
* Why not declare both bins in package.json? npm 11's `npx <scoped-pkg>`
* (no version) skips bin auto-resolve when `bin` has multiple keys. Keeping
* `bin` as a single string preserves clean `npx @photon-ai/photon` usage.
*
* Why not a `postinstall` script? Bun blocks postinstall by default — that
* would silently strip `pho` from `bun add -g` (our primary install path).
*
* Approach: walk up from the running script's path to the package root, then
* try the standard bin-dir layouts adjacent to it (local node_modules/.bin,
* bun-global `<root>/bin`, npm-global `<prefix>/bin`). First match wins.
*
* Cost is two `existsSync` calls per launch after `pho` exists. Errors are
* swallowed: this is convenience, never load-bearing.
*/
export function ensurePhoAlias(): void {
try {
const me = process.argv[1];
if (!me) return;

// process.argv[1] resolves symlinks → me is `<pkg>/dist/photon.js`.
// pkgRoot is two levels up.
const pkgRoot = resolve(me, "..", "..");

const candidates = [
resolve(pkgRoot, "..", "..", ".bin"), // local: node_modules/.bin
resolve(pkgRoot, "..", "..", "..", "bin"), // bun global: <bun-root>/bin
resolve(pkgRoot, "..", "..", "..", "..", "bin"), // npm global: <prefix>/bin
];
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Comment thread
lcandy2 marked this conversation as resolved.
Outdated
for (const dir of candidates) {
const photon = join(dir, "photon");
const pho = join(dir, "pho");
if (!existsSync(photon)) continue;
if (existsSync(pho)) return;
symlinkSync("./photon", pho);
return;
Comment thread
lcandy2 marked this conversation as resolved.
}
} catch {
// best-effort
}
}