ticketlens 0.43.2 → 0.43.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/package.json
CHANGED
|
@@ -207,7 +207,7 @@ async function applySummarize(brief, args, opts, configDir, conn, licensedFn, up
|
|
|
207
207
|
const cliToken = opts.cliToken ?? readCliToken(configDir);
|
|
208
208
|
const provider = opts.provider ?? resolveAiProvider(args, credentials);
|
|
209
209
|
const aiInput = augmentBriefForAi(brief, ticket?.localAttachments);
|
|
210
|
-
const summary = await summarizerFn({ brief: aiInput, mode, credentials, cliToken, provider });
|
|
210
|
+
const summary = await summarizerFn({ brief: aiInput, mode, credentials, cliToken, provider, ticketKey });
|
|
211
211
|
if (ticketKey && !opts.summarizer) writeSummaryCache(ticketKey, profileName, summary, configDir);
|
|
212
212
|
const divider = '─'.repeat(60);
|
|
213
213
|
return brief + `\n\n${divider}\n─── AI Summary ${'─'.repeat(45)}\n${summary}\n${divider}\n`;
|
|
@@ -241,7 +241,7 @@ async function applyHandoff(ticket, args, opts, configDir, licensedFn, upgradeFn
|
|
|
241
241
|
const cliToken = opts.cliToken ?? readCliToken(configDir);
|
|
242
242
|
const provider = opts.provider ?? resolveAiProvider(args, credentials);
|
|
243
243
|
const input = buildHandoffInput(ticket);
|
|
244
|
-
const body = await summarizerFn({ brief: input, mode, credentials, cliToken, prompt: HANDOFF_PROMPT, maxTokens: 512, provider });
|
|
244
|
+
const body = await summarizerFn({ brief: input, mode, credentials, cliToken, prompt: HANDOFF_PROMPT, maxTokens: 512, provider, ticketKey: ticket?.key ?? null });
|
|
245
245
|
return `## Handoff Brief — ${ticket.key}\n\n${body}\n`;
|
|
246
246
|
} catch (err) {
|
|
247
247
|
const onErrorFn = opts.onError ?? ((msg) => process.stderr.write(msg + '\n'));
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Centralised here to avoid triplicating the regex and warning logic.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
export const DEFAULT_API_BASE = '
|
|
6
|
+
export const DEFAULT_API_BASE = 'http://api.ticketlens.test';
|
|
7
7
|
export const DEFAULT_SITE_BASE = 'https://ticketlens.app';
|
|
8
8
|
|
|
9
9
|
// Matches localhost, 127.0.0.1, and any hostname ending in .test or .local,
|
|
@@ -4,6 +4,17 @@ import { detectBase } from './branch-scanner.mjs';
|
|
|
4
4
|
const TICKET_KEY_RE = /^[A-Z][A-Z0-9]+-\d+$/;
|
|
5
5
|
const SPAWN_OPTS = { encoding: 'utf8', timeout: 10_000 };
|
|
6
6
|
|
|
7
|
+
// Backlog #26b: markdown never carries source evidence for an acceptance
|
|
8
|
+
// criterion, so unrelated doc edits must not leak into `analyzeDiff` or the
|
|
9
|
+
// raw diff sent to `--consensus`'s external AI providers.
|
|
10
|
+
//
|
|
11
|
+
// `top` anchors the pattern to the repo root; without it `*.md` resolves
|
|
12
|
+
// relative to `cwd`, and callers routinely run from a monorepo subdirectory.
|
|
13
|
+
//
|
|
14
|
+
// Scoped to `.md`, not `docs/**`: non-markdown files under `docs/` can be
|
|
15
|
+
// real evidence (e.g. a docs site's own source).
|
|
16
|
+
const EXCLUDED_DIFF_PATHSPECS = [':(exclude,top)*.md'];
|
|
17
|
+
|
|
7
18
|
function run(execFn, cmd, args, cwd) {
|
|
8
19
|
const result = execFn(cmd, args, { ...SPAWN_OPTS, cwd });
|
|
9
20
|
return result.status === 0 ? (result.stdout || '') : null;
|
|
@@ -19,10 +30,10 @@ function computeDiff(execFn, cwd) {
|
|
|
19
30
|
if (base) {
|
|
20
31
|
const mergeBase = run(execFn, 'git', ['merge-base', 'HEAD', base], cwd)?.trim();
|
|
21
32
|
if (mergeBase) {
|
|
22
|
-
return run(execFn, 'git', ['diff', mergeBase], cwd);
|
|
33
|
+
return run(execFn, 'git', ['diff', mergeBase, '--', ...EXCLUDED_DIFF_PATHSPECS], cwd);
|
|
23
34
|
}
|
|
24
35
|
}
|
|
25
|
-
return run(execFn, 'git', ['diff', 'HEAD'], cwd);
|
|
36
|
+
return run(execFn, 'git', ['diff', 'HEAD', '--', ...EXCLUDED_DIFF_PATHSPECS], cwd);
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
export function findLinkedCommits(ticketKey, opts = {}) {
|
|
@@ -17,13 +17,13 @@ const DEFAULT_MAX_TOKENS = 256;
|
|
|
17
17
|
* @param {number} [opts.timeoutMs]
|
|
18
18
|
* @returns {Promise<string>} Summary text
|
|
19
19
|
*/
|
|
20
|
-
export async function summarize({ brief, mode, credentials = null, cliToken = null, fetcher = globalThis.fetch, timeoutMs = 30_000, prompt, maxTokens, provider }) {
|
|
20
|
+
export async function summarize({ brief, mode, credentials = null, cliToken = null, fetcher = globalThis.fetch, timeoutMs = 30_000, prompt, maxTokens, provider, ticketKey }) {
|
|
21
21
|
const effectivePrompt = prompt ?? DEFAULT_PROMPT;
|
|
22
22
|
const effectiveMaxTokens = maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
23
23
|
if (mode === 'byok') {
|
|
24
24
|
return byok({ brief, credentials, fetcher, timeoutMs, prompt: effectivePrompt, maxTokens: effectiveMaxTokens, provider });
|
|
25
25
|
}
|
|
26
|
-
return cloud({ brief, cliToken, fetcher, timeoutMs });
|
|
26
|
+
return cloud({ brief, ticketKey, cliToken, fetcher, timeoutMs });
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
async function byok({ brief, credentials, fetcher, timeoutMs, prompt, maxTokens, provider }) {
|
|
@@ -137,8 +137,10 @@ async function callGroq({ brief, apiKey, fetcher, timeoutMs, prompt, maxTokens }
|
|
|
137
137
|
return data.choices[0].message.content;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
async function cloud({ brief, cliToken, fetcher, timeoutMs }) {
|
|
140
|
+
async function cloud({ brief, ticketKey, cliToken, fetcher, timeoutMs }) {
|
|
141
141
|
if (!cliToken) throw new Error('Not logged in. Run `ticketlens login` first.');
|
|
142
|
+
const payload = { brief };
|
|
143
|
+
if (ticketKey) payload.ticketKey = ticketKey;
|
|
142
144
|
const res = await fetcher(`${apiBase()}/v1/summarize`, {
|
|
143
145
|
method: 'POST',
|
|
144
146
|
signal: AbortSignal.timeout(timeoutMs),
|
|
@@ -146,7 +148,7 @@ async function cloud({ brief, cliToken, fetcher, timeoutMs }) {
|
|
|
146
148
|
'Content-Type': 'application/json',
|
|
147
149
|
'Authorization': `Bearer ${cliToken}`,
|
|
148
150
|
},
|
|
149
|
-
body: JSON.stringify(
|
|
151
|
+
body: JSON.stringify(payload),
|
|
150
152
|
});
|
|
151
153
|
|
|
152
154
|
if (!res.ok) {
|