ticketlens 0.4.5 → 0.4.6

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.
@@ -284,8 +284,9 @@ switch (command) {
284
284
  const result = await runScheduleWizard({ answers, cliToken: readCliToken() });
285
285
  if (!result.ok) { process.exitCode = 1; break; }
286
286
 
287
- process.stdout.write(`✔ Digest scheduled for ${answers.time} ${answers.timezone}\n`);
288
- process.stdout.write(` Next delivery: ${result.nextDelivery}\n`);
287
+ const s = createStyler({ isTTY: process.stdout.isTTY });
288
+ process.stdout.write(` ${s.green('✔')} Digest scheduled for ${s.cyan(answers.time)} ${answers.timezone}\n`);
289
+ process.stdout.write(` Next delivery: ${s.cyan(result.nextDelivery)}\n`);
289
290
  break;
290
291
  }
291
292
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ticketlens",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "Jira CLI for developers — fetch ticket context, triage your queue, and stop tab-switching. Zero dependencies, all local.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,8 +1,8 @@
1
1
  import { readCliToken } from './cli-auth.mjs';
2
2
  import { formatCollisions } from './collision-reporter.mjs';
3
3
  import { DEFAULT_CONFIG_DIR } from './config.mjs';
4
-
5
4
  import { apiBase, warnIfInsecure } from './api-utils.mjs';
5
+ import { red, yellow, bold, cyan } from './ansi.mjs';
6
6
 
7
7
  const COLLISIONS_PATH = '/v1/triage/collisions';
8
8
 
