open-wadah 1.2.3 → 1.2.4

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
@@ -1,6 +1,15 @@
1
1
  # open-wadah
2
2
 
3
- Open WADAH CLI shared task board for humans and agents. Use it from the terminal or from Cursor, Claude Code, and Kimi.
3
+ Command-line interface for Wadah task boards and autonomous agent workflows.
4
+
5
+ `open-wadah` gives teams and AI agents a fast, scriptable way to plan, assign, and deliver work from the terminal.
6
+
7
+ ## Why teams use Wadah CLI
8
+
9
+ - Manage tasks, assignees, and board flow without leaving your terminal.
10
+ - Automate workflows with stable JSON output for scripts and CI.
11
+ - Power autonomous agents with scoped agent tokens.
12
+ - Keep human and agent work on the same board and process.
4
13
 
5
14
  ## Install
6
15
 
@@ -8,92 +17,135 @@ Open WADAH CLI — shared task board for humans and agents. Use it from the term
8
17
  npm install -g open-wadah
9
18
  ```
10
19
 
11
- Commands: `wadah`, `tm`, `ow` (same CLI).
20
+ Available commands: `wadah`, `ow`, `tm`.
21
+
22
+ ## 60-second quick start
12
23
 
13
- ## Quick start
24
+ 1. Sign in:
14
25
 
15
- 1. API must be reachable (default: `https://api.openwadah.com`). Override: `TASK_MANAGER_API_URL` or `--api <url>`.
16
- 2. Sign in: `wadah login` (browser) or `wadah login --password` (terminal).
17
- 3. Use the board:
26
+ ```bash
27
+ wadah login
28
+ ```
29
+
30
+ 2. Open your assigned tasks:
18
31
 
19
32
  ```bash
20
33
  wadah open
21
- wadah add "Fix login issue"
34
+ ```
35
+
36
+ 3. Create and move work:
37
+
38
+ ```bash
39
+ wadah add "Fix login issue" --board "Main"
40
+ wadah move <task-id> <bucket-id>
22
41
  wadah complete <task-id>
23
42
  ```
24
43
 
25
- ## Commands
44
+ Default API URL is `https://api.openwadah.com`. Override with `--api <url>` or `WADAH_API_URL`.
45
+
46
+ ## Core workflows
26
47
 
27
- | Command | Description |
28
- |--------|-------------|
29
- | **Auth** | `login`, `signup`, `logout`, `whoami` |
30
- | **Tasks** | `open`, `list`, `search`, `requested`, `add`, `complete`, `reopen`, `view`, `update`, `move`, `assign`, `comment`, `subtask list/add/toggle/delete`, `delete` |
31
- | **Relationships** | `add --blocks <id>`, `add --blocked-by <id>`, `update --blocks <id>` |
32
- | **Board** | `boards --json`, `buckets --json`, `assignees --json`; `board create/delete`, `bucket create/update/delete`, `assignee create/update/delete` |
33
- | **Files** | `folders`, `files`, `folder create` / `mkdir`, `upload` |
34
- | **Calendar** | `calendar` (list; `--assignee`, `--task`, `--from`, `--to`), `calendar add`, `calendar update <id>`, `calendar delete <id>` |
35
- | **Docs** | `docs` (list), `doc create [title]`, `doc show <id>`, `doc update <id>`, `doc delete <id>` |
36
- | **Agent tokens** | `agent-tokens` (list), `agent-token create [name]`, `agent-token delete <id>` |
37
- | **Workspace** | `state`, `members`, `invite`, `config` |
38
- | **Other** | `do "<sentence>"` (natural language, needs `OPENAI_API_KEY`), `doctor`, `completion [bash\|zsh]` |
48
+ ### Daily task operations
39
49
 
40
- Run `wadah --help` for full list and options.
50
+ ```bash
51
+ wadah list --board "Main"
52
+ wadah search "billing"
53
+ wadah view <task-id>
54
+ wadah update <task-id> --notes "Root cause + next steps"
55
+ wadah comment <task-id> "Investigating now"
56
+ ```
41
57
 
42
- Subtask examples:
58
+ ### Dependencies and subtasks
43
59
 
