pipe-kan 0.34.1 → 0.34.2

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/dist/pipe-kan.js CHANGED
@@ -2219,7 +2219,16 @@ function createPlaneCli(opts) {
2219
2219
  return { id: asString(row?.id) ?? slug, name: asString(row?.name) ?? slug, slug };
2220
2220
  }
2221
2221
  const known = new Set;
2222
+ let probeCache;
2222
2223
  async function probeWorkspaces() {
2224
+ const ttl = opts.cacheTtlMs ?? 300000;
2225
+ if (ttl > 0 && probeCache && nowFn() - probeCache.at < ttl)
2226
+ return probeCache.rows;
2227
+ const rows = await probeWorkspacesUncached();
2228
+ probeCache = { at: nowFn(), rows };
2229
+ return rows;
2230
+ }
2231
+ async function probeWorkspacesUncached() {
2223
2232
  const env = opts.env ?? process.env;
2224
2233
  const fromFlags = parseFlags(`${defaultFlags} ${lastFlags}`);
2225
2234
  const candidates = new Set([
@@ -2232,20 +2241,20 @@ function createPlaneCli(opts) {
2232
2241
  ...(env.PIPE_KAN_WORKSPACES ?? "").split(","),
2233
2242
  ...COMMON_WORKSPACE_SLUGS
2234
2243
  ]);
2235
- const found = [];
2236
- for (const raw of candidates) {
2244
+ const results = await Promise.all([...candidates].map(async (raw) => {
2237
2245
  const slug = raw.trim();
2238
2246
  if (!slug || !/^[A-Za-z0-9_-]+$/.test(slug))
2239
- continue;
2247
+ return;
2240
2248
  try {
2241
2249
  await requestJson(queryPath(`/workspaces/${slug}/projects/`, { per_page: "1" }));
2242
2250
  known.add(slug);
2243
- found.push({ id: slug, name: slug, slug });
2251
+ return { id: slug, name: slug, slug };
2244
2252
  } catch {
2245
2253
  known.delete(slug);
2254
+ return;
2246
2255
  }
2247
- }
2248
- return found;
2256
+ }));
2257
+ return results.filter((row) => Boolean(row));
2249
2258
  }
2250
2259
  function parseWorkspaceList(raw) {
2251
2260
  const rows = Array.isArray(raw) ? raw : asRecord(raw)?.results;
@@ -2320,7 +2329,7 @@ function createPlaneCli(opts) {
2320
2329
  };
2321
2330
  }
2322
2331
  const projectCache = new Map;
2323
- const cacheTtlMs = opts.cacheTtlMs ?? 30000;
2332
+ const cacheTtlMs = opts.cacheTtlMs ?? 300000;
2324
2333
  async function projectsFor(slug) {
2325
2334
  const hit = projectCache.get(slug);
2326
2335
  const now = nowFn();
@@ -2590,6 +2599,9 @@ function createPlaneCli(opts) {
2590
2599
  return loaded.columns;
2591
2600
  },
2592
2601
  async listWorkspaces() {
2602
+ const ttl = opts.cacheTtlMs ?? 300000;
2603
+ if (ttl > 0 && probeCache && nowFn() - probeCache.at < ttl)
2604
+ return probeCache.rows;
2593
2605
  for (const path of ["/users/me/workspaces/", "/workspaces/"]) {
2594
2606
  try {
2595
2607
  const listed = parseWorkspaceList(await requestJson(path));
@@ -14200,9 +14212,15 @@ function handleRequest(req, res, ctx) {
14200
14212
  if (handleAppApi(req, res, ctx.app, { kind: ctx.kind, env: ctx.env, onSource: ctx.switchSource }) || handleAgentApi(req, res, ctx.app)) {
14201
14213
  return true;
14202
14214
  }
14203
- if (ctx.kind === "plane")
14204
- return false;
14205
- return handleFakeJira(req, res, ctx.store);
14215
+ if (ctx.kind !== "plane" && handleFakeJira(req, res, ctx.store))
14216
+ return true;
14217
+ if ((req.url ?? "").split("?")[0].startsWith("/api/")) {
14218
+ res.statusCode = 404;
14219
+ res.setHeader("content-type", "application/json");
14220
+ res.end(JSON.stringify({ error: "unknown API route" }));
14221
+ return true;
14222
+ }
14223
+ return false;
14206
14224
  }
14207
14225
 
14208
14226
  // src/jira-config.ts
@@ -14343,12 +14361,12 @@ async function runServer(opts) {
14343
14361
  live.store = next.store;
14344
14362
  live.kind = next.kind;
14345
14363
  if (next.kind === "plane" || next.kind === "jira") {
14346
- try {
14347
- await refreshFromJira(live.app, next.kind);
14348
- } catch (err) {
14349
- const message = err instanceof Error ? err.message : String(err);
14350
- return { ok: true, kind: live.kind, source, error: message };
14351
- }
14364
+ const app = live.app;
14365
+ const kind = next.kind;
14366
+ refreshFromJira(app, kind).catch((err) => {
14367
+ console.error(`${kind} Refresh after source switch failed`, err);
14368
+ });
14369
+ return { ok: true, kind: live.kind, source, refreshing: true };
14352
14370
  }
14353
14371
  return { ok: true, kind: live.kind, source };
14354
14372
  } catch (err) {
@@ -14368,20 +14386,17 @@ async function runServer(opts) {
14368
14386
  res.end("pipe-kan UI is missing. Run bun run build.");
14369
14387
  }
14370
14388
  });
14371
- if (live.kind === "plane") {
14372
- try {
14373
- await refreshFromJira(live.app, live.kind, { piped: Boolean(piped) });
14374
- } catch (err) {
14375
- console.error(`${live.kind} Refresh failed`, err);
14376
- }
14377
- const error = live.app.board().error;
14378
- if (error)
14379
- console.error(`${live.kind} Refresh failed; keeping last live Board`, error);
14380
- }
14381
14389
  const { host, port } = resolveListen();
14382
14390
  await bindListen(server, host, port);
14383
14391
  const origin = `http://127.0.0.1:${port}`;
14384
14392
  announce(`pipe-kan http://${host}:${port}`);
14393
+ if (live.kind === "plane") {
14394
+ refreshFromJira(live.app, live.kind, { piped: Boolean(piped) }).catch((err) => console.error(`${live.kind} Refresh failed`, err)).then(() => {
14395
+ const error = live.app.board().error;
14396
+ if (error)
14397
+ console.error(`${live.kind} Refresh failed; keeping last live Board`, error);
14398
+ });
14399
+ }
14385
14400
  if (live.kind === "plane") {
14386
14401
  announce(`cli plane ${planeHost()} ${planeWorkspace(flags)}`);
14387
14402
  announce(`Plane host default ${DEFAULT_PLANE_HOST}`);