flowcollab 0.2.5 → 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 || '';
@@ -76,6 +79,8 @@ export async function flowFetch(path, { method = 'GET', body } = {}) {
76
79
  'content-type': 'application/json',
77
80
  };
78
81
  if (actingViaClaude()) headers['x-flow-acting-via'] = 'claude';
82
+ const org = process.env.FLOW_ORG_ID || _gc.orgId || '';
83
+ if (org) headers['x-flow-org'] = org;
79
84
  const proj = process.env.FLOW_PROJECT_ID || _gc.projectId || '';
80
85
  if (proj) headers['x-flow-project'] = proj;
81
86
 
@@ -97,7 +102,9 @@ export async function flowFetch(path, { method = 'GET', body } = {}) {
97
102
  }
98
103
 
99
104
  export const RESOLVED_BASE = DEFAULT_BASE;
100
- 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 || '';
101
108
  export const RESOLVED_PROJECT = process.env.FLOW_PROJECT_ID || _gc.projectId || '';
102
109
  export function resolvedTokenDisplay() {
103
110
  const raw = envToken();
package/bin/close.mjs CHANGED
@@ -16,7 +16,8 @@ async function main() {
16
16
  body: { task_id: id, ...(summary ? { summary } : {}) },
17
17
  });
18
18
 
19
- process.stdout.write(`Closed #${r.task.id.slice(0, 6)} — "${r.task.title}"\n`);
19
+ const ref = r.task.issue_num != null ? r.task.issue_num : r.task.id.slice(0, 6);
20
+ process.stdout.write(`Closed #${ref} — "${r.task.title}"\n`);
20
21
  }
21
22
 
22
23
  main().catch(e => die(e.message || e));
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/bin/scan.mjs CHANGED
@@ -176,10 +176,11 @@ function printSection(heading, suggestions) {
176
176
 
177
177
  // ── Main ───────────────────────────────────────────────────────────────────────
178
178
  async function main() {
179
- const doTodos = !!arg('todos');
180
- const doIssues = !!arg('issues');
181
- const doPRs = !!arg('prs');
182
- const doSecurity = !!arg('security');
179
+ const argv = process.argv;
180
+ const doTodos = argv.includes('--todos');
181
+ const doIssues = argv.includes('--issues');
182
+ const doPRs = argv.includes('--prs');
183
+ const doSecurity = argv.includes('--security');
183
184
  const all = !doTodos && !doIssues && !doPRs && !doSecurity;
184
185
 
185
186
  const dir = arg('dir') || process.cwd();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowcollab",
3
- "version": "0.2.5",
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": [