44
60
  ```bash
61
+ wadah add "Ship release notes" --blocks <task-id>
45
62
  wadah subtask add <task-id> "Write tests"
46
63
  wadah subtask list <task-id>
47
64
  wadah subtask toggle <task-id> <subtask-id>
48
- wadah subtask delete <task-id> <subtask-id>
49
65
  ```
50
66
 
51
- ## Shell completion
52
-
53
- **Bash:**
67
+ ### Board administration
54
68
 
55
69
  ```bash
56
- wadah completion bash >> ~/.bashrc
57
- source ~/.bashrc
70
+ wadah board create "Backend"
71
+ wadah bucket create "In Review" --board <board-id>
72
+ wadah assignee create "Cursor Agent" --type agent
73
+ wadah buckets --board "Backend" --json
58
74
  ```
59
75
 
60
- **Zsh:**
76
+ ## Command surface
77
+
78
+ | Area | Commands |
79
+ |---|---|
80
+ | Auth | `login`, `signup`, `logout`, `whoami` |
81
+ | Tasks | `open`, `list`, `search`, `requested`, `add`, `view`, `update`, `move`, `assign`, `comment`, `complete`, `reopen`, `delete` |
82
+ | Subtasks | `subtask list`, `subtask add`, `subtask toggle`, `subtask delete` |
83
+ | Boards & members | `boards`, `buckets`, `assignees`, `board create/delete`, `bucket create/update/delete`, `assignee create/update/delete` |
84
+ | Docs | `docs`, `doc create/show/update/delete` |
85
+ | Calendar | `calendar`, `calendar add/update/delete` |
86
+ | Files | `folders`, `files`, `folder create`, `mkdir`, `upload` |
87
+ | Agent tokens | `agent-tokens`, `agent-token create/delete` |
88
+ | Utilities | `doctor`, `completion bash`, `completion zsh`, `state`, `members`, `invite`, `config`, `do` |
89
+
90
+ Use `wadah --help` or `wadah <command> --help` for full flags and examples.
91
+
92
+ ## AI agent mode
93
+
94
+ For autonomous workflows (Cursor, Claude Code, GitHub Actions):
95
+
96
+ - Create an agent token:
61
97
 
62
98
  ```bash
63
- wadah completion zsh >> ~/.zshrc
64
- source ~/.zshrc
99
+ wadah agent-token create "My Agent"
65
100
  ```
66
101
 
67
- ## Agent / AI use
102
+ - Set it as `WADAH_AGENT_TOKEN` in your environment.
103
+ - Use `--json` for deterministic machine output (`wadah open --json`).
104
+ - Optional natural-language command:
105
+
106
+ ```bash
107
+ wadah do "add a task to fix onboarding bug"
108
+ ```
68
109
 
69
- - Set `TASK_MANAGER_TOKEN` (create a token: `wadah agent-token create "My Agent"`).
70
- - Use `--json` for machine-readable output: `wadah open --json`, `wadah list --json`, `wadah buckets --json`.
71
- - Natural language: `wadah do "add a task to fix the bug"` (requires `OPENAI_API_KEY`).
72
- - In Cursor/Claude/Kimi: see **WADAH_CLI.md** in the repo root for a short reference.
73
- - For autonomous 24/7 agents with GitHub Actions: see **AGENTS.md** in the repo root.
110
+ `wadah do` requires `OPENAI_API_KEY`.
74
111
 
75
112
  ## Global flags
76
113
 
77
- - `--api <url>` API base URL
78
- - `--profile <name>` config profile
79
- - `--token <token>` — auth token for this run
80
- - `--json` JSON output
81
- - `--quiet` minimal output
114
+ - `--api <url>`: API base URL
115
+ - `--profile <name>`: config profile
116
+ - `--token <token>`: token for current command only
117
+ - `--json`: machine-readable output
118
+ - `--quiet`: reduce non-essential output
82
119
 
83
- ## Develop & test
120
+ ## Environment variables
84
121
 
85
- From the repo root:
122
+ - `WADAH_AGENT_TOKEN`: preferred auth token for automation
123
+ - `WADAH_API_URL`: override API base URL
124
+ - `OPENAI_API_KEY`: required for `wadah do`
125
+
126
+ ## Shell completion
127
+
128
+ ```bash
129
+ # Bash
130
+ wadah completion bash >> ~/.bashrc && source ~/.bashrc
131
+
132
+ # Zsh
133
+ wadah completion zsh >> ~/.zshrc && source ~/.zshrc
134
+ ```
135
+
136
+ ## Development
86
137
 
