pipe-kan 0.34.0 → 0.34.1

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
@@ -63,6 +63,8 @@ bunx pipe-kan --plane --projects APH,PULSE,PKAN,PUI,DEC
63
63
 
64
64
  Same `--projects` style as Jira: comma-separated, trimmed, uppercased. CLI flags are startup defaults. The sidebar switcher (O then W) checks Sources, Workspaces, and Projects and refreshes the merged Board. The header project chip opens that same menu. Scope flags still round-trip the selection. Next launch uses argv, else `PLANE_WORKSPACE`, else `personal`.
65
65
 
66
+ Workspace discovery: Plane's public v1 API has no workspace-list endpoint, so the switcher lists every workspace the key can read by probing candidate slugs (startup flags, `PLANE_WORKSPACE`, `PLANE_WORKSPACES`, `PIPE_KAN_WORKSPACES`, plus `personal` and `work`) regardless of the startup scope. The startup flags bar is hidden by default; Display > Show startup flags bar brings it back.
67
+
66
68
  Plane mode adds Initiatives and Projects. Initiatives are modules (health, status, priority, target date) in a list, board, or timeline. Projects show completion, target date, and health. Display is Shift+V. The Filter menu (F) adds view filters, chips, and saved views. Right-click a row for status, assignee, priority, labels, or copy link. Cmd+K jumps to those views; `ow` lists workspaces.
67
69
 
68
70
  When more than one Workspace is selected, issue keys are `workspace/KEY` so `work/PULSE` and `personal/PULSE` stay distinct. Catalog reads are serialized, cached, and keep trailing slashes.
package/dist/pipe-kan.js CHANGED
@@ -1841,6 +1841,7 @@ function sourceOptions(input) {
1841
1841
  // src/plane.ts
1842
1842
  var DEFAULT_PLANE_HOST = "https://plane.tail48fe8.ts.net";
1843
1843
  var DEFAULT_PLANE_WORKSPACE = "personal";
1844
+ var COMMON_WORKSPACE_SLUGS = ["personal", "work"];
1844
1845
  var STATE_GROUPS = ["backlog", "unstarted", "started", "completed", "cancelled"];
1845
1846
  function planeHost(env = process.env) {
1846
1847
  return (env.PLANE_HOST ?? DEFAULT_PLANE_HOST).replace(/\/$/, "");
@@ -2217,6 +2218,35 @@ function createPlaneCli(opts) {
2217
2218
  return;
2218
2219
  return { id: asString(row?.id) ?? slug, name: asString(row?.name) ?? slug, slug };
2219
2220
  }
2221
+ const known = new Set;
2222
+ async function probeWorkspaces() {
2223
+ const env = opts.env ?? process.env;
2224
+ const fromFlags = parseFlags(`${defaultFlags} ${lastFlags}`);
2225
+ const candidates = new Set([
2226
+ ...known,
2227
+ ...fromFlags.workspaces,
2228
+ ...fromFlags.workspace ? [fromFlags.workspace] : [],
2229
+ ...fromFlags.scopes.map((scope) => scope.workspace),
2230
+ ...env.PLANE_WORKSPACE ? [env.PLANE_WORKSPACE] : [],
2231
+ ...(env.PLANE_WORKSPACES ?? "").split(","),
2232
+ ...(env.PIPE_KAN_WORKSPACES ?? "").split(","),
2233
+ ...COMMON_WORKSPACE_SLUGS
2234
+ ]);
2235
+ const found = [];
2236
+ for (const raw of candidates) {
2237
+ const slug = raw.trim();
2238
+ if (!slug || !/^[A-Za-z0-9_-]+$/.test(slug))
2239
+ continue;
2240
+ try {
2241
+ await requestJson(queryPath(`/workspaces/${slug}/projects/`, { per_page: "1" }));
2242
+ known.add(slug);
2243
+ found.push({ id: slug, name: slug, slug });
2244
+ } catch {
2245
+ known.delete(slug);
2246
+ }
2247
+ }
2248
+ return found;
2249
+ }
2220
2250
  function parseWorkspaceList(raw) {
2221
2251
  const rows = Array.isArray(raw) ? raw : asRecord(raw)?.results;
2222
2252
  if (!Array.isArray(rows))
@@ -2562,15 +2592,12 @@ function createPlaneCli(opts) {
2562
2592
  async listWorkspaces() {
2563
2593
  for (const path of ["/users/me/workspaces/", "/workspaces/"]) {
2564
2594
  try {
2565
- return parseWorkspaceList(await requestJson(path)) ?? [];
2566
- } catch (err) {
2567
- const status = err.status;
2568
- if (status === 404 && path === "/users/me/workspaces/")
2569
- continue;
2570
- return [];
2571
- }
2595
+ const listed = parseWorkspaceList(await requestJson(path));
2596
+ if (listed?.length)
2597
+ return listed;
2598
+ } catch {}
2572
2599
  }
2573
- return [];
2600
+ return probeWorkspaces();
2574
2601
  },
2575
2602
  async listProjectIdentifiers(workspace) {
2576
2603
  const slug = workspace.trim();
@@ -2740,6 +2767,7 @@ async function createBoardApp(opts) {
2740
2767
  apiKey: env.PLANE_API_KEY ?? "",
2741
2768
  workspace: planeWorkspace(flags, env),
2742
2769
  flags,
2770
+ env,
2743
2771
  fetch: opts.fetch ?? resolvePlaneFetch(env)
2744
2772
  }) : useJira ? createJiraCli({
2745
2773
  bin,