@openagentsinc/pylon 0.1.1 → 0.1.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 CHANGED
@@ -1,33 +1,57 @@
1
1
  # `@openagentsinc/pylon`
2
2
 
3
3
  Bootstrap the latest tagged standalone `Pylon` release asset from GitHub
4
- Releases, stream first-run status updates in the terminal, and open the Pylon
5
- terminal UI without Cargo.
4
+ Releases, fall back to a deterministic source build when no matching asset
5
+ exists for the local platform, stream first-run status updates in the terminal,
6
+ and open the Pylon terminal UI without Cargo when prebuilt binaries are
7
+ available.
6
8
 
7
9
  ## Usage
8
10
 
9
11
  ```bash
10
12
  npx @openagentsinc/pylon
11
- npx @openagentsinc/pylon --version 0.0.1-rc3
13
+ bunx @openagentsinc/pylon
14
+ npm install -g @openagentsinc/pylon && pylon
15
+ bun install -g @openagentsinc/pylon && pylon
16
+ npx @openagentsinc/pylon --version 0.0.1-rc4
12
17
  npx @openagentsinc/pylon --no-launch
13
- npx @openagentsinc/pylon --model gemma-4-e2b --diagnostic-repeats 2
18
+ npx @openagentsinc/pylon --download-curated-cache --model gemma-4-e2b --diagnostic-repeats 2
19
+ npx @openagentsinc/pylon --verbose
14
20
  ```
15
21
 
16
22
  The launcher:
17
23
 
18
- - resolves the latest tagged `pylon-v...` release by default, or a specific
19
- tagged `Pylon` version when `--version` is provided
24
+ - supports direct `npx` / `bunx` execution plus global `npm install -g` /
25
+ `bun install -g` installs with the same `pylon` command
26
+ - checks GitHub for the latest tagged `pylon-v...` release on each default run,
27
+ or resolves a specific tagged `Pylon` version when `--version` is provided
20
28
  - resolves the correct `pylon-v<version>-<os>-<arch>.tar.gz` asset for the
21
29
  current machine
30
+ - falls back to the exact tagged source checkout and builds `pylon` plus
31
+ `pylon-tui` locally when no matching release asset exists for the machine
32
+ - prompts before installing the Rust toolchain via `rustup` if a source build
33
+ is needed and `cargo` / `rustc` are missing
22
34
  - downloads the archive and published SHA-256 checksum
23
35
  - verifies the checksum before extracting
24
36
  - caches the unpacked binaries under `~/.openagents/pylon/bootstrap/`
37
+ - never links or copies those cached standalone binaries into a shared global
38
+ bin directory, so the package-managed `pylon` launcher remains the command on
39
+ `PATH`
25
40
  - prints status lines such as release resolution, runtime checks, and local
26
41
  model scanning while it runs
42
+ - ends first run with an explicit verdict such as `fully online`, `runtime
43
+ ready`, or `installed but runtime missing`, plus exact next-step guidance
27
44
  - runs `pylon --help`, `init`, `status --json`, and `inventory --json`
28
- - runs `pylon gemma download <model>`
29
45
  - runs `pylon gemma diagnose <model> --json`
46
+ - only runs `pylon gemma download <model>` when `--download-curated-cache` is
47
+ set, because the optional GGUF cache does not satisfy the sellable runtime by
48
+ itself
49
+ - falls back to `curl` for release metadata and asset downloads when the Node
50
+ fetch path fails in constrained network contexts
30
51
  - opens `pylon-tui` by default after the smoke path unless `--no-launch` is set
52
+ - does not try to install or register a local runtime automatically; the
53
+ bootstrap stays honest about the separate Ollama-compatible runtime
54
+ prerequisite instead of mutating the host behind the user's back
31
55
 
32
56
  ## Publish
33
57
 
@@ -35,5 +59,6 @@ Publish directly from this package directory:
35
59
 
36
60
  ```bash
37
61
  cd packages/pylon-bootstrap
62
+ npm pack --dry-run
38
63
  npm publish
39
64
  ```
package/bin/pylon ADDED
@@ -0,0 +1,26 @@
1
+ #!/bin/sh
2
+
3
+ set -eu
4
+
5
+ SCRIPT_PATH="$0"
6
+ while [ -L "$SCRIPT_PATH" ]; do
7
+ LINK_TARGET=$(readlink "$SCRIPT_PATH")
8
+ case "$LINK_TARGET" in
9
+ /*) SCRIPT_PATH="$LINK_TARGET" ;;
10
+ *) SCRIPT_PATH="$(dirname -- "$SCRIPT_PATH")/$LINK_TARGET" ;;
11
+ esac
12
+ done
13
+
14
+ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$SCRIPT_PATH")" && pwd)
15
+ LAUNCHER_JS="${SCRIPT_DIR}/pylon.js"
16
+
17
+ if command -v node >/dev/null 2>&1; then
18
+ exec node "$LAUNCHER_JS" "$@"
19
+ fi
20
+
21
+ if command -v bun >/dev/null 2>&1; then
22
+ exec bun "$LAUNCHER_JS" "$@"
23
+ fi
24
+
25
+ echo "pylon launcher requires Node.js or Bun on PATH." >&2
26
+ exit 1
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@openagentsinc/pylon",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Bootstrap the standalone OpenAgents Pylon release asset and run first-run smoke checks.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "pylon": "./bin/pylon.js"
7
+ "pylon": "./bin/pylon"
8
8
  },
9
9
  "files": [
10
10
  "bin",
package/src/cli.js CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  bootstrapInstalledPylon,
8
8
  ensureReleaseInstall,
9
9
  launchInstalledPylonTui,
10
+ resolveBootstrapOutcome,
10
11
  renderBootstrapSummary,
11
12
  } from "./index.js";
12
13
 
@@ -67,27 +68,38 @@ function createReporter({ enableColor = process.stdout.isTTY && !process.env.NO_
67
68
  export function usage() {
68
69
  return `Usage:
69
70
  npx @openagentsinc/pylon [options]
71
+ bunx @openagentsinc/pylon [options]
72
+ pylon [options]
70
73
 
71
74
  Description:
72
75
  Download the latest tagged standalone Pylon release asset for this machine,
73
- or a specific tagged Pylon version when --version is set. Verify its
74
- checksum, cache the binaries locally, run the first-run smoke path, and then
75
- open the Pylon terminal UI by default with live status updates.
76
+ or a specific tagged Pylon version when --version is set. If no matching
77
+ asset exists for the local platform, fetch the exact tagged source checkout
78
+ and build it locally instead. Cache the binaries, run the first-run smoke
79
+ path, and then open the Pylon terminal UI by default with live status
80
+ updates. The launcher checks GitHub for newer tagged pylon-v... releases on
81
+ each default run, but only caches the standalone binaries under the local
82
+ bootstrap root; it does not replace your global npm or bun pylon command.
76
83
 
77
84
  Options:
78
85
  --version <x.y.z> Resolve a specific Pylon release.
79
86
  --install-root <path> Override the launcher cache/install root.
80
87
  --config-path <path> Override OPENAGENTS_PYLON_CONFIG_PATH.
81
88
  --pylon-home <path> Override OPENAGENTS_PYLON_HOME.
82
- --model <model-id> Model to download and diagnose.
89
+ --model <model-id> Model to diagnose, and optionally
90
+ prefetch into the local GGUF cache.
83
91
  Default: ${DEFAULT_MODEL_ID}
92
+ --download-curated-cache Prefetch the optional Hugging Face GGUF
93
+ cache before opening the TUI.
84
94
  --diagnostic-repeats <n> Repeat count for pylon gemma diagnose.
85
95
  Default: ${DEFAULT_DIAGNOSTIC_REPEATS}
86
96
  --diagnostic-max-output-tokens <n> Max output tokens for diagnostics.
87
97
  Default: ${DEFAULT_DIAGNOSTIC_MAX_OUTPUT_TOKENS}
88
- --skip-model-download Skip pylon gemma download.
98
+ --skip-model-download Keep the curated GGUF cache skipped.
89
99
  --skip-diagnostics Skip pylon gemma diagnose.
90
100
  --no-launch Do not open pylon-tui after bootstrap.
101
+ --verbose Print extra network and recovery detail.
102
+ --debug-network Alias for --verbose.
91
103
  --json Emit a machine-readable JSON summary.
92
104
 
93
105
  Test and maintainer options:
@@ -108,9 +120,10 @@ export function parseArgs(argv) {
108
120
  model: DEFAULT_MODEL_ID,
109
121
  diagnosticRepeats: DEFAULT_DIAGNOSTIC_REPEATS,
110
122
  diagnosticMaxOutputTokens: DEFAULT_DIAGNOSTIC_MAX_OUTPUT_TOKENS,
111
- skipModelDownload: false,
123
+ skipModelDownload: true,
112
124
  skipDiagnostics: false,
113
125
  noLaunch: false,
126
+ verbose: false,
114
127
  json: false,
115
128
  help: false,
116
129
  };
@@ -148,6 +161,9 @@ export function parseArgs(argv) {
148
161
  throw new Error("--model requires a value.");
149
162
  }
150
163
  break;
164
+ case "--download-curated-cache":
165
+ options.skipModelDownload = false;
166
+ break;
151
167
  case "--diagnostic-repeats":
152
168
  options.diagnosticRepeats = parseIntegerFlag(
153
169
  argv[++index],
@@ -169,6 +185,10 @@ export function parseArgs(argv) {
169
185
  case "--no-launch":
170
186
  options.noLaunch = true;
171
187
  break;
188
+ case "--verbose":
189
+ case "--debug-network":
190
+ options.verbose = true;
191
+ break;
172
192
  case "--json":
173
193
  options.json = true;
174
194
  break;
@@ -229,7 +249,12 @@ export async function main(argv = process.argv.slice(2), dependencies = {}) {
229
249
  if (options.json) {
230
250
  console.log(JSON.stringify(summary, null, 2));
231
251
  } else {
232
- reporter?.success("Pylon bootstrap complete");
252
+ const outcome = resolveBootstrapOutcome(summary);
253
+ if (outcome.level === "success") {
254
+ reporter?.success(`Pylon ${outcome.verdict}`, outcome.detail);
255
+ } else {
256
+ reporter?.warning(`Pylon ${outcome.verdict}`, outcome.detail);
257
+ }
233
258
  console.log(renderBootstrapSummary(summary));
234
259
  if (!options.noLaunch) {
235
260
  await launchInstalledPylonTuiImpl(