@@ -29,7 +29,7 @@ export async function runCollisions(args = [], opts = {}) {
29
29
 
30
30
  const cliToken = readCliTokenFn(configDir) ?? null;
31
31
  if (!cliToken) {
32
- print('✗ collisions requires Console access. Run ticketlens login first.\n');
32
+ print(` ${red('✗')} ${bold('collisions')} requires Console access. Run ${cyan('ticketlens login')} first.\n`);
33
33
  return { ok: false };
34
34
  }
35
35
 
@@ -41,14 +41,14 @@ export async function runCollisions(args = [], opts = {}) {
41
41
 
42
42
  if (!res.ok) {
43
43
  if (res.status === 401) {
44
- print('✗ Session expired. Run ticketlens login to reconnect.\n');
44
+ print(` ${red('✗')} Session expired. Run ${cyan('ticketlens login')} to reconnect.\n`);
45
45
  return { ok: false, status: 401 };
46
46
  }
47
47
  if (res.status === 403) {
48
- print('✗ collisions requires a Team license\n');
48
+ print(` ${red('✗')} ${bold('collisions')} requires a Team license\n`);
49
49
  return { ok: false, status: 403 };
50
50
  }
51
- print(`⚠ Failed to fetch collisions (${res.status})\n`);
51
+ print(` ${yellow('⚠')} Failed to fetch collisions (${res.status})\n`);
52
52
  return { ok: false, status: res.status };
53
53
  }
54
54
 
@@ -67,7 +67,7 @@ export async function runCollisions(args = [], opts = {}) {
67
67
 
68
68
  return { ok: true };
69
69
  } catch {
70
- print('⚠ Failed to fetch collisions (network error)\n');
70
+ print(` ${yellow('⚠')} Failed to fetch collisions (network error)\n`);
71
71
  return { ok: false };
72
72
  }
73
73
  }
@@ -2,6 +2,7 @@ import { writeFileSync, mkdirSync, unlinkSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { homedir, platform as osPlatform } from 'node:os';
4
4
  import { spawnSync } from 'node:child_process';
5
+ import { red, green, cyan } from './ansi.mjs';
5
6
 
6
7
  const SCHEDULE_URL = 'https://api.ticketlens.dev/v1/schedule';
7
8
 
@@ -60,7 +61,7 @@ export async function runScheduleWizard({
60
61
  print = s => process.stdout.write(s),
61
62
  }) {
62
63
  if (!cliToken) {
63
- print('✗ schedule requires Console access. Run ticketlens login first.\n');
64
+ print(` ${red('✗')} schedule requires Console access. Run ${cyan('ticketlens login')} first.\n`);
64
65
  return { ok: false };
65
66
  }
66
67
  const { time, email, timezone } = answers;
@@ -103,7 +104,7 @@ export async function runScheduleStop({
103
104
  print = s => process.stdout.write(s),
104
105
  }) {
105
106
  if (!cliToken) {
106
- print('✗ schedule requires Console access. Run ticketlens login first.\n');
107
+ print(` ${red('✗')} schedule requires Console access. Run ${cyan('ticketlens login')} first.\n`);
107
108
  return;
108
109
  }
109
110
  const res = await fetcher(SCHEDULE_URL, {
@@ -125,7 +126,7 @@ export async function runScheduleStop({
125
126
  spawnSync('crontab', [tmp], { encoding: 'utf8' });
126
127
  }
127
128
 
128
- process.stdout.write('✔ Digest schedule removed.\n');
129
+ print(` ${green('✔')} Digest schedule removed.\n`);
129
130
  }
130
131
 
131
132
  export async function runScheduleStatus({
@@ -134,7 +135,7 @@ export async function runScheduleStatus({
134
135
  print = s => process.stdout.write(s),
135
136
  }) {
136
137
  if (!cliToken) {
137
- print('✗ schedule requires Console access. Run ticketlens login first.\n');
138
+ print(` ${red('✗')} schedule requires Console access. Run ${cyan('ticketlens login')} first.\n`);
138
139
  return;
139
140
  }
140
141
  const res = await fetcher(SCHEDULE_URL, {
@@ -147,9 +148,9 @@ export async function runScheduleStatus({
147
148
  return;
148
149
  }
149
150
  const data = await res.json();
150
- process.stdout.write(`Digest schedule: ${data.deliverAt} ${data.timezone}\n`);
151
- process.stdout.write(`Last delivered: ${data.lastDeliveredAt ?? 'never'}\n`);
152
- process.stdout.write(`Next delivery: ${data.nextDelivery}\n`);
151
+ print(` ${green('✔')} Digest schedule: ${cyan(data.deliverAt)} ${data.timezone}\n`);
152
+ print(` Last delivered: ${data.lastDeliveredAt ?? 'never'}\n`);
153
+ print(` Next delivery: ${cyan(data.nextDelivery)}\n`);
153
154
  }
154
155
 
155
156
  function resolveTicketlensBin() {
@@ -8,6 +8,7 @@ import { isLicensed } from './license.mjs';
8
8
  import { DEFAULT_CONFIG_DIR } from './config.mjs';
9
9
  import { apiBase, warnIfInsecure } from './api-utils.mjs';
10
10
  import { buildTicketPayload } from './ticket-payload.mjs';
11
+ import { red, green, yellow, bold, cyan } from './ansi.mjs';
11
12
 
12
13
  const PUSH_PATH = '/v1/triage/push';
13
14
 
@@ -54,7 +55,7 @@ export async function pushTriageSnapshot({
54
55
  } = {}) {
55
56
  warnIfInsecure(apiBase(), warn);
56
57
  if (!cliToken) {
57
- print('✗ --push requires Console access. Run ticketlens login first.\n');
58
+ print(` ${red('✗')} ${bold('--push')} requires Console access. Run ${cyan('ticketlens login')} first.\n`);
58
59
  return { ok: false };
59
60
  }
60
61
 
@@ -100,24 +101,24 @@ export async function pushTriageSnapshot({
100
101
  });
101
102
 
102
103
  if (res.ok) {
103
- print(`✓ Queue updated — view at ${queueUrl(apiBase())}\n`);
104
+ print(` ${green('✓')} Queue updated — view at ${queueUrl(apiBase())}\n`);
104
105
  return { ok: true, status: res.status };
105
106
  }
106
107
 
107
108
  if (res.status === 401) {
108
- print('✗ Session expired. Run ticketlens login to reconnect.\n');
109
+ print(` ${red('✗')} Session expired. Run ${cyan('ticketlens login')} to reconnect.\n`);
109
110
  return { ok: false, status: res.status };
110
111
  }
111
112
 
112
113
  if (res.status === 403) {
113
- print('✗ --push requires a Team license\n');
114
+ print(` ${red('✗')} ${bold('--push')} requires a Team license\n`);
114
115
  return { ok: false, status: res.status };
115
116
  }
116
117
 
117
- print(`⚠ Push failed (${res.status}) — triage output unaffected\n`);
118
+ print(` ${yellow('⚠')} Push failed (${res.status}) — triage output unaffected\n`);
118
119
  return { ok: false, status: res.status };
119
120
  } catch {
120
- print('⚠ Push failed (network error) — triage output unaffected\n');
121
+ print(` ${yellow('⚠')} Push failed (network error) — triage output unaffected\n`);
121
122
  return { ok: false };
122
123
  }
123
124
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { apiBase, warnIfInsecure } from './api-utils.mjs';
7
+ import { red, green, yellow, bold, cyan } from './ansi.mjs';
7
8
 
8
9
  const SHARE_PATH = '/v1/triage/share';
9
10
 
@@ -48,7 +49,7 @@ export async function shareTriageSnapshot({
48
49
  } = {}) {
49
50
  warnIfInsecure(apiBase(), warn);
50
51
  if (!cliToken) {
51
- print('✗ --share requires Console access. Run ticketlens login first.\n');
52
+ print(` ${red('✗')} ${bold('--share')} requires Console access. Run ${cyan('ticketlens login')} first.\n`);
52
53
  return { ok: false };
53
54
  }
54
55
 
@@ -71,24 +72,24 @@ export async function shareTriageSnapshot({
71
72
 
72
73
  if (res.ok) {
73
74
  const data = await res.json();
74
- print(`✓ Share link (expires in 24h):\n ${data.url}\n`);
75
+ print(` ${green('✓')} Share link (expires in 24h):\n ${data.url}\n`);
75
76
  return { ok: true, status: res.status };
76
77
  }
77
78
 
78
79
  if (res.status === 401) {
79
- print('✗ Session expired. Run ticketlens login to reconnect.\n');
80
+ print(` ${red('✗')} Session expired. Run ${cyan('ticketlens login')} to reconnect.\n`);
80
81
  return { ok: false, status: res.status };
81
82
  }
82
83
 
83
84
  if (res.status === 403) {
84
- print('✗ --share requires a Team license\n');
85
+ print(` ${red('✗')} ${bold('--share')} requires a Team license\n`);
85
86
  return { ok: false, status: res.status };
86
87
  }
87
88
 
88
- print(`⚠ Share failed (${res.status}) — triage output unaffected\n`);
89
+ print(` ${yellow('⚠')} Share failed (${res.status}) — triage output unaffected\n`);
89
90
  return { ok: false, status: res.status };
90
91
  } catch {
91
- print('⚠ Share failed (network error) — triage output unaffected\n');
92
+ print(` ${yellow('⚠')} Share failed (network error) — triage output unaffected\n`);
92
93
  return { ok: false };
93
94
  }
94
95
  }