mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-09 18:28:15 +01:00
* Keep the scroll selector when --wait is absent Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Skip a PATH browse that links to another program such as xdg-open Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Give each project its own browse slug on installs without ~/.claude Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Keep a question marker when its signal hint is malformed Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Read the lowercased question id in the never-ask preference hook Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Keep a marker's tail in the one-way door check Review-Finding: p1/targeted#1 reader=targeted Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Keep a marker's tail apart from the next word in the one-way door check Review-Finding: p2/outside-voice#1 reader=outside-voice Review-Finding: p2/adversarial-native#1 reader=adversarial-native Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Say where old domain skills live and narrow the marker note in the changelog Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Say how the browse daemon picks a project's domain skill file Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
32 lines
1.1 KiB
TypeScript
32 lines
1.1 KiB
TypeScript
/**
|
|
* The <gstack-qid:...> marker a skill puts in an asked question (#3442).
|
|
*
|
|
* `<gstack-qid:{id}>` names the question; an unregistered id may add a
|
|
* signal hint, `<gstack-qid:{id};signal={signal_key}>`, naming the
|
|
* SIGNAL_MAP key its answer speaks to. Ids and keys are read lowercase.
|
|
* A malformed hint (an underscore, a space, an empty or unknown key name)
|
|
* is dropped on its own; the id still names the question. Whether a hint
|
|
* is a real SIGNAL_MAP key is checked where the row is logged
|
|
* (bin/gstack-question-log), not here.
|
|
*/
|
|
export const QID_MARKER_RE = /<gstack-qid:([a-z0-9-]{1,64})(?:;([^<>\n]{0,128}))?>/i;
|
|
|
|
const SIGNAL_HINT_RE = /^signal=([a-z0-9-]{1,64})$/i;
|
|
|
|
export interface QidMarker {
|
|
id: string;
|
|
signal_key?: string;
|
|
stripped: string;
|
|
}
|
|
|
|
export function parseQidMarker(text: string): QidMarker | undefined {
|
|
const m = QID_MARKER_RE.exec(text);
|
|
if (!m) return undefined;
|
|
const hint = m[2] === undefined ? undefined : SIGNAL_HINT_RE.exec(m[2])?.[1];
|
|
return {
|
|
id: m[1]!.toLowerCase(),
|
|
...(hint ? { signal_key: hint.toLowerCase() } : {}),
|
|
stripped: text.replace(QID_MARKER_RE, '').trim(),
|
|
};
|
|
}
|