flowcollab 0.2.6 → 0.2.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/bin/_client.mjs CHANGED
@@ -54,7 +54,10 @@ function loadGlobalConfig() {
54
54
  }
55
55
  const _gc = loadGlobalConfig();
56
56
 
57
- const DEFAULT_BASE = process.env.FLOW_API_BASE || _gc.apiBase || 'https://flow-production-84b7.up.railway.app';
57
+ // flow-login writes apiBase to ~/.flow/config.json that takes precedence over env so
58
+ // a stale FLOW_API_BASE doesn't silently override the user's server selection.
59
+ // FLOW_API_BASE is still honoured as an explicit override when config.json has no apiBase.
60
+ const DEFAULT_BASE = _gc.apiBase || process.env.FLOW_API_BASE || 'https://flow-production-84b7.up.railway.app';
58
61
 
59
62
  function envToken() {
60
63
  return process.env.FLOW_API_TOKEN_OWNER || process.env.FLOW_API_TOKEN_CONTRIBUTOR || _gc.token || '';
@@ -99,7 +102,9 @@ export async function flowFetch(path, { method = 'GET', body } = {}) {
99
102
  }
100
103
 
101
104
  export const RESOLVED_BASE = DEFAULT_BASE;
102
- export const RESOLVED_ACTOR = process.env.FLOW_DEFAULT_ASSIGNEE || _gc.actorId || '';
105
+ // Prefer config.json actorId (written by flow-login) over env vars.
106
+ // FLOW_DEFAULT_ASSIGNEE is the legacy env name; kept for backwards compat.
107
+ export const RESOLVED_ACTOR = _gc.actorId || process.env.FLOW_DEFAULT_ASSIGNEE || process.env.FLOW_ACTOR || '';
103
108
  export const RESOLVED_PROJECT = process.env.FLOW_PROJECT_ID || _gc.projectId || '';
104
109
  export function resolvedTokenDisplay() {
105
110
  const raw = envToken();
package/bin/create.mjs CHANGED
@@ -93,7 +93,7 @@ async function main() {
93
93
  ...(arg('priority') ? { priority: arg('priority') } : {}),
94
94
  ...(arg('status') ? { status: arg('status') } : {}),
95
95
  ...(arg('assignee') ? { assignee_id: arg('assignee') } : {}),
96
- ...(arg('due') ? { due_at: new Date(arg('due')).toISOString() } : {}),
96
+ ...(arg('due') ? (() => { const d = new Date(arg('due')); if (isNaN(d.getTime())) die(`Invalid --due date: "${arg('due')}". Use YYYY-MM-DD format.`); return { due_at: d.toISOString() }; })() : {}),
97
97
  ...(arg('blocked-by') ? { blocked_by: arg('blocked-by').split(',').map(s => s.trim()).filter(Boolean) } : {}),
98
98
  ...(arg('milestone') ? { milestone: arg('milestone') } : {}),
99
99
  };
package/bin/handoff.mjs CHANGED
@@ -9,10 +9,11 @@
9
9
  flow_files are auto-read from the task and included in handoff_data.
10
10
  */
11
11
 
12
- import { flowFetch, arg } from './_client.mjs';
12
+ import { flowFetch, resolveTaskId, arg } from './_client.mjs';
13
13
 
14
14
  async function main() {
15
- const task_id = arg('task');
15
+ const rawTask = arg('task');
16
+ const task_id = rawTask ? await resolveTaskId(rawTask) : undefined;
16
17
  const to = arg('to');
17
18
  const context = arg('context');
18
19
  const branch = arg('branch') || null;
package/bin/login.mjs CHANGED
@@ -61,8 +61,9 @@ async function main() {
61
61
  process.stdout.write('\n');
62
62
  throw new Error(`Unexpected server response: ${poll.status}. Run flow-login again.`);
63
63
  }
64
- if (poll.ok) {
64
+ if (poll.status === 200) {
65
65
  const { token, actor_id, org_id, api_base } = await poll.json();
66
+ if (!token) throw new Error('Server returned no token. Run flow-login again.');
66
67
  const dir = join(homedir(), '.flow');
67
68
  mkdirSync(dir, { recursive: true });
68
69
  writeFileSync(
package/bin/review.mjs CHANGED
@@ -24,8 +24,15 @@ async function main() {
24
24
 
25
25
  const taskId = await resolveTaskId(rawId);
26
26
 
27
- // Fetch tasks + people in parallel.
28
- const { tasks = [] } = await flowFetch('/api/flow/tasks?limit=500');
27
+ // Fetch all tasks (paginated to handle boards with >500 tasks).
28
+ let tasks = [], cursor = null;
29
+ do {
30
+ const url = `/api/flow/tasks?limit=200${cursor ? '&cursor=' + encodeURIComponent(cursor) : ''}`;
31
+ const page = await flowFetch(url);
32
+ const pageItems = Array.isArray(page) ? page : (page.tasks ?? []);
33
+ tasks = tasks.concat(pageItems);
34
+ cursor = page.has_more ? page.next_cursor : null;
35
+ } while (cursor);
29
36
 
30
37
  const task = tasks.find(t => t.id === taskId);
31
38
  if (!task) die(`Task ${taskId} not found.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowcollab",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Multi-Claude coordination layer — shared task board + CLI for teams running Claude Code",
5
5
  "type": "module",
6
6
  "files": [