pi-freeflow 1.0.5 → 1.0.7

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
@@ -137,17 +137,6 @@ export default {
137
137
  status: response.status,
138
138
  headers: response.headers,
139
139
  });
140
- }
141
- };
142
- ```
143
-
144
- After deploying, register your Cloudflare Worker URL in OMP:
145
- ```text
146
- /freeflow use https://your-worker-name.your-subdomain.workers.dev
147
- ```
148
-
149
- ---
150
-
151
140
  ### 2. Vercel Relay
152
141
  Deploy using the built-in deploy command:
153
142
  ```text
@@ -159,13 +148,20 @@ Deploy using the built-in deploy command:
159
148
 
160
149
  ## 🛠️ Diagnostics & Troubleshooting
161
150
 
151
+ ### Custom Port Configuration
152
+ By default, `pi-freeflow` uses a **Single Shared Port** (`18080`). All concurrent sub-agents automatically share the same master proxy port without spawning redundant servers.
153
+
154
+ To change the base port:
155
+ ```env
156
+ FREEFLOW_PORT=19000
157
+ ```
158
+
162
159
  View live debug logs:
163
160
  ```bash
164
161
  cat ~/.pi/agent/pi-freeflow.log | tail -n 30
165
162
  # or inside OMP:
166
163
  /freeflow logs
167
164
  ```
168
-
169
165
  ---
170
166
 
171
167
  ## 📄 License
@@ -25,7 +25,7 @@ if (!process.env.BANSOS_API_KEY) {
25
25
  const UPSTREAM_OPENCODE = "https://opencode.ai/zen";
26
26
  // KiloCode gateway — OpenAI-compatible; free models are keyless (200 req/hr per IP)
27
27
  const KILO_CHAT_URL = "https://api.kilo.ai/api/gateway/chat/completions";
28
- const PORT = Number(process.env.BANSOS_PORT) || 18080;
28
+ const PORT = Number(process.env.FREEFLOW_PORT || process.env.BANSOS_PORT) || 18080;
29
29
  const HOST = "127.0.0.1";
30
30
  const API = `${UPSTREAM_OPENCODE}/v1`;
31
31
  const OPENCODE_USER_AGENT = "opencode/latest/1.14.50/cli";
@@ -1267,23 +1267,43 @@ function startProxy(
1267
1267
  });
1268
1268
  }
1269
1269
 
1270
- // ── Main extension ─────────────────────────────────────────────────
1271
- export default async function (pi: ExtensionAPI) {
1272
- log("info", "extension loading...");
1273
- let server: http.Server;
1274
- let actualPort: number;
1270
+ // Probe whether an existing freeflow proxy is already running on a port
1271
+ async function isProxyAlive(port: number): Promise<boolean> {
1275
1272
  try {
1276
- const r = await startProxy();
1277
- server = r.server;
1278
- actualPort = r.port;
1273
+ const res = await fetch(`http://${HOST}:${port}/v1/models`, {
1274
+ signal: AbortSignal.timeout(500),
1275
+ });
1276
+ return res.ok;
1279
1277
  } catch {
1280
- log(
1281
- "error",
1282
- "extension inactive — could not bind proxy port. resolve the port conflict and restart pi.",
1283
- );
1284
- return;
1278
+ return false;
1285
1279
  }
1280
+ }
1286
1281
 
1282
+ // ── Main extension ─────────────────────────────────────────────────
1283
+ export default async function (pi: ExtensionAPI) {
1284
+ log("info", "extension loading...");
1285
+ let server: http.Server | null = null;
1286
+ let actualPort = PORT;
1287
+
1288
+ // Single-Port Shared Pattern: If proxy is already running on PORT (e.g. parent session),
1289
+ // subagents reuse http://127.0.0.1:18080 directly without spawning redundant servers!
1290
+ const alreadyRunning = await isProxyAlive(PORT);
1291
+ if (alreadyRunning) {
1292
+ log("info", `reusing existing freeflow proxy on http://${HOST}:${PORT}`);
1293
+ actualPort = PORT;
1294
+ } else {
1295
+ try {
1296
+ const r = await startProxy();
1297
+ server = r.server;
1298
+ actualPort = r.port;
1299
+ } catch {
1300
+ log(
1301
+ "error",
1302
+ "extension inactive — could not bind proxy port. resolve the port conflict and restart pi.",
1303
+ );
1304
+ return;
1305
+ }
1306
+ }
1287
1307
  // Health check opencode models
1288
1308
  log("info", `checking ${KNOWN_MODELS.length} opencode model(s)...`);
1289
1309
  const opencodeChecks = await Promise.all(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-freeflow",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Personal multi-cloud rolling fallback relay for OpenCode Zen and KiloCode models in OMP/Pi",
5
5
  "keywords": [
6
6
  "pi-package",