@pugi/cli 1.0.0-alpha.251 → 1.0.0-alpha.253

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 CHANGED
@@ -1,25 +1,36 @@
1
- # @pugi/cli
1
+ # Pugi CLI
2
2
 
3
- Pugi CLI - terminal-native software execution system.
3
+ Pugi is an AI product team in your terminal. Describe what you want in plain words and a team of AI specialists plans it, builds it, tests it and checks its security, then you publish it. Works on your own repository or a new project, on macOS and Linux.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- npm install -g @pugi/cli
8
+ curl -fsSL https://pugi.io/install | sh # macOS and Linux, no Node needed
9
+ npm install -g @pugi/cli # or with npm
10
+ brew install pugi-io/tap/pugi # or with Homebrew
9
11
  ```
10
12
 
11
13
  ## Usage
12
14
 
13
15
  ```bash
16
+ pugi # interactive session in the current folder
17
+ pugi run "..." # one-shot task
18
+ pugi login # sign in with your Pugi account
14
19
  pugi --help
15
- pugi # interactive TUI
16
- pugi run "..." # one-shot prompt
17
20
  ```
18
21
 
22
+ ## What else is Pugi
23
+
24
+ - Web console: https://app.pugi.io (build sites and apps from a brief, preview, publish)
25
+ - Desktop apps, editor and browser extensions: https://pugi.io/download
26
+ - Free logo maker and brand kit: https://logo.pugi.io
27
+ - For AI agents (MCP server, Claude Code and Cursor plugins): https://pugi.io/agents.md
28
+ - Plans: https://pugi.io/pricing
29
+
19
30
  ## License
20
31
 
21
32
  MIT - see LICENSE for upstream attribution and THIRD_PARTY_NOTICES.md for ported code.
22
33
 
23
- ## Homepage
34
+ ## Support
24
35
 
25
- https://pugi.io
36
+ support@pugi.io · https://pugi.io
package/bin/pugi CHANGED
@@ -1,22 +1,95 @@
1
- # PUGI_LAUNCHER_STUB
2
- self="$0"
3
- while [ -h "$self" ]; do
4
- link=$(readlink "$self")
5
- case "$link" in /*) self="$link" ;; *) self="$(dirname "$self")/$link" ;; esac
6
- done
7
- bindir=$(cd "$(dirname "$self")" && pwd)
8
- pkgdir=$(dirname "$bindir")
9
- if command -v node >/dev/null 2>&1; then
10
- node "$pkgdir/postinstall.mjs" >&2 || true
11
- fi
12
- if [ -x "$bindir/pugi" ] && ! grep -q "PUGI_LAUNCHER_STUB" "$bindir/pugi" 2>/dev/null; then
13
- exec "$bindir/pugi" "$@"
14
- fi
15
- echo "Error: the Pugi CLI binary could not be installed." >&2
16
- echo "" >&2
17
- echo "Your npm blocked the install script. Reinstall with it allowed:" >&2
18
- echo " npm install -g @pugi/cli --allow-scripts=@pugi/cli" >&2
19
- echo "" >&2
20
- echo "Or run the install step by hand:" >&2
21
- echo " cd "$pkgdir" && node postinstall.mjs" >&2
22
- exit 1
1
+ #!/usr/bin/env node
2
+ // `bin/pugi` of the @pugi/cli npm package (PUG-44). It runs the native Pugi
3
+ // binary from the platform package @pugi/cli-<os>-<arch>.
4
+ //
5
+ // Why a Node launcher: npm's Windows shims run the bin target by its name, and
6
+ // cmd and PowerShell will not start an exe without the .exe extension, so a
7
+ // native binary copied to `bin/pugi` never started from them. The shebang makes
8
+ // npm's cmd-shim run this file with node. It also works when install scripts
9
+ // are blocked (npm 12 does that by default for global installs): it needs no
10
+ // postinstall. On POSIX under npm or bun, the postinstall replaces this file
11
+ // with the native binary so no extra process runs (postinstall.mjs).
12
+ //
13
+ // The engine finds files that ship in the wrapper (the bundled skills) through
14
+ // PUGI_CLI_PACKAGE_DIR, because the binary it runs lives in another package.
15
+ "use strict"
16
+
17
+ const childProcess = require("child_process")
18
+ const fs = require("fs")
19
+ const path = require("path")
20
+
21
+ const PACKAGE_DIR_ENV = "PUGI_CLI_PACKAGE_DIR"
22
+ const PLATFORMS = { darwin: "darwin", linux: "linux", win32: "windows" }
23
+ const ARCHES = { x64: "x64", arm64: "arm64" }
24
+
25
+ function platformPackage(platform, arch) {
26
+ return `@pugi/cli-${PLATFORMS[platform] || platform}-${ARCHES[arch] || arch}`
27
+ }
28
+
29
+ /** The platform package's binary, resolved from the wrapper whether npm nested or hoisted it. */
30
+ function resolveBinary(packageDir, platform, arch) {
31
+ const name = platformPackage(platform, arch)
32
+ const manifest = (() => {
33
+ try {
34
+ return require.resolve(`${name}/package.json`, { paths: [packageDir] })
35
+ } catch {
36
+ return undefined
37
+ }
38
+ })()
39
+ if (!manifest) return { name }
40
+ const binary = path.join(path.dirname(manifest), "bin", platform === "win32" ? "pugi.exe" : "pugi")
41
+ return fs.existsSync(binary) ? { name, binary } : { name }
42
+ }
43
+
44
+ function run() {
45
+ const packageDir = path.dirname(path.dirname(fs.realpathSync(__filename)))
46
+ const found = resolveBinary(packageDir, process.platform, process.arch)
47
+ if (!found.binary) {
48
+ console.error(`Pugi could not find its program for ${process.platform}-${process.arch}: the package ${found.name} is not installed.`)
49
+ console.error("It is an optional dependency of @pugi/cli, so it must not be skipped. Reinstall with:")
50
+ console.error(" npm install -g @pugi/cli")
51
+ process.exit(1)
52
+ }
53
+
54
+ const child = childProcess.spawn(found.binary, process.argv.slice(2), {
55
+ stdio: "inherit",
56
+ env: { ...process.env, [PACKAGE_DIR_ENV]: packageDir },
57
+ })
58
+
59
+ // Windows: the child shares the console and gets Ctrl+C, Ctrl+Break and the
60
+ // close event itself; child.kill() would be TerminateProcess, so the launcher
61
+ // only keeps itself alive and waits. POSIX: forward, so a signal sent to the
62
+ // launcher's pid alone also reaches the engine. A Ctrl+C the terminal sends
63
+ // to the whole group then arrives twice; the engine coalesces it.
64
+ const handlers = new Map()
65
+ const ignored = process.platform === "win32" ? ["SIGINT", "SIGBREAK"] : []
66
+ const forwarded = process.platform === "win32" ? [] : ["SIGINT", "SIGTERM", "SIGHUP"]
67
+ for (const signal of ignored) handlers.set(signal, () => {})
68
+ for (const signal of forwarded) {
69
+ handlers.set(signal, () => {
70
+ try {
71
+ child.kill(signal)
72
+ } catch {
73
+ // The child has already exited.
74
+ }
75
+ })
76
+ }
77
+ for (const [signal, handler] of handlers) process.on(signal, handler)
78
+
79
+ child.on("error", (error) => {
80
+ console.error(`Pugi could not start ${found.binary}: ${error.message}`)
81
+ process.exit(1)
82
+ })
83
+ child.on("exit", (code, signal) => {
84
+ for (const [name, handler] of handlers) process.removeListener(name, handler)
85
+ if (signal && process.platform !== "win32") {
86
+ process.kill(process.pid, signal)
87
+ return
88
+ }
89
+ process.exit(typeof code === "number" ? code : 1)
90
+ })
91
+ }
92
+
93
+ if (require.main === module) run()
94
+
95
+ module.exports = { PACKAGE_DIR_ENV, platformPackage, resolveBinary }