@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 +18 -7
- package/bin/pugi +95 -22
- package/models.json +1 -1
- package/package.json +16 -12
- package/postinstall.mjs +158 -23
- package/release.json +5 -5
package/README.md
CHANGED
|
@@ -1,25 +1,36 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Pugi CLI
|
|
2
2
|
|
|
3
|
-
Pugi
|
|
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
|
-
|
|
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
|
-
##
|
|
34
|
+
## Support
|
|
24
35
|
|
|
25
|
-
https://pugi.io
|
|
36
|
+
support@pugi.io · https://pugi.io
|
package/bin/pugi
CHANGED
|
@@ -1,22 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 }
|