@zipwire/zw 0.0.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.
Files changed (3) hide show
  1. package/README.md +552 -0
  2. package/bin/cli.js +298 -0
  3. package/package.json +33 -0
package/README.md ADDED
@@ -0,0 +1,552 @@
1
+ # Zipwire CLI (zw)
2
+
3
+ A command-line interface for the Zipwire journaling application. Track time, manage activities, and view your productivity data from the terminal.
4
+
5
+ ## Think of it like Git for Work
6
+
7
+ Just like you use `git` to log your commits, you use `zw` to track your working day. Every entry goes into your private journal, which Zipwire then uses to auto-fill your timesheets – so they're never wrong! The system sends them for approval with a perfect invoice attached.
8
+
9
+ ## What is Zipwire?
10
+
11
+ Zipwire Approve is a timesheet and contractor management system designed for the modern flexible workforce. It solves a fundamental problem: how do you accurately track time, get it approved, and get paid – without the errors and delays that plague traditional timesheet systems?
12
+
13
+ ### The Core Concept
14
+
15
+ **Your Private Journal** → **Auto-filled Timesheets** → **Workflow Approval** → **Automatic Invoicing**
16
+
17
+ 1. **Journal**: You keep a private, detailed record of what you worked on each day. This journal belongs to you and is only visible to you. Track time against activities (like "Company > Project > Task") with notes about what you did.
18
+
19
+ 2. **Timesheets**: When it's time to bill, Zipwire automatically creates timesheets from your journal data. The system applies billing rules (rates, minimums, overtime) to fill out the timesheet correctly – eliminating the common mistakes that cause rejections and invoice rework.
20
+
21
+ 3. **Workflows**: Timesheets flow through approval chains you set up. A manager approves, then it goes to processing. The workflow defines who sees what and when. If your boss is away, a deputy can step in because items go to team inboxes, not individuals. Workflows link activities to billing rates, payment methods, and client invoicing information. They're automatically created when you first submit a timesheet for an unlinked activity, or you can set them up in advance.
22
+
23
+ 4. **Invoicing**: Once approved, Zipwire can automatically generate invoices. Freelancers get invoices to send to agencies, and agencies get invoices to send to clients. No more rekeying data and introducing errors.
24
+
25
+ ### Why It's Different
26
+
27
+ - **Privacy-first**: Your journal is yours. Zipwire only uses it to fill timesheets – you control your data.
28
+ - **Error reduction**: By auto-filling from detailed journal data, timesheets are accurate from the start.
29
+ - **Multi-client support**: Work for multiple clients? Zipwire automatically routes the right time to the right timesheet for the right client.
30
+ - **WhatsApp integration**: Track time and approve timesheets via WhatsApp – no need to open an app.
31
+ - **No passwords**: Use social logins or Ethereum wallet authentication.
32
+
33
+ This CLI gives you command-line access to all of this functionality, making it easy to track time, manage activities, create timesheets, and handle workflows from your terminal.
34
+
35
+ ## Installation
36
+
37
+ ### From Source
38
+
39
+ ```bash
40
+ git clone https://github.com/lukepuplett/zwcli.git
41
+ cd zwcli
42
+ go build -o zw ./cmd/zw
43
+ sudo mv zw /usr/local/bin/
44
+ ```
45
+
46
+ ### Using Go Install
47
+
48
+ ```bash
49
+ go install github.com/lukepuplett/zwcli/cmd/zw@latest
50
+ ```
51
+
52
+ ### Using NPM (Recommended)
53
+
54
+ Install the CLI globally using NPM:
55
+
56
+ ```bash
57
+ npm install -g @zipwire/zw
58
+ ```
59
+
60
+ After installation, the `zw` command will be available in your PATH.
61
+
62
+ **Using npx (No Installation Required):**
63
+
64
+ You can also run the CLI without installing it using npx:
65
+
66
+ ```bash
67
+ npx @zipwire/zw --help
68
+ npx @zipwire/zw activity list
69
+ ```
70
+
71
+ The NPM distribution automatically installs the correct platform-specific binary for your system (Linux, macOS, Windows). For detailed information about the NPM distribution, troubleshooting, and platform support, see [NPM_DISTRIBUTION.md](docs/NPM_DISTRIBUTION.md).
72
+
73
+ ## Quick Start
74
+
75
+ 1. **Set up authentication** (opens browser automatically):
76
+ ```bash
77
+ zw auth login
78
+ ```
79
+
80
+ Or manually with a token:
81
+ ```bash
82
+ zw auth login --token your-api-token
83
+ ```
84
+
85
+ 2. **List your activities** to see what's available:
86
+ ```bash
87
+ zw activity list
88
+ ```
89
+
90
+ 3. **Track your first time entry**:
91
+ ```bash
92
+ zw journal track "Fixed authentication bug" -d 45 --activity "Company > Project > Development"
93
+ ```
94
+
95
+ ## Command Structure
96
+
97
+ The CLI follows the pattern: `zw <noun> <verb> [options]`
98
+
99
+ ### Activity Commands ✅ (Fully Implemented)
100
+
101
+ Manage activities for time tracking. Activities use a hierarchical structure: `Company > Project > Activity`:
102
+
103
+ ```bash
104
+ # List all activities
105
+ zw activity list
106
+
107
+ # Search for activities
108
+ zw activity search "meeting"
109
+ zw activity search "ABC Corp"
110
+
111
+ # Create new activities
112
+ zw activity create "Company > Project > New Feature"
113
+
114
+ # Show recently used activities
115
+ zw activity recent
116
+ zw activity recent --period 2w # Last 2 weeks
117
+
118
+ # Rename/merge activities (consolidate duplicates)
119
+ zw activity rename --from "Old Dev" --from "Dev Work" --to "General > Development"
120
+ zw activity rename --from "abe_jnla_ac71x94j8smyi0fu" --to "ABC Corp > General > Development"
121
+ ```
122
+
123
+ **Activity Types:**
124
+ - **Client Activities**: Require workflow linking before timesheets can be created (e.g., "Acme Corp > Project > Task")
125
+ - **Personal Activities**: Don't require workflows (e.g., "Personal > Learning > Research")
126
+ - **Assigned Activities**: Created by clients/assigners with restricted editing capabilities
127
+
128
+ **Activity-Workflow Relationship:**
129
+ - Activities must be linked to workflows for billing and approval
130
+ - Linking happens automatically when creating timesheets, or manually via workflow commands
131
+ - Unlinked activities will prompt for workflow selection during timesheet creation
132
+ - Activities can be unlinked from workflows if needed (workflows must have no linked activities before deletion)
133
+
134
+ ### Configuration Commands ✅ (Fully Implemented)
135
+
136
+ Manage CLI settings:
137
+
138
+ ```bash
139
+ # View current configuration
140
+ zw config show
141
+
142
+ # Set configuration values
143
+ zw config set no-color true
144
+ zw config set output-format structured
145
+ zw config set work-day-hours 7.5
146
+
147
+ # Authentication
148
+ zw auth login # Web-based authentication (opens browser)
149
+ zw auth login --token <token> # Manual token entry
150
+ zw auth status # Check authentication status
151
+ zw auth logout # Clear stored token
152
+ zw auth set-token <token> # Set token manually (fallback)
153
+ ```
154
+
155
+ ### Journal Commands ✅ (Fully Implemented)
156
+
157
+ Track and manage time entries:
158
+
159
+ ```bash
160
+ # Track time ✅ (IMPLEMENTED)
161
+ zw journal track "Fixed auth bug" -d 45 --activity "Company > Project > Bug Fix"
162
+ zw journal track "Team meeting" -d 30 --activity-key "abe_jnla_ac71x94j8s" # using activity key
163
+ zw journal track "Conference" -d 1d # 8 hours (work day)
164
+ zw journal track "Deep work" -d 2.5h # 2.5 hours
165
+ zw journal track "Project work" -d 2h30m # 2 hours 30 minutes
166
+
167
+ # Track with dates
168
+ zw journal track "Catch up" -d 120 --date "Monday" --activity "Company > Project > Development"
169
+ zw journal track "Review" -d 60 --date "yesterday" --activity-key "abe_jnla_xyz123"
170
+ zw journal track "Planning" -d 90 --date "2024-05-26" --activity "Company > Planning > Sprint Planning"
171
+
172
+ # AI/LLM Analysis Examples
173
+ zw journal list --from "2024-06-01" --to "2024-08-31" --format structured # Summer report data
174
+ zw journal list --activity "Learning" --group-by-week --format structured # Learning progress
175
+ zw activity list --format structured # Activity analysis
176
+
177
+ # Activity suggestions - if you don't specify an activity, you'll get helpful suggestions:
178
+ # ✗ Error tracking: No activity specified. Please choose from recent activities or create a new one.
179
+ #
180
+ # Recent activities you can use:
181
+ # Company > Project > Development [abe_jnla_xyz123] - 2 hours ago
182
+ # Company > Marketing > Blog Writing [abe_jnla_abc456] - 1 day ago
183
+ # Personal > Learning > Research [abe_jnla_def789] - 3 days ago
184
+ #
185
+ # Usage: Use --activity "Display Name" or --activity-key "key"
186
+
187
+ # View entries ✅ (FULLY IMPLEMENTED)
188
+ zw journal list # recent entries (default)
189
+ zw journal list --count 20 # last 20 entries
190
+ zw journal list --today # today's entries
191
+ zw journal list --week # current week
192
+ zw journal list --week 35 # week 35 of current year
193
+ zw journal list --week 2025-W35 # specific week (ISO format)
194
+ zw journal list --from 2025-08-01 --to 2025-08-31 # date range
195
+ zw journal list --group-by-week # group entries by week
196
+ zw journal list --activity "Zipwire > Development" # filter by activity
197
+
198
+ # Show specific entry ✅ (FULLY IMPLEMENTED)
199
+ zw journal show jnla_ac71x94j8s # show specific entry by key
200
+
201
+ # Edit entries ✅ (FULLY IMPLEMENTED)
202
+ zw journal edit jnla_ac71x94j8s --duration 2h30m
203
+ zw journal edit --last --duration 90m --public-note "Updated description"
204
+
205
+ # Delete entries ✅ (FULLY IMPLEMENTED)
206
+ zw journal delete jnla_ac71x94j8s
207
+ zw journal delete --last # delete most recent entry
208
+ ```
209
+
210
+ ### Workflow Commands ✅ (Fully Implemented)
211
+
212
+ Manage workflows for timesheet approval and processing. Workflows define the approval chain, billing rates, and payment methods for your activities:
213
+
214
+ ```bash
215
+ # List available workflows
216
+ zw workflow list
217
+
218
+ # Create approval workflow
219
+ zw workflow create --approve-name "Jane Doe" --approve-email "jane.doe@client.com"
220
+
221
+ # Create two-step workflow (approval + processing)
222
+ zw workflow create --approve-name "Manager" --approve-email "manager@client.com" --process-name "Admin" --process-email "admin@agency.com"
223
+
224
+ # Create workflow with billing information
225
+ zw workflow create --approve-name "Client Manager" --approve-email "manager@client.com" \
226
+ --hourly-rate 75 --currency USD \
227
+ --company-name "Acme Corp" --contact-name "John Smith" \
228
+ --company-address "123 Main St\nNew York, NY 10001"
229
+
230
+ # Link activity to workflow
231
+ zw workflow link --activity "Company > Project > Development" --workflow-key "wf_123"
232
+ zw workflow link --activity-key "abe_jnla_ac71x94j8smyi0fu" --workflow-key "wf_456"
233
+
234
+ # Remove workflow link
235
+ zw workflow unlink --activity "Company > Project > Development"
236
+ zw workflow unlink --activity-key "abe_jnla_ac71x94j8smyi0fu"
237
+
238
+ # Delete workflow (only if no activities are linked)
239
+ zw workflow delete wf_abc123def456
240
+ ```
241
+
242
+ **How Workflows Work:**
243
+ - **Automatic Creation**: When you create a timesheet for an activity without a workflow, the system prompts you to create one or select an existing workflow
244
+ - **Activity Linking**: Activities must be linked to workflows before timesheets can be sent. Personal activities (Company = "Personal") don't require workflows
245
+ - **Billing Integration**: Workflows store hourly rates, currency, and client invoicing information (company name, address, tax codes)
246
+ - **Payment Methods**: Link payment methods to workflows for automatic invoicing
247
+ - **Multi-Step Approval**: Support for simple approval or two-step processes (approval → processing)
248
+ - **Usage Tracking**: Workflows track how many times they've been used and when last used
249
+
250
+ For detailed workflow management documentation, see [TZ_WORKFLOW_MANAGEMENT.md](docs/TZ_WORKFLOW_MANAGEMENT.md).
251
+
252
+ ### Timesheet Commands ✅ (Fully Implemented)
253
+
254
+ Create and manage timesheets from time entries. Timesheets automatically use the workflows linked to your activities:
255
+
256
+ ```bash
257
+ # Create timesheets from unsheeted time entries
258
+ zw timesheet create --from "2024-01-01" --to "2024-01-31"
259
+ zw timesheet create --from "last Monday" --to "last Friday"
260
+ zw timesheet create --from "today" --to "yesterday"
261
+
262
+ # List timesheets with filtering
263
+ zw timesheet list # recent timesheets (default)
264
+ zw timesheet list --count 10 # last 10 timesheets
265
+ zw timesheet list --status draft # only draft timesheets
266
+ zw timesheet list --status sent # only sent timesheets
267
+ zw timesheet list --status done # only completed timesheets
268
+ zw timesheet list --from 2024-01-01 --to 2024-03-31 # date range
269
+ zw timesheet list --page 2 --page-size 5 # pagination
270
+
271
+ # Show specific timesheet details
272
+ zw timesheet show ts_123456 # show timesheet by ID
273
+
274
+ **Detailed Timesheet View Example:**
275
+ ```bash
276
+ ✓ Retrieved timesheet: "Zipwire Development - Week 1" [ID: ts_abc123]
277
+ 📝 Draft → Standard Approval → Waiting for approval
278
+ 2024-01-01 to 2024-01-07 (Week 1)
279
+
280
+ 📅 Daily Breakdown:
281
+
282
+ 🎯 Monday, January 1, 2024 (3 entries)
283
+ 📋 Frontend bug fixes - Zipwire > Development > Bug Fixes (6h 30m) [abe_jnle_abc123]
284
+ 📋 API integration work - Zipwire > Development > Backend (1h 30m) [abe_jnle_def456]
285
+ 8h
286
+
287
+ 🎯 Tuesday, January 2, 2024 (3 entries)
288
+ 📋 Team standup meeting - Zipwire > General > Meetings (2h 30m) [abe_jnle_ghi789]
289
+ 📋 Code review session - Zipwire > Development > Code Review (4h 15m) [abe_jnle_jkl012]
290
+ 📋 Documentation updates - Zipwire > General > Documentation (1h 15m) [abe_jnle_mno345]
291
+ 8h
292
+
293
+ 🎯 Wednesday, January 3, 2024 (0 entries)
294
+ --
295
+
296
+ 38h 30m across 12 entries
297
+ ```
298
+ ```
299
+
300
+ **Timesheet Status Emojis:**
301
+ - 📝 **Draft** - Timesheet is being prepared (unsent)
302
+ - 📤 **Sent** - Timesheet has been sent for processing
303
+ - ✅ **Done** - Timesheet has been completed and processed
304
+ ```
305
+
306
+ **Workflow Integration:**
307
+ - Timesheets automatically use the workflow linked to each activity
308
+ - If an activity has no workflow, you'll be prompted to create or select one during timesheet creation
309
+ - Workflows define the approval chain (who approves, who processes)
310
+ - Billing rates and payment methods from workflows are used for invoicing
311
+ - Timesheets flow through workflow steps: Send → Process (optional) → Approve
312
+
313
+ ### Smart Features ✅
314
+
315
+ The journal track command includes intelligent parsing:
316
+
317
+ **Duration Formats:**
318
+ - `45` or `45m` → 45 minutes
319
+ - `2h` → 2 hours (120 minutes)
320
+ - `1.5h` → 1.5 hours (90 minutes)
321
+ - `1d` → 8 hours (480 minutes, configurable)
322
+ - `2h30m` → 2 hours 30 minutes (150 minutes)
323
+
324
+ **Date Formats:**
325
+ - `today` → current date
326
+ - `yesterday` → previous day
327
+ - `Monday` → most recent Monday
328
+ - `last Monday` → Monday from previous week
329
+ - `2024-05-26` → specific date
330
+ - `May 26` → current year
331
+
332
+ **Configuration:**
333
+ ```bash
334
+ zw config set work-day-hours 7.5 # customize how many hours '1d' represents
335
+ ```
336
+
337
+ **Week Numbers:**
338
+ The CLI uses ISO 8601 week numbering (YYYY-WWW format):
339
+ - Week 1 is the week containing January 4th
340
+ - Weeks start on Monday
341
+ - `2025-W35` = week 35 of 2025
342
+ - `35` = week 35 of current year
343
+ - `W35` = week 35 of current year
344
+
345
+ **List Command Examples:**
346
+ ```bash
347
+ # Basic listing
348
+ zw journal list
349
+ zw journal list --count 20
350
+
351
+ # Time-based filtering
352
+ zw journal list --today
353
+ zw journal list --week 35
354
+ zw journal list --week 2025-W35
355
+
356
+ # Date range filtering
357
+ zw journal list --from "last Monday" --to "Friday"
358
+ zw journal list --from 2025-08-01 --to 2025-08-31
359
+
360
+ # Grouping and filtering
361
+ zw journal list --group-by-week
362
+ zw journal list --activity "Zipwire > Development" --group-by-week
363
+ ```
364
+
365
+ ## Output Formats
366
+
367
+ ### Human-Friendly (Default)
368
+
369
+ ```
370
+ ✓ Created activity: ABC Corp > Development > Testing [act_abc123]
371
+
372
+ 🔄 Consolidating activities...
373
+
374
+ ✓ Merging 3 activities → "General > Development"
375
+ • "Old Dev" (5 entries)
376
+ • "Dev Work" (12 entries)
377
+ • "Development" (8 entries)
378
+
379
+ 25 journal entries updated, 2 duplicate activities removed
380
+ ```
381
+
382
+ ### Structured Format
383
+
384
+ Add `--format structured` to any command for machine-readable output:
385
+
386
+ **Success Response:**
387
+ ```
388
+ STATUS: SUCCESS
389
+ ACTION: activity_create
390
+ ACTIVITY_KEY: act_abc123
391
+ DISPLAY_NAME: ABC Corp > Development > Testing
392
+ COMPANY: ABC Corp
393
+ PROJECT: Development
394
+ ACTIVITY: Testing
395
+ CREATED: 2024-08-25T15:30:00Z
396
+ ```
397
+
398
+ **Error Response with Suggestions:**
399
+ ```
400
+ STATUS: ERROR
401
+ ACTION: journal_track
402
+ ERROR: No activity specified. Please choose from recent activities or create a new one.
403
+ SUGGESTIONS_COUNT: 3
404
+ SUGGESTIONS:
405
+ - ACTIVITY_1_NAME: Company > Project > Development
406
+ ACTIVITY_1_KEY: abe_jnla_xyz123
407
+ ACTIVITY_1_LAST_USED: 2 hours ago
408
+ - ACTIVITY_2_NAME: Company > Marketing > Blog Writing
409
+ ACTIVITY_2_KEY: abe_jnla_abc456
410
+ ACTIVITY_2_LAST_USED: 1 day ago
411
+ USAGE: Use --activity "Display Name" or --activity-key "key"
412
+ ```
413
+
414
+ ## Configuration
415
+
416
+ The CLI stores configuration in `~/.config/zw/config.yaml`. Available settings:
417
+
418
+ - `api-base-url`: Base URL for the Zipwire API
419
+ - `api-token`: API authentication token
420
+ - `no-color`: Disable colored output (true/false)
421
+ - `output-format`: Default output format (human/structured)
422
+ - `work-day-hours`: Hours for '1d' duration (default: 8)
423
+
424
+ ## Global Flags
425
+
426
+ - `--config`: Specify a custom config file path
427
+ - `--no-color`: Disable colored output
428
+ - `--format`: Output format (human or structured)
429
+
430
+ ## Examples
431
+
432
+ ### Complete Workflow Example
433
+
434
+ Here's a typical workflow from time tracking to invoicing:
435
+
436
+ ```bash
437
+ # 1. Authenticate (opens browser automatically)
438
+ zw auth login
439
+
440
+ # 2. Create or find an activity
441
+ zw activity list
442
+ zw activity create "Acme Corp > Website Redesign > Frontend Development"
443
+
444
+ # 3. Set up workflow for billing (if not already created)
445
+ zw workflow create --approve-name "Project Manager" --approve-email "pm@acme.com" \
446
+ --hourly-rate 85 --currency USD \
447
+ --company-name "Acme Corporation" --contact-name "Jane Manager"
448
+
449
+ # 4. Link activity to workflow
450
+ zw workflow link --activity "Acme Corp > Website Redesign > Frontend Development" \
451
+ --workflow-key "wf_abc123"
452
+
453
+ # 5. Track your time
454
+ zw journal track "Implemented responsive navigation" -d 2h30m \
455
+ --activity "Acme Corp > Website Redesign > Frontend Development"
456
+ zw journal track "Code review and fixes" -d 1h15m \
457
+ --activity "Acme Corp > Website Redesign > Frontend Development"
458
+
459
+ # 6. Review your entries
460
+ zw journal list --today
461
+ zw journal list --week
462
+
463
+ # 7. Create timesheet from journal entries
464
+ zw timesheet create --from "last Monday" --to "last Friday"
465
+
466
+ # 8. View timesheet status
467
+ zw timesheet list --status sent
468
+ zw timesheet show ts_abc123
469
+ ```
470
+
471
+ ### Quick Start Example
472
+
473
+ ```bash
474
+ # Authenticate (opens browser automatically)
475
+ zw auth login
476
+
477
+ # Track time (workflow will be created automatically if needed)
478
+ zw journal track "Fixed auth bug" -d 45 --activity "Company > Development"
479
+ zw journal list --today
480
+ ```
481
+
482
+ ## Development Status
483
+
484
+ This CLI currently has **comprehensive real API integration for activities, configuration, and journal tracking**, with advanced activity suggestions and intelligent error handling.
485
+
486
+ ### ✅ What's Working Now:
487
+ - **Activity management** (list, search, create, recent, rename/merge)
488
+ - **Configuration management** and authentication
489
+ - **Journal time tracking** with intelligent activity suggestions
490
+ - **Smart activity selection** - get helpful suggestions when no activity is specified
491
+ - **Workflow management** - create workflows, link activities, manage approval processes
492
+ - **Timesheet management** - create, list, and view timesheets from journal entries
493
+ - **Real API integration** with production data
494
+ - **Advanced activity cleanup** and consolidation features
495
+ - **Dual input support** - both activity keys and display names
496
+ - **Comprehensive error handling** with structured suggestions
497
+ - **Consistent formatting** across human and structured output modes
498
+ - **LLM/AI-friendly data access** - structured output for automated analysis
499
+
500
+ ### 🤖 LLM/AI Integration
501
+
502
+ The CLI is designed to work seamlessly with AI assistants and LLMs for automated reporting and analysis. Instead of building dedicated "stats" features, the CLI provides raw data that AI can analyze:
503
+
504
+ **Example: Generate a Summer Work Report**
505
+ ```bash
506
+ # Get all summer entries in structured format
507
+ zw journal list --from "2024-06-01" --to "2024-08-31" --format structured
508
+
509
+ # Get activity information
510
+ zw activity list --format structured
511
+
512
+ # Get configuration for context
513
+ zw config show --format structured
514
+ ```
515
+
516
+ **AI Analysis Workflow:**
517
+ 1. **Data Collection**: Use structured output to get complete datasets
518
+ 2. **Pattern Analysis**: AI analyzes time patterns, project distribution, learning progress
519
+ 3. **Report Generation**: AI creates comprehensive reports with insights and recommendations
520
+ 4. **Custom Queries**: AI can run specific queries for targeted analysis
521
+
522
+ **Benefits of This Approach:**
523
+ - **No Feature Bloat**: CLI stays focused on data access, not analysis
524
+ - **Flexible Reporting**: AI can generate any type of report or analysis
525
+ - **Real-time Insights**: Always uses current data from the API
526
+ - **Custom Analysis**: AI can perform complex analysis not possible with fixed features
527
+
528
+ ### ✅ Recently Added:
529
+ - **Workflow Management** - Create workflows, link activities, manage approval processes
530
+ - **Timesheet Management** - Create, list, and view timesheets from time entries
531
+ - **Status Emoji System** - Visual indicators for timesheet and journal entry status
532
+
533
+ ## Documentation
534
+
535
+ Additional technical documentation is available in the `docs/` directory:
536
+
537
+ - **[FORMATTING_FUNCTIONS_GUIDE.md](docs/FORMATTING_FUNCTIONS_GUIDE.md)** - Comprehensive reference for all formatting functions and patterns used throughout the CLI
538
+ - **[PLAN_OUTPUT_SAMPLES.md](docs/PLAN_OUTPUT_SAMPLES.md)** - Output samples and test cases for hierout integration
539
+ - **[PROMPTS.md](docs/PROMPTS.md)** - Reflection and documentation prompts for development workflow
540
+ - **[TZ_WORKFLOW_MANAGEMENT.md](docs/TZ_WORKFLOW_MANAGEMENT.md)** - Comprehensive guide to the workflow management system, including activity linking, billing integration, payment methods, and workflow lifecycle
541
+
542
+ ## Contributing
543
+
544
+ 1. Fork the repository
545
+ 2. Create a feature branch
546
+ 3. Make your changes
547
+ 4. Run tests: `go test ./...`
548
+ 5. Submit a pull request
549
+
550
+ ## License
551
+
552
+ MIT License - see LICENSE file for details.
package/bin/cli.js ADDED
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Zipwire CLI Runtime Wrapper
4
+ *
5
+ * Purpose:
6
+ * This JavaScript wrapper serves as the NPM package entry point for the zw CLI.
7
+ * It detects the user's platform, locates the appropriate platform-specific
8
+ * Go binary, and executes it with all command-line arguments.
9
+ *
10
+ * How It Works:
11
+ * 1. Detects platform using Node.js runtime variables (process.platform, process.arch)
12
+ * 2. Maps platform to the corresponding NPM satellite package name
13
+ * 3. Resolves the satellite package location using require.resolve()
14
+ * 4. Constructs the path to the Go binary within the satellite package
15
+ * 5. Spawns the binary process with stdio inheritance for seamless I/O
16
+ * 6. Forwards all command-line arguments and propagates exit codes
17
+ *
18
+ * Platform Mapping:
19
+ * - linux + x64 → @zipwire/zw-linux-amd64
20
+ * - linux + arm64 → @zipwire/zw-linux-arm64
21
+ * - darwin + x64 → @zipwire/zw-darwin-amd64
22
+ * - darwin + arm64 → @zipwire/zw-darwin-arm64
23
+ * - win32 + x64 → @zipwire/zw-windows-amd64
24
+ *
25
+ * Error Handling:
26
+ * - Unsupported platforms: Clear error message with troubleshooting steps
27
+ * - Binary not found: Fallback search in common node_modules locations
28
+ * - Execution failures: Detailed error messages with actionable guidance
29
+ *
30
+ * Stdio Configuration:
31
+ *
32
+ * What is this?
33
+ * The wrapper can use two different methods to handle input/output streams between
34
+ * the Node.js wrapper and the Go binary: 'inherit' (default) or 'pipe' mode.
35
+ *
36
+ * Default Mode ('inherit'):
37
+ * - Directly connects the Go binary's stdin/stdout/stderr to your terminal
38
+ * - Works perfectly for 99% of users and scenarios
39
+ * - Provides seamless I/O with no overhead
40
+ *
41
+ * Pipe Mode ('pipe'):
42
+ * - Manually pipes data between the wrapper and binary through Node.js streams
43
+ * - Use ONLY if you encounter issues with the default mode
44
+ * - When to use:
45
+ * * Older Windows terminals (cmd.exe, older PowerShell) that handle inherited
46
+ * streams poorly, causing garbled output or hanging processes
47
+ * * Specialized terminal emulators with stream compatibility issues
48
+ * * CI/CD environments where inherited streams cause problems
49
+ *
50
+ * Usage:
51
+ * CLI_STDIO_MODE=pipe zw <command>
52
+ *
53
+ * Note: If you're not experiencing any issues, you don't need to set this variable.
54
+ * The default 'inherit' mode is faster and more efficient.
55
+ *
56
+ * Requirements:
57
+ * - Node.js >= 14.0.0
58
+ * - Platform-specific satellite package must be installed
59
+ *
60
+ * This file is executed automatically by NPM when users run the 'zw' command.
61
+ * Users should not need to run this file directly.
62
+ */
63
+
64
+ const { spawn, execSync } = require('child_process');
65
+ const fs = require('fs');
66
+ const path = require('path');
67
+
68
+ const platform = process.platform;
69
+ const arch = process.arch;
70
+
71
+ function getPackageName(platform, arch) {
72
+ const platformMap = {
73
+ 'linux': {
74
+ 'x64': '@zipwire/zw-linux-amd64',
75
+ 'arm64': '@zipwire/zw-linux-arm64'
76
+ },
77
+ 'darwin': {
78
+ 'x64': '@zipwire/zw-darwin-amd64',
79
+ 'arm64': '@zipwire/zw-darwin-arm64'
80
+ },
81
+ 'win32': {
82
+ 'x64': '@zipwire/zw-windows-amd64'
83
+ }
84
+ };
85
+
86
+ if (!platformMap[platform]) {
87
+ return null;
88
+ }
89
+
90
+ return platformMap[platform][arch] || null;
91
+ }
92
+
93
+ function getBinaryName(platform, arch) {
94
+ if (platform === 'win32') {
95
+ return 'zw-windows-amd64.exe';
96
+ }
97
+
98
+ const archMap = {
99
+ 'x64': 'amd64',
100
+ 'arm64': 'arm64'
101
+ };
102
+
103
+ const goArch = archMap[arch] || arch;
104
+ const osMap = {
105
+ 'linux': 'linux',
106
+ 'darwin': 'darwin'
107
+ };
108
+
109
+ const goOs = osMap[platform] || platform;
110
+ return `zw-${goOs}-${goArch}`;
111
+ }
112
+
113
+ function getNpmGlobalPrefix() {
114
+ try {
115
+ return execSync('npm config get prefix', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
116
+ } catch (error) {
117
+ return null;
118
+ }
119
+ }
120
+
121
+ function findBinaryPath(packageName, binaryName) {
122
+ try {
123
+ const packagePath = require.resolve(packageName);
124
+ const packageDir = path.dirname(packagePath);
125
+ const packageJsonPath = path.join(packageDir, 'package.json');
126
+
127
+ if (fs.existsSync(packageJsonPath)) {
128
+ const packageJson = require(packageJsonPath);
129
+ if (packageJson.bin && packageJson.bin.zw) {
130
+ const binPath = path.resolve(packageDir, packageJson.bin.zw);
131
+ if (fs.existsSync(binPath)) {
132
+ return binPath;
133
+ }
134
+ }
135
+ }
136
+
137
+ const binPath = path.join(packageDir, 'bin', binaryName);
138
+ if (fs.existsSync(binPath)) {
139
+ return binPath;
140
+ }
141
+ } catch (error) {
142
+ }
143
+
144
+ const npmPrefix = getNpmGlobalPrefix();
145
+ const fallbackPaths = [
146
+ path.join(process.cwd(), 'node_modules', packageName, 'bin', binaryName),
147
+ path.join(__dirname, '..', 'node_modules', packageName, 'bin', binaryName),
148
+ path.join(process.env.HOME || process.env.USERPROFILE, '.npm-global', 'lib', 'node_modules', packageName, 'bin', binaryName),
149
+ path.join(process.env.APPDATA || '', 'npm', 'node_modules', packageName, 'bin', binaryName)
150
+ ];
151
+
152
+ if (npmPrefix) {
153
+ fallbackPaths.push(path.join(npmPrefix, 'lib', 'node_modules', packageName, 'bin', binaryName));
154
+ }
155
+
156
+ for (const fallbackPath of fallbackPaths) {
157
+ if (fs.existsSync(fallbackPath)) {
158
+ return fallbackPath;
159
+ }
160
+ }
161
+
162
+ if (npmPrefix) {
163
+ try {
164
+ const Module = require('module');
165
+ const nodeModulesPath = path.join(npmPrefix, 'lib', 'node_modules');
166
+ const packagePath = Module._resolveFilename(packageName, { paths: [nodeModulesPath] }, false);
167
+ const packageDir = path.dirname(packagePath);
168
+ const packageJsonPath = path.join(packageDir, 'package.json');
169
+
170
+ if (fs.existsSync(packageJsonPath)) {
171
+ const packageJson = require(packageJsonPath);
172
+ if (packageJson.bin && packageJson.bin.zw) {
173
+ const binPath = path.resolve(packageDir, packageJson.bin.zw);
174
+ if (fs.existsSync(binPath)) {
175
+ return binPath;
176
+ }
177
+ }
178
+ }
179
+
180
+ const binPath = path.join(packageDir, 'bin', binaryName);
181
+ if (fs.existsSync(binPath)) {
182
+ return binPath;
183
+ }
184
+ } catch (error) {
185
+ }
186
+ }
187
+
188
+ return null;
189
+ }
190
+
191
+ function ensureExecutable(binaryPath) {
192
+ if (process.platform === 'win32') {
193
+ return;
194
+ }
195
+
196
+ try {
197
+ fs.accessSync(binaryPath, fs.constants.X_OK);
198
+ } catch (error) {
199
+ try {
200
+ fs.chmodSync(binaryPath, 0o755);
201
+ } catch (chmodError) {
202
+ console.error(`Warning: Could not set executable permissions on ${binaryPath}`);
203
+ }
204
+ }
205
+ }
206
+
207
+ function getStdioMode() {
208
+ const mode = process.env.CLI_STDIO_MODE;
209
+ if (mode === 'pipe') {
210
+ return 'pipe';
211
+ }
212
+ return 'inherit';
213
+ }
214
+
215
+ function setupPipeMode(child) {
216
+ process.stdin.pipe(child.stdin);
217
+ child.stdout.pipe(process.stdout);
218
+ child.stderr.pipe(process.stderr);
219
+
220
+ process.stdin.on('error', () => { });
221
+ child.stdout.on('error', () => { });
222
+ child.stderr.on('error', () => { });
223
+
224
+ process.stdin.on('end', () => {
225
+ if (child.stdin && !child.stdin.destroyed) {
226
+ child.stdin.end();
227
+ }
228
+ });
229
+ }
230
+
231
+ function main() {
232
+ const packageName = getPackageName(platform, arch);
233
+
234
+ if (!packageName) {
235
+ console.error(`Error: Unsupported platform: ${platform} ${arch}`);
236
+ console.error('');
237
+ console.error('Supported platforms:');
238
+ console.error(' - Linux (x64, arm64)');
239
+ console.error(' - macOS (x64, arm64)');
240
+ console.error(' - Windows (x64)');
241
+ console.error('');
242
+ console.error('For manual installation or other platforms, please visit:');
243
+ console.error(' https://github.com/lukepuplett/zwcli');
244
+ process.exit(1);
245
+ }
246
+
247
+ const binaryName = getBinaryName(platform, arch);
248
+ const binaryPath = findBinaryPath(packageName, binaryName);
249
+
250
+ if (!binaryPath) {
251
+ console.error(`Error: Could not find binary for ${packageName}`);
252
+ console.error('');
253
+ console.error('The platform-specific package may not have been installed correctly.');
254
+ console.error('Try reinstalling:');
255
+ console.error(' npm install -g @zipwire/zw');
256
+ console.error('');
257
+ console.error('If the problem persists, please check:');
258
+ console.error(' 1. Node.js version is >= 14.0.0');
259
+ console.error(' 2. NPM installation completed without errors');
260
+ console.error(' 3. Platform-specific package exists in node_modules');
261
+ process.exit(1);
262
+ }
263
+
264
+ if (!fs.existsSync(binaryPath)) {
265
+ console.error(`Error: Binary not found at ${binaryPath}`);
266
+ process.exit(1);
267
+ }
268
+
269
+ ensureExecutable(binaryPath);
270
+
271
+ const args = process.argv.slice(2);
272
+ const stdioMode = getStdioMode();
273
+ const child = spawn(binaryPath, args, {
274
+ stdio: stdioMode,
275
+ shell: false
276
+ });
277
+
278
+ if (stdioMode === 'pipe') {
279
+ setupPipeMode(child);
280
+ }
281
+
282
+ child.on('error', (error) => {
283
+ console.error(`Error executing binary: ${error.message}`);
284
+ if (error.code === 'ENOENT') {
285
+ console.error('The binary file was not found. It may have been deleted or moved.');
286
+ } else if (error.code === 'EACCES') {
287
+ console.error('Permission denied. Try running with appropriate permissions.');
288
+ }
289
+ process.exit(1);
290
+ });
291
+
292
+ child.on('exit', (code) => {
293
+ process.exit(code || 0);
294
+ });
295
+ }
296
+
297
+ main();
298
+
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@zipwire/zw",
3
+ "version": "0.0.1",
4
+ "description": "Zipwire CLI tool for time tracking and activity management",
5
+ "bin": {
6
+ "zw": "bin/cli.js"
7
+ },
8
+ "optionalDependencies": {
9
+ "@zipwire/zw-linux-amd64": "0.0.1",
10
+ "@zipwire/zw-linux-arm64": "0.0.1",
11
+ "@zipwire/zw-darwin-amd64": "0.0.1",
12
+ "@zipwire/zw-darwin-arm64": "0.0.1",
13
+ "@zipwire/zw-windows-amd64": "0.0.1"
14
+ },
15
+ "files": [
16
+ "bin/",
17
+ "package.json"
18
+ ],
19
+ "engines": {
20
+ "node": ">=14.0.0"
21
+ },
22
+ "keywords": [
23
+ "cli",
24
+ "time-tracking",
25
+ "zipwire"
26
+ ],
27
+ "author": "Zipwire",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/lukepuplett/zwcli.git"
32
+ }
33
+ }