@qpfai/pf-gate-cli 1.0.21 → 1.0.23

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-02-17T00:29:14.163Z",
3
+ "generatedAt": "2026-02-17T00:54:14.813Z",
4
4
  "pythonPackage": "persons-field",
5
5
  "pythonPackageVersion": "1.0.0",
6
6
  "wheel": "persons_field-1.0.0-py3-none-any.whl",
7
- "sha256": "03fdc1cc05a98dccc792ca55eed751388b7a5e17cea6097662780b0ae28bcbe0"
7
+ "sha256": "14e691f6192750c06bf93dbf790d0af215175e41f97f32fa0355f779baba56aa"
8
8
  }
package/lib/main.mjs CHANGED
@@ -18,7 +18,6 @@ const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
18
18
  const UPDATE_CHECK_TIMEOUT_MS = 6000;
19
19
  const UPDATE_INSTALL_MAX_RETRIES = 10;
20
20
  const UPDATE_INSTALL_RETRY_MS = 3000;
21
- const SPHERE_FRAMES = ["🌐", "🌍", "🌎", "🌏"];
22
21
 
23
22
  function isWindows() {
24
23
  return process.platform === "win32";
@@ -35,6 +34,27 @@ function runtimeVenvPath(runtimeRoot) {
35
34
  return path.join(runtimeRoot, ".venv");
36
35
  }
37
36
 
37
+ function runtimeBinDir(runtimeRoot) {
38
+ if (isWindows()) {
39
+ return path.join(runtimeRoot, ".venv", "Scripts");
40
+ }
41
+ return path.join(runtimeRoot, ".venv", "bin");
42
+ }
43
+
44
+ function removeStaleRuntimeEntryPoints(runtimeRoot) {
45
+ const binDir = runtimeBinDir(runtimeRoot);
46
+ const candidates = isWindows()
47
+ ? ["pf.exe", "pf.cmd", "PF.exe", "PF.cmd", "pf-gate.exe", "pf-gate.cmd"]
48
+ : ["pf", "PF", "pf-gate"];
49
+ for (const name of candidates) {
50
+ try {
51
+ fs.rmSync(path.join(binDir, name), { force: true });
52
+ } catch (_error) {
53
+ // best-effort cleanup only.
54
+ }
55
+ }
56
+ }
57
+
38
58
  function runtimePipArgs(runtimeRoot) {
39
59
  return ["-m", "pip"];
40
60
  }
@@ -124,20 +144,13 @@ function sleep(ms) {
124
144
  }
125
145
 
126
146
  function startSphereSpinner(message) {
127
- if (!process.stdout.isTTY) {
128
- return (_doneMessage) => {};
129
- }
130
- let index = 0;
131
- const draw = () => {
132
- const frame = SPHERE_FRAMES[index % SPHERE_FRAMES.length];
133
- process.stdout.write(`\r${frame} ${message}`);
134
- index += 1;
135
- };
136
- draw();
137
- const timer = setInterval(draw, 120);
147
+ if (process.stdout.isTTY) {
148
+ process.stdout.write(`${message}\n`);
149
+ }
138
150
  return (doneMessage = `✓ ${message}`) => {
139
- clearInterval(timer);
140
- process.stdout.write(`\r${doneMessage}\n`);
151
+ if (process.stdout.isTTY && doneMessage) {
152
+ process.stdout.write(`${doneMessage}\n`);
153
+ }
141
154
  };
142
155
  }
143
156
 
@@ -169,17 +182,18 @@ function spawnCapture(command, args, options = {}) {
169
182
  }
170
183
 
171
184
  async function runCommandWithSphereSpinner(command, args, message, options = {}) {
185
+ const { failureMessage, successMessage, ...spawnOptions } = options;
172
186
  const stop = startSphereSpinner(message);
173
- const result = await spawnCapture(command, args, options);
187
+ const result = await spawnCapture(command, args, spawnOptions);
174
188
  if (result.error || (result.status ?? 1) !== 0) {
175
- stop(`✗ ${message}`);
189
+ stop(failureMessage || `… ${message}`);
176
190
  const error =
177
191
  result.error ||
178
192
  new Error(`Command failed (${result.status}): ${command} ${args.join(" ")}`);
179
193
  error.commandOutput = `${String(result.stdout || "")}\n${String(result.stderr || "")}`;
180
194
  throw error;
181
195
  }
182
- stop(`✓ ${message}`);
196
+ stop(successMessage || `✓ ${message}`);
183
197
  return result;
184
198
  }
185
199
 
@@ -659,6 +673,7 @@ async function recreateVirtualenv(runtimeRoot, bootstrapPython) {
659
673
  async function installRuntime(runtimeRoot, source, cliVersion) {
660
674
  const pythonPath = runtimePythonPath(runtimeRoot);
661
675
  const skipPipUpgrade = String(process.env.PF_GATE_SKIP_PIP_UPGRADE || "").trim() === "1";
676
+ removeStaleRuntimeEntryPoints(runtimeRoot);
662
677
  if (!skipPipUpgrade) {
663
678
  await runCommandWithSphereSpinner(
664
679
  pythonPath,
@@ -674,6 +689,7 @@ async function installRuntime(runtimeRoot, source, cliVersion) {
674
689
  "install",
675
690
  "--upgrade",
676
691
  "--force-reinstall",
692
+ "--ignore-installed",
677
693
  source.wheelPath,
678
694
  ],
679
695
  "Installing PF Gate runtime..."
@@ -681,13 +697,27 @@ async function installRuntime(runtimeRoot, source, cliVersion) {
681
697
  } else {
682
698
  await runCommandWithSphereSpinner(
683
699
  pythonPath,
684
- [...runtimePipArgs(runtimeRoot), "install", "--upgrade", source.pipSpec],
700
+ [
701
+ ...runtimePipArgs(runtimeRoot),
702
+ "install",
703
+ "--upgrade",
704
+ "--force-reinstall",
705
+ "--ignore-installed",
706
+ source.pipSpec,
707
+ ],
685
708
  "Installing PF Gate runtime..."
686
709
  );
687
710
  }
688
711
  await runCommandWithSphereSpinner(
689
712
  pythonPath,
690
- [...runtimePipArgs(runtimeRoot), "install", "--upgrade", "prompt_toolkit>=3.0.39"],
713
+ [
714
+ ...runtimePipArgs(runtimeRoot),
715
+ "install",
716
+ "--upgrade",
717
+ "--force-reinstall",
718
+ "--ignore-installed",
719
+ "prompt_toolkit>=3.0.39",
720
+ ],
691
721
  "Installing terminal UX dependencies..."
692
722
  );
693
723
  const fingerprint = desiredStateFingerprint(source, cliVersion);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qpfai/pf-gate-cli",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "PF Gate terminal launcher with first-run runtime bootstrap.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",