ticketlens 0.38.29 → 0.38.30
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
|
@@ -118,9 +118,17 @@ export function hasRecentCapture(cwd, now = Date.now()) {
|
|
|
118
118
|
* tool — for note-add. Missing the MCP path here was a real bug: it made
|
|
119
119
|
* the Stop hook nudge even after a note was genuinely captured via MCP,
|
|
120
120
|
* since only the Bash/CLI form was ever recognized.
|
|
121
|
+
*
|
|
122
|
+
* `ticketKey` carries the FIRST matched ticket key's literal text (or
|
|
123
|
+
* `null`), so callers can resolve a profile by ticket-key prefix the same
|
|
124
|
+
* way `resolveConnection()` does — see recall-nudge-stop.mjs. First match,
|
|
125
|
+
* not last: the primary ticket a session is about is normally established
|
|
126
|
+
* early, and picking one deterministic match keeps this function decoupled
|
|
127
|
+
* from profiles.json (it stays a pure transcript reader; profile lookup
|
|
128
|
+
* and its own fallback chain belong entirely to resolveProfile()).
|
|
121
129
|
*/
|
|
122
130
|
export function scanTranscript(transcriptPath) {
|
|
123
|
-
const result = { sawTicketKey: false, sawRecallFlag: false, sawNoteAdd: false };
|
|
131
|
+
const result = { sawTicketKey: false, sawRecallFlag: false, sawNoteAdd: false, ticketKey: null };
|
|
124
132
|
let lines;
|
|
125
133
|
try {
|
|
126
134
|
lines = fs.readFileSync(transcriptPath, 'utf8').split('\n').filter(Boolean);
|
|
@@ -136,10 +144,22 @@ export function scanTranscript(transcriptPath) {
|
|
|
136
144
|
continue;
|
|
137
145
|
}
|
|
138
146
|
|
|
139
|
-
// Ticket-key detection stays broad (whole entry, any role) —
|
|
140
|
-
// the weaker "did ticket work happen at
|
|
141
|
-
// positive
|
|
142
|
-
|
|
147
|
+
// Ticket-key detection stays broad (whole entry, any role) — for
|
|
148
|
+
// sawTicketKey alone, it's only the weaker "did ticket work happen at
|
|
149
|
+
// all" signal, so a rare false positive just means an extra harmless
|
|
150
|
+
// once-per-session check. The captured ticketKey text carries a bit
|
|
151
|
+
// more weight (it also selects which profile's recallStrictness
|
|
152
|
+
// applies, see recall-nudge-stop.mjs), but the ceiling is still just
|
|
153
|
+
// "the wrong local settings value governs one Stop-hook decision" — no
|
|
154
|
+
// credentials or ticket data are read using this key, so a false
|
|
155
|
+
// positive here stays low-consequence, not narrowed further for now.
|
|
156
|
+
if (!result.ticketKey) {
|
|
157
|
+
const match = TICKET_KEY_RE.exec(JSON.stringify(entry));
|
|
158
|
+
if (match) {
|
|
159
|
+
result.sawTicketKey = true;
|
|
160
|
+
result.ticketKey = match[0];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
143
163
|
|
|
144
164
|
if (entry.type !== 'assistant') continue;
|
|
145
165
|
const blocks = entry.message?.content;
|
|
@@ -21,14 +21,13 @@
|
|
|
21
21
|
* profile's recallStrictness — see recall-nudge-lib.mjs's shouldNag() doc
|
|
22
22
|
* comment for the calibration and why strict doesn't widen this further.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* Not fixed here — see design spec §6 for the follow-up.
|
|
24
|
+
* resolveProfile() below is given scanTranscript()'s matched ticket key (not
|
|
25
|
+
* null), so it resolves by ticket-key prefix the same way the brief-injection
|
|
26
|
+
* lever (resolveConnection(ticketKey, ...) in profile-resolver.mjs) does —
|
|
27
|
+
* both levers now agree on which profile's recallStrictness applies for a
|
|
28
|
+
* multi-profile user. When no ticket key was seen, or it matches no profile's
|
|
29
|
+
* ticketPrefixes, this falls through to cwd/projectPaths then the default
|
|
30
|
+
* profile, same as before (backlog #12, design spec §6).
|
|
32
31
|
*/
|
|
33
32
|
|
|
34
33
|
import { readStdinJson, readState, writeState, scanTranscript, hasRecentCapture, writeLastCaptureAt, shouldNag } from './recall-nudge-lib.mjs';
|
|
@@ -41,7 +40,7 @@ const cwd = input?.cwd ?? process.cwd();
|
|
|
41
40
|
|
|
42
41
|
if (!sessionId || !transcriptPath) process.exit(0);
|
|
43
42
|
|
|
44
|
-
const { sawTicketKey, sawRecallFlag, sawNoteAdd } = scanTranscript(transcriptPath);
|
|
43
|
+
const { sawTicketKey, sawRecallFlag, sawNoteAdd, ticketKey } = scanTranscript(transcriptPath);
|
|
45
44
|
|
|
46
45
|
// Refreshed on every check, independent of the once-per-session gate below —
|
|
47
46
|
// a capture that happens AFTER this session already nagged once must still
|
|
@@ -51,7 +50,7 @@ if (sawNoteAdd) writeLastCaptureAt(cwd, Date.now());
|
|
|
51
50
|
const state = readState(sessionId);
|
|
52
51
|
if (state.stopChecked) process.exit(0); // already asked once this session — respect the answer
|
|
53
52
|
|
|
54
|
-
const profile = resolveProfile(
|
|
53
|
+
const profile = resolveProfile(ticketKey, { cwd });
|
|
55
54
|
const recallStrictness = normalizeRecallStrictness(profile?.recallStrictness);
|
|
56
55
|
|
|
57
56
|
if (!shouldNag({ sawTicketKey, sawRecallFlag, sawNoteAdd, recallStrictness })) {
|
|
@@ -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,
|