ticketlens 0.9.11 → 0.9.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ticketlens",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
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": {
@@ -552,6 +552,7 @@ export async function run(args, envOrOpts = process.env, fetcher = globalThis.fe
552
552
  const complianceRunner = opts.runComplianceCheck ?? runComplianceCheck;
553
553
  const complianceResult = await complianceRunner({
554
554
  brief: briefC,
555
+ description: ticketC.description,
555
556
  ticketKey: ticketKeyArg,
556
557
  configDir: resolvedConfigDir,
557
558
  });
@@ -1041,6 +1042,7 @@ export async function run(args, envOrOpts = process.env, fetcher = globalThis.fe
1041
1042
  if (args.includes('--compliance')) {
1042
1043
  const checkResult = await runComplianceCheck({
1043
1044
  brief,
1045
+ description: cached.ticket.description,
1044
1046
  ticketKey,
1045
1047
  configDir,
1046
1048
  });
@@ -1227,6 +1229,7 @@ export async function run(args, envOrOpts = process.env, fetcher = globalThis.fe
1227
1229
  if (args.includes('--compliance')) {
1228
1230
  const checkResult = await runComplianceCheck({
1229
1231
  brief: output,
1232
+ description: ticket.description,
1230
1233
  ticketKey,
1231
1234
  configDir,
1232
1235
  });
@@ -83,19 +83,10 @@ export async function downloadAttachments(ticket, opts = {}) {
83
83
  onProgress?.(` download ${a.filename}`);
84
84
  try {
85
85
  const headers = buildAuthHeader(env);
86
- let response;
87
- try {
88
- // Prefer no-redirect so auth headers stay on the Jira origin.
89
- response = await fetcher(a.content, { headers, redirect: 'error' });
90
- } catch (err) {
91
- // Jira Cloud attachment URLs sometimes redirect to CDN/S3 presigned URLs.
92
- // On redirect, retry without auth — the presigned URL provides its own authentication.
93
- if (err?.cause?.message?.includes('redirect mode is set to error')) {
94
- response = await fetcher(a.content, { redirect: 'follow' });
95
- } else {
96
- throw err;
97
- }
98
- }
86
+ // Default redirect:'follow' — Jira Cloud attachment URLs may redirect to CDN/S3
87
+ // presigned URLs. The SSRF guard above already validates the initial URL is on
88
+ // the configured Jira origin, which is the relevant security boundary here.
89
+ const response = await fetcher(a.content, { headers });
99
90
  if (!response.ok) throw new Error(`HTTP ${response.status} (${response.statusText})`);
100
91
  const buffer = await response.arrayBuffer();
101
92
  fs.writeFileSync(localPath, Buffer.from(buffer));
@@ -29,6 +29,7 @@ function formatReport({ ticketKey, requirements, analysis, usage, isPro }) {
29
29
  const icon = STATUS_ICON[status] ?? '?';
30
30
  lines.push(` ${icon} ${requirement}`);
31
31
  if (evidence) lines.push(` └─ ${evidence}`);
32
+ lines.push('');
32
33
  }
33
34
 
34
35
  lines.push('');
@@ -47,6 +48,7 @@ function formatReport({ ticketKey, requirements, analysis, usage, isPro }) {
47
48
 
48
49
  export async function runComplianceCheck({
49
50
  brief,
51
+ description = null,
50
52
  ticketKey,
51
53
  configDir = DEFAULT_CONFIG_DIR,
52
54
  stream = process.stderr,
@@ -70,7 +72,9 @@ export async function runComplianceCheck({
70
72
 
71
73
  incrementUsageFn(configDir);
72
74
 
73
- const requirements = extractRequirementsFn(brief);
75
+ // Extract requirements from the ticket description only — not from comments,
76
+ // linked tickets, or the styled output, which would produce false positives.
77
+ const requirements = extractRequirementsFn(description ?? brief);
74
78
  const { diff } = findLinkedCommitsFn(ticketKey, { cwd: process.cwd() });
75
79
  const analysis = analyzeDiffFn(requirements, diff);
76
80