87
138
  ```bash
88
- npm run install:all
89
- npm run tm -- --help
90
- cd task-manager-cli && npm test
139
+ npm test
140
+ node cli.js --help
91
141
  ```
92
142
 
93
- ## Error codes (with `--json`)
143
+ ## JSON error codes
144
+
145
+ When running with `--json`, failures include structured error codes:
94
146
 
95
- - `auth_error` — not authenticated
96
- - `validation_error` — bad input
97
- - `network_error` — request failed
98
- - `api_error` — API returned an error
99
- - `config` — missing config (e.g. OPENAI_API_KEY for `do`)
147
+ - `auth_error`
148
+ - `validation_error`
149
+ - `network_error`
150
+ - `api_error`
151
+ - `config`
package/cli.js CHANGED
@@ -31,7 +31,7 @@ function normalizeApiUrl(url) {
31
31
  const conf = new Conf({ projectName: 'open-wadah' })
32
32
 
33
33
  function getProfile() {
34
- const profile = (process.env.TASK_MANAGER_PROFILE ?? runtimeProfile ?? 'default').trim()
34
+ const profile = (process.env.WADAH_PROFILE ?? runtimeProfile ?? 'default').trim()
35
35
  return profile || 'default'
36
36
  }
37
37
 
@@ -55,15 +55,28 @@ function confDelete(key) {
55
55
 
56
56
  function getApiBase() {
57
57
  return (
58
- (process.env.TASK_MANAGER_API_URL ?? '').trim() ||
58
+ (process.env.WADAH_API_URL ?? '').trim() ||
59
59
  runtimeApiBase ||
60
60
  confGet('api_url') ||
61
61
  DEFAULT_API_BASE
62
62
  )
63
63
  }
64
64
 
65
+ /** Agent token from env: reads WADAH_AGENT_TOKEN. */
66
+ function envAgentToken() {
67
+ const w = (process.env.WADAH_AGENT_TOKEN ?? '').trim()
68
+ return w || null
69
+ }
70
+
71
+ /** Which env var supplied the agent token (for status output). */
72
+ function envAgentTokenVarName() {
73
+ if ((process.env.WADAH_AGENT_TOKEN ?? '').trim()) return 'WADAH_AGENT_TOKEN'
74
+ return null
75
+ }
76
+
65
77
  function getAuthToken() {
66
- if (process.env.TASK_MANAGER_TOKEN) return process.env.TASK_MANAGER_TOKEN
78
+ const fromEnv = envAgentToken()
79
+ if (fromEnv) return fromEnv
67
80
  if (runtimeToken) return runtimeToken
68
81
  return confGet('access_token') ?? null
69
82
  }
@@ -99,7 +112,7 @@ async function refreshAccessToken() {
99
112
  }
100
113
 
101
114
  async function ensureAuth() {
102
- if (process.env.TASK_MANAGER_TOKEN) return // agent token, no refresh needed
115
+ if (envAgentToken()) return // agent token, no refresh needed
103
116
  const expires = confGet('token_expires')
104
117
  // Refresh if within 5 minutes of expiry or already expired
105
118
  if (expires && Date.now() > (expires * 1000) - 300_000) {
@@ -120,7 +133,7 @@ async function api(path, options = {}, retry = true) {
120
133
  }
121
134
 
122
135
  // If 401 and we have a refresh token, try once more
123
- if (res.status === 401 && retry && !process.env.TASK_MANAGER_TOKEN) {
136
+ if (res.status === 401 && retry && !envAgentToken()) {
124
137
  const refreshed = await refreshAccessToken()
125
138
  if (refreshed) return api(path, options, false)
126
139
  }
@@ -197,7 +210,7 @@ function handleError(err) {
197
210
  } else if (authLike) {
198
211
  console.error(chalk.red('\n✗ Not authenticated.'))
199
212
  console.error(chalk.gray(' Humans: wadah login'))
200
- console.error(chalk.gray(' Agents: TASK_MANAGER_TOKEN=<token> wadah open\n'))
213
+ console.error(chalk.gray(' Agents: WADAH_AGENT_TOKEN=<token> wadah open\n'))
201
214
  } else if (code === 'network_error') {
202
215
  console.error(chalk.red('\n✗ Network error — could not reach the API.'))
203
216
  console.error(chalk.gray(` Check your connection or API URL: ${getApiBase()}`))
@@ -400,7 +413,7 @@ Available commands and their args (use these exact command names):
400
413
  - buckets: args = []. List columns.
401
414
  - assignees: args = []. List assignees.
402
415
  - state: args = []. Full state JSON.
403
- - move: args = [task id, bucket name or id]. Move task to another column.
416
+ - move: args = [task id, bucket name or id]. Move task to another column. Use --board <name> to move to another board (lands in first column). Add --bucket <name> to specify the column on that board.
404
417
  - assign: args = [task id, "--to", "assignee[,assignee2]", "--mode", "set|add|remove"]. Assign one or more people.
405
418
  - whoami: args = []. Show current user/workspace.
406
419
  - folders: args = []. List folders.
@@ -738,7 +751,7 @@ program
738
751
  .action(async () => {
739
752
  if (isMachineOutput()) {
740
753
  try {
741
- if (process.env.TASK_MANAGER_TOKEN || runtimeToken) {
754
+ if (envAgentToken() || runtimeToken) {
742
755
  const me = await api('/api/auth/me')
743
756
  const ws = me.workspaces?.[0] ?? null
744
757
  console.log(JSON.stringify({
@@ -771,8 +784,8 @@ program
771
784
  return
772
785
  }
773
786
 
774
- if (process.env.TASK_MANAGER_TOKEN) {
775
- console.log(chalk.bold('\nAgent') + ' (TASK_MANAGER_TOKEN)')
787
+ if (envAgentToken()) {
788
+ console.log(chalk.bold('\nAgent') + ` (${envAgentTokenVarName()})`)
776
789
  } else {
777
790
  const email = confGet('user_email')
778
791
  if (!email) {
@@ -1089,11 +1102,49 @@ program
1089
1102
  })
1090
1103
 
1091
1104
  program
1092
- .command('move <id> <bucket>')
1093
- .description('Move a task to another column')
1094
- .action(async (id, bucketQuery) => {
1105
+ .command('move <id> [bucket]')
1106
+ .description('Move a task to another column or board')
1107
+ .option('--board <name>', 'Target board (name or id)')
1108
+ .option('--bucket <name>', 'Target column on that board (defaults to first column)')
1109
+ .action(async (id, bucketArg, opts) => {
1095
1110
  try {
1096
1111
  const state = await getState()
1112
+
1113
+ // --board flag: resolve board then pick column
1114
+ if (opts.board) {
1115
+ const boardQuery = opts.board.toLowerCase()
1116
+ const board = state.boards.find((b) => b.id === opts.board || b.name.toLowerCase().includes(boardQuery))
1117
+ if (!board) return fail(`Board not found: ${opts.board}`)
1118
+
1119
+ const boardBuckets = state.buckets
1120
+ .filter((b) => b.boardId === board.id)
1121
+ .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
1122
+ if (boardBuckets.length === 0) return fail(`Board "${board.name}" has no columns`)
1123
+
1124
+ let bucket
1125
+ if (opts.bucket) {
1126
+ const bq = opts.bucket.toLowerCase()
1127
+ bucket = boardBuckets.find((b) => b.id === opts.bucket || b.title.toLowerCase().includes(bq))
1128
+ if (!bucket) return fail(`Column "${opts.bucket}" not found on board "${board.name}"`)
1129
+ } else if (bucketArg) {
1130
+ const bq = bucketArg.toLowerCase()
1131
+ bucket = boardBuckets.find((b) => b.id === bucketArg || b.title.toLowerCase().includes(bq))
1132
+ if (!bucket) return fail(`Column "${bucketArg}" not found on board "${board.name}"`)
1133
+ } else {
1134
+ bucket = boardBuckets[0]
1135
+ }
1136
+
1137
+ const task = await api(`/api/tasks/${id}`, {
1138
+ method: 'PATCH',
1139
+ body: JSON.stringify({ bucketId: bucket.id, boardId: board.id }),
1140
+ })
1141
+ console.log(chalk.green('\n✓ Moved') + ` ${chalk.bold(task.title)} → ${board.name} / ${bucket.title}\n`)
1142
+ return
1143
+ }
1144
+
1145
+ // positional bucket arg (original behaviour — cross-board if bucket is on another board)
1146
+ const bucketQuery = bucketArg ?? opts.bucket
1147
+ if (!bucketQuery) return fail('Provide a column name/id, or use --board <name>')
1097
1148
  const bucket = findBucket(state.buckets, bucketQuery)
1098
1149
  if (!bucket) return fail(`Bucket not found: ${bucketQuery}`)
1099
1150
  const patch = { bucketId: bucket.id }
@@ -1471,13 +1522,42 @@ const boardCmd = program.command('board').description('Create or delete a board
1471
1522
  boardCmd
1472
1523
  .command('create <name>')
1473
1524
  .description('Create a new board')
1474
- .action(async (name) => {
1525
+ .option('--flow <columns>', 'Comma-separated column flow, e.g. "Backlog,Ready,Doing,QA,Done"')
1526
+ .action(async function (name) {
1475
1527
  try {
1528
+ const opts = this.opts()
1476
1529
  const board = await api('/api/boards', { method: 'POST', body: JSON.stringify({ name: String(name).trim() }) })
1530
+ const createdBuckets = []
1531
+ if (opts.flow) {
1532
+ const flowColumns = String(opts.flow)
1533
+ .split(',')
1534
+ .map((c) => c.trim())
1535
+ .filter(Boolean)
1536
+ if (flowColumns.length === 0) {
1537
+ return fail('Flow is empty. Provide comma-separated columns, e.g. --flow "Backlog,Doing,Done".')
1538
+ }
1539
+ for (const column of flowColumns) {
1540
+ if (!column) continue
1541
+ const bucket = await api('/api/buckets', {
1542
+ method: 'POST',
1543
+ body: JSON.stringify({ title: column, boardId: board.id }),
1544
+ })
1545
+ createdBuckets.push(bucket)
1546
+ }
1547
+ }
1477
1548
  if (isMachineOutput()) {
1478
- console.log(JSON.stringify(board, null, runtimeJsonOutput ? 2 : 0))
1549
+ console.log(JSON.stringify(
1550
+ { ...board, flow: createdBuckets.map((b) => ({ id: b.id, title: b.title })) },
1551
+ null,
1552
+ runtimeJsonOutput ? 2 : 0
1553
+ ))
1479
1554
  } else {
1480
1555
  console.log(chalk.green('\n✓ Board created') + ` ${chalk.bold(board.name)} ${chalk.gray(board.id?.slice(0, 8))}\n`)
1556
+ if (createdBuckets.length > 0) {
1557
+ console.log(chalk.gray(' Flow columns:'))
1558
+ createdBuckets.forEach((b) => console.log(` - ${b.title} ${chalk.gray(b.id?.slice(0, 8))}`))
1559
+ console.log()
1560
+ }
1481
1561
  }
1482
1562
  } catch (err) { handleError(err) }
1483
1563
  })
@@ -1858,7 +1938,7 @@ const agentTokenCmd = program.command('agent-token').description('Create or dele
1858
1938
 
1859
1939
  agentTokenCmd
1860
1940
  .command('create [name]')
1861
- .description('Create an agent token; token is shown once — store it as TASK_MANAGER_TOKEN')
1941
+ .description('Create an agent token; token is shown once — store it as WADAH_AGENT_TOKEN')
1862
1942
  .option('--name <text>', 'Token name (if not passed as argument)')
1863
1943
  .option('--assignee-name <text>', 'Display name for the agent (default: same as name)')
1864
1944
  .action(async function (nameArg) {
@@ -1876,9 +1956,9 @@ agentTokenCmd
1876
1956
  console.log(chalk.yellow('\n Token (store it now — shown once):'))
1877
1957
  console.log(` ${result.token}`)
1878
1958
  console.log(chalk.gray('\n Store it so you don’t lose it:'))
1879
- console.log(chalk.gray(' · GitHub Actions: Repo → Settings → Secrets and variables → Actions → New secret → TASK_MANAGER_TOKEN'))
1880
- console.log(chalk.gray(' · Cursor: Settings → Environment variables → TASK_MANAGER_TOKEN'))
1881
- console.log(chalk.gray(' · Shell: export TASK_MANAGER_TOKEN="<paste token here>"\n'))
1959
+ console.log(chalk.gray(' · GitHub Actions: Repo → Settings → Secrets and variables → Actions → New secret → WADAH_AGENT_TOKEN'))
1960
+ console.log(chalk.gray(' · Cursor: Settings → Environment variables → WADAH_AGENT_TOKEN'))
1961
+ console.log(chalk.gray(' · Shell: export WADAH_AGENT_TOKEN="<paste token here>"\n'))
1882
1962
  }
1883
1963
  } catch (err) { handleError(err) }
1884
1964
  })
@@ -2202,12 +2282,12 @@ program
2202
2282
  addCheck('api_ping', 'fail', `API ping failed: ${err.message}`)
2203
2283
  }
2204
2284
 
2205
- const hasEnvToken = Boolean(process.env.TASK_MANAGER_TOKEN || runtimeToken)
2285
+ const hasEnvToken = Boolean(envAgentToken() || runtimeToken)
2206
2286
  const hasSavedToken = Boolean(confGet('access_token'))
2207
2287
  if (!hasEnvToken && !hasSavedToken) {
2208
2288
  addCheck('auth_token', 'warn', 'No token available. Run wadah login.')
2209
2289
  } else if (hasEnvToken) {
2210
- addCheck('auth_token', 'pass', 'Using agent token from env/flag (TASK_MANAGER_TOKEN)')
2290
+ addCheck('auth_token', 'pass', `Using agent token from env/flag (${envAgentTokenVarName()})`)
2211
2291
  } else {
2212
2292
  addCheck('auth_token', 'pass', 'Using token from profile config')
2213
2293
  }
@@ -2233,7 +2313,7 @@ program
2233
2313
  addCheck('auth_me', 'warn', `Auth check failed: ${err.message}`)
2234
2314
  }
2235
2315
 
2236
- // Agent-specific checks (only when TASK_MANAGER_TOKEN is set)
2316
+ // Agent-specific checks (only when an env agent token is set)
2237
2317
  if (hasEnvToken && meBody) {
2238
2318
  const isAgent = meBody.workspaces?.[0]?.role === 'agent'
2239
2319
  if (!isAgent) {
@@ -2359,7 +2439,7 @@ program
2359
2439
  const config = {
2360
2440
  api_url: getApiBase(),
2361
2441
  signed_in_as: confGet('user_email') ?? null,
2362
- agent_mode: Boolean(process.env.TASK_MANAGER_TOKEN || runtimeToken),
2442
+ agent_mode: Boolean(envAgentToken() || runtimeToken),
2363
2443
  profile: getProfile(),
2364
2444
  default_board: defaultBoard ?? null,
2365
2445
  config_file: conf.path,
@@ -2372,7 +2452,7 @@ program
2372
2452
  console.log(chalk.bold('CLI config'))
2373
2453
  console.log(chalk.gray(` API URL: ${config.api_url}`))
2374
2454
  console.log(chalk.gray(` Signed in as: ${config.signed_in_as ?? '—'}`))
2375
- console.log(chalk.gray(` Agent mode: ${config.agent_mode ? 'yes (TASK_MANAGER_TOKEN set)' : 'no'}`))
2455
+ console.log(chalk.gray(` Agent mode: ${config.agent_mode ? `yes (${envAgentTokenVarName() ?? 'token flag'} set)` : 'no'}`))
2376
2456
  console.log(chalk.gray(` Default board: ${defaultBoard ?? '— (not set, use: wadah config --default-board "Name")'}`))
2377
2457
  console.log(chalk.gray(` Profile: ${getProfile()}`))
2378
2458
  console.log(chalk.gray(` Config file: ${config.config_file}`))
@@ -2461,7 +2541,7 @@ program
2461
2541
  .description('Interactive wizard: create an agent token, write it to your shell profile, and verify everything works')
2462
2542
  .option('--name <name>', 'Agent name (skip prompt)')
2463
2543
  .option('--board <board>', 'Default board name (skip prompt)')
2464
- .option('--skip-env', 'Skip writing TASK_MANAGER_TOKEN to shell profile (print instructions only)')
2544
+ .option('--skip-env', 'Skip writing WADAH_AGENT_TOKEN to shell profile (print instructions only)')
2465
2545
  .action(async (opts) => {
2466
2546
  const readline = await import('node:readline/promises')
2467
2547
  const os = await import('node:os')
@@ -2525,18 +2605,18 @@ program
2525
2605
 
2526
2606
  // Step 4: write env var to shell profile
2527
2607
  console.log()
2528
- console.log(chalk.bold('Step 4/5 Setting up TASK_MANAGER_TOKEN…'))
2608
+ console.log(chalk.bold('Step 4/5 Setting up WADAH_AGENT_TOKEN…'))
2529
2609
 
2530
2610
  const shell = process.env.SHELL ?? ''
2531
2611
  const profileMap = { zsh: '.zshrc', bash: '.bashrc', fish: '.config/fish/config.fish' }
2532
2612
  const profileKey = Object.keys(profileMap).find((k) => shell.includes(k))
2533
2613
  const profileFile = profileKey ? path.join(os.homedir(), profileMap[profileKey]) : null
2534
2614
  const marker = '# added by wadah setup-agent'
2535
- const exportLine = `\nexport TASK_MANAGER_TOKEN="${rawToken}" ${marker}\n`
2615
+ const exportLine = `\nexport WADAH_AGENT_TOKEN="${rawToken}" ${marker}\n`
2536
2616
 
2537
2617
  if (opts.skipEnv || !profileFile) {
2538
2618
  console.log(chalk.gray(' Skipping automatic profile write. Add this line manually:'))
2539
- console.log(chalk.gray(` export TASK_MANAGER_TOKEN="${rawToken}"`))
2619
+ console.log(chalk.gray(` export WADAH_AGENT_TOKEN="${rawToken}"`))
2540
2620
  const rcGuess = shell.includes('zsh') ? '~/.zshrc' : shell.includes('fish') ? '~/.config/fish/config.fish' : '~/.bashrc'
2541
2621
  console.log(chalk.gray(` Then reload: source ${rcGuess}`))
2542
2622
  } else {
@@ -2546,7 +2626,7 @@ program
2546
2626
  const existing = fs.existsSync(profileFile) ? fs.readFileSync(profileFile, 'utf8') : ''
2547
2627
  const filtered = existing
2548
2628
  .split('\n')
2549
- .filter((line) => !line.includes('TASK_MANAGER_TOKEN=') && !line.includes(marker))
2629
+ .filter((line) => !line.includes('WADAH_AGENT_TOKEN=') && !line.includes(marker))
2550
2630
  .join('\n')
2551
2631
  const next = `${filtered.trimEnd()}${exportLine}`
2552
2632
  fs.writeFileSync(profileFile, `${next.endsWith('\n') ? next : `${next}\n`}`)
@@ -2554,10 +2634,10 @@ program
2554
2634
  console.log(chalk.gray(` Reload now: source ${profileFile}`))
2555
2635
  } catch (e) {
2556
2636
  console.log(chalk.yellow(` ⚠ Could not write to ${profileFile}: ${e.message}`))
2557
- console.log(chalk.gray(` Add manually: export TASK_MANAGER_TOKEN="${rawToken}"`))
2637
+ console.log(chalk.gray(` Add manually: export WADAH_AGENT_TOKEN="${rawToken}"`))
2558
2638
  }
2559
2639
  } else {
2560
- console.log(chalk.gray(` Skipped. Add manually: export TASK_MANAGER_TOKEN="${rawToken}"`))
2640
+ console.log(chalk.gray(` Skipped. Add manually: export WADAH_AGENT_TOKEN="${rawToken}"`))
2561
2641
  }
2562
2642
  }
2563
2643
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-wadah",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Open Wadah CLI — shared task board for humans and agents",
5
5
  "type": "module",
6
6
  "bin": {
package/test/cli.test.js CHANGED
@@ -11,7 +11,7 @@ function runCli(args) {
11
11
  return new Promise((resolvePromise, reject) => {
12
12
  const child = spawn(process.execPath, [cliPath, ...args], {
13
13
  stdio: ['ignore', 'pipe', 'pipe'],
14
- env: { ...process.env, TASK_MANAGER_TOKEN: '' },
14
+ env: { ...process.env, WADAH_AGENT_TOKEN: '' },
15
15
  })
16
16
  let stdout = ''
17
17
  let stderr = ''