@supersession/sup 0.1.2 → 0.1.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.
@@ -55,4 +55,13 @@ export interface DistillOptions {
55
55
  secretsRedacted?: number;
56
56
  }
57
57
  export declare function groundFiles(session: NsfSession): FileState[];
58
+ /**
59
+ * One-line title + short summary for a session, used as cloud/list metadata.
60
+ * Prefers the source tool's own session name (Cursor names chats); otherwise
61
+ * the inferred goal. Same grounded-only rules as the rest of template distill.
62
+ */
63
+ export declare function sessionHeadline(session: NsfSession): {
64
+ title: string;
65
+ summary: string;
66
+ };
58
67
  export declare function distillTemplate(session: NsfSession, opts?: DistillOptions): Brief;
@@ -103,6 +103,22 @@ function inferNextStep(turns) {
103
103
  return firstLines(lastUser.text, 3);
104
104
  return "(no pending user request — continue the last thread)";
105
105
  }
106
+ /**
107
+ * One-line title + short summary for a session, used as cloud/list metadata.
108
+ * Prefers the source tool's own session name (Cursor names chats); otherwise
109
+ * the inferred goal. Same grounded-only rules as the rest of template distill.
110
+ */
111
+ export function sessionHeadline(session) {
112
+ const clip = (s, n) => {
113
+ const one = s.split("\n")[0].trim();
114
+ return one.length > n ? `${one.slice(0, n - 1)}…` : one;
115
+ };
116
+ const title = session.provenance.title?.trim() || inferGoal(session.turns);
117
+ return {
118
+ title: clip(title, 80),
119
+ summary: clip(summarizeState(session.turns), 200),
120
+ };
121
+ }
106
122
  export function distillTemplate(session, opts = {}) {
107
123
  const recentN = opts.recentTurns ?? DEFAULT_RECENT;
108
124
  const recentTurns = session.turns.slice(-recentN);
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/distill/template.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/distill/template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AA6CjD,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,0EAA0E;AAC1E,SAAS,SAAS,CAAC,KAAgB;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACpB,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,0DAA0D;QAC1D,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,SAAS;QAC3D,OAAO,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,qCAAqC,CAAC;AAC/C,CAAC;AAED,oFAAoF;AACpF,SAAS,SAAS,CAAC,GAAuB,EAAE,KAAe;IACzD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE;YACzD,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,4DAA4D;QAC5D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;QACxC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/B,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrB,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACvD,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAmB;IAC7C,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACpE,OAAO,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzC,IAAI;QACJ,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC;QACxB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;KACnB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,4EAA4E;AAC5E,SAAS,WAAW,CAAC,OAAmB;IACtC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,4CAA4C,CAAC;IAC7D,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO;gBAAE,SAAS;YAC7C,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;YAC7C,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACzD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,CAAS;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,cAAc,CAAC,KAAgB;IACtC,MAAM,aAAa,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IACzF,IAAI,aAAa;QAAE,OAAO,UAAU,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5D,OAAO,4CAA4C,CAAC;AACtD,CAAC;AAED,SAAS,aAAa,CAAC,KAAgB;IACrC,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/E,IAAI,QAAQ;QAAE,OAAO,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClD,OAAO,sDAAsD,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE;QACpC,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;QACrC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1D,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3E,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC;KAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB,EAAE,OAAuB,EAAE;IAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,cAAc,CAAC;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAE/E,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;QAC9B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC;QAC3B,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC;QAC9B,WAAW;QACX,YAAY,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC;QAC3C,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC;QACtC,QAAQ,EAAE;YACR,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;YAChC,aAAa,EAAE,WAAW,CAAC,MAAM;YACjC,eAAe;YACf,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YAC7E,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,CAAC;SAC3C;KACF,CAAC;AACJ,CAAC"}
package/dist/engine.d.ts CHANGED
@@ -9,7 +9,7 @@ import { type Brief } from "./distill/template.js";
9
9
  import type { NsfSession } from "./nsf.js";
10
10
  export declare class NoSessionError extends Error {
11
11
  }
12
- /** Parse the latest Claude Code session for a directory, or throw NoSessionError. */
12
+ /** Parse the newest session (any supported tool) for a directory, or throw. */
13
13
  export declare function requireSession(cwd: string): NsfSession;
14
14
  export interface DistillResult {
15
15
  brief: Brief;
package/dist/engine.js CHANGED
@@ -5,19 +5,18 @@
5
5
  * over stdout, so a stray console.log would corrupt the protocol. Callers get
6
6
  * structured results and decide how (or whether) to print them.
7
7
  */
8
- import { findClaudeCodeSession } from "./discover.js";
9
- import { parseClaudeCode } from "./parsers/claude-code.js";
8
+ import { findLatestSession } from "./discover.js";
10
9
  import { redactSession } from "./redact.js";
11
10
  import { distillTemplate } from "./distill/template.js";
12
11
  import { distillSmart } from "./distill/smart.js";
13
12
  export class NoSessionError extends Error {
14
13
  }
15
- /** Parse the latest Claude Code session for a directory, or throw NoSessionError. */
14
+ /** Parse the newest session (any supported tool) for a directory, or throw. */
16
15
  export function requireSession(cwd) {
17
- const found = findClaudeCodeSession(cwd);
16
+ const found = findLatestSession(cwd);
18
17
  if (!found)
19
- throw new NoSessionError(`No Claude Code session found for ${cwd} (looked under ~/.claude/projects).`);
20
- const parsed = parseClaudeCode(found.filePath);
18
+ throw new NoSessionError(`No session found for ${cwd} (looked for Claude Code, Codex, and Cursor sessions).`);
19
+ const parsed = found.parse();
21
20
  if (parsed.turns.length === 0)
22
21
  throw new NoSessionError("Session file had no usable turns.");
23
22
  return parsed;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAc,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK;QACR,MAAM,IAAI,cAAc,CAAC,oCAAoC,GAAG,qCAAqC,CAAC,CAAC;IACzG,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,mCAAmC,CAAC,CAAC;IAC7F,OAAO,MAAM,CAAC;AAChB,CAAC;AASD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAe,EACf,aAAsB;IAEtB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACxF,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,OAAO;QAClB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,KAAK;YACL,CAAC,CAAC,8BAA8B,KAAK,0BAA0B;YAC/D,CAAC,CAAC,wGAAwG,CAAC;IAC/G,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAc,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAE5C,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QACR,MAAM,IAAI,cAAc,CACtB,wBAAwB,GAAG,wDAAwD,CACpF,CAAC;IACJ,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;IAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,mCAAmC,CAAC,CAAC;IAC7F,OAAO,MAAM,CAAC;AAChB,CAAC;AASD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAe,EACf,aAAsB;IAEtB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACxF,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,MAAM,IAAI,GAAG,OAAO;QAClB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,KAAK;YACL,CAAC,CAAC,8BAA8B,KAAK,0BAA0B;YAC/D,CAAC,CAAC,wGAAwG,CAAC;IAC/G,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * `sup facts` — extract the nuggets people scroll transcripts hunting for:
3
+ * credentials the agent generated, URLs and ports, and credential-ish prose
4
+ * lines ("your test login is admin@x.com / hunter2").
5
+ *
6
+ * LOCAL ONLY. This module is the mirror image of redact.ts: redaction strips
7
+ * secrets before anything leaves the machine; facts surfaces them ON the
8
+ * machine. Nothing here is ever pushed, written to a brief, or logged remotely.
9
+ */
10
+ import type { NsfSession } from "./nsf.js";
11
+ export interface Fact {
12
+ /** What was found (secret value, URL, or a verbatim prose line). */
13
+ value: string;
14
+ /** Category detail, e.g. "github-token" or "credential mention". */
15
+ label: string;
16
+ /** 1-based turn number, so the user can find it in context. */
17
+ turn: number;
18
+ }
19
+ export interface SessionFacts {
20
+ secrets: Fact[];
21
+ urls: Fact[];
22
+ credentialLines: Fact[];
23
+ }
24
+ export declare function extractFacts(session: NsfSession): SessionFacts;
package/dist/facts.js ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * `sup facts` — extract the nuggets people scroll transcripts hunting for:
3
+ * credentials the agent generated, URLs and ports, and credential-ish prose
4
+ * lines ("your test login is admin@x.com / hunter2").
5
+ *
6
+ * LOCAL ONLY. This module is the mirror image of redact.ts: redaction strips
7
+ * secrets before anything leaves the machine; facts surfaces them ON the
8
+ * machine. Nothing here is ever pushed, written to a brief, or logged remotely.
9
+ */
10
+ import { findSecrets } from "./redact.js";
11
+ const URL_RE = /\bhttps?:\/\/[^\s)"'`<>\]]+/g;
12
+ // Bare host:port the way dev servers get mentioned ("listening on localhost:3000").
13
+ // The lookbehind keeps it from double-reporting the host inside an http:// URL.
14
+ const HOSTPORT_RE = /(?<![/.\w])(?:localhost|127\.0\.0\.1|0\.0\.0\.0):\d{2,5}\b/g;
15
+ // Prose lines that talk about credentials without matching a key pattern.
16
+ const CRED_LINE_RE = /\b(password|passwd|username|user ?name|login|credentials?|api ?key|access ?token)\b/i;
17
+ /** Dedupe by value, keeping the first (earliest turn) occurrence. */
18
+ function dedupe(facts) {
19
+ const seen = new Set();
20
+ return facts.filter((f) => (seen.has(f.value) ? false : (seen.add(f.value), true)));
21
+ }
22
+ export function extractFacts(session) {
23
+ const secrets = [];
24
+ const urls = [];
25
+ const credentialLines = [];
26
+ session.turns.forEach((t, i) => {
27
+ const turn = i + 1;
28
+ const texts = [t.text, ...t.actions.map((a) => a.command ?? "")].filter(Boolean);
29
+ for (const text of texts) {
30
+ for (const hit of findSecrets(text))
31
+ secrets.push({ value: hit.value, label: hit.name, turn });
32
+ for (const m of text.matchAll(URL_RE)) {
33
+ // Trailing punctuation is sentence noise, not part of the URL.
34
+ urls.push({ value: m[0].replace(/[.,;:!?]+$/, ""), label: "url", turn });
35
+ }
36
+ for (const m of text.matchAll(HOSTPORT_RE))
37
+ urls.push({ value: m[0], label: "port", turn });
38
+ }
39
+ // Credential mentions: only assistant prose (that's where "your login is…"
40
+ // lives), line-by-line so the printed fact reads in context.
41
+ if (t.role === "assistant" && t.text) {
42
+ for (const line of t.text.split("\n")) {
43
+ const trimmed = line.trim();
44
+ if (trimmed && CRED_LINE_RE.test(trimmed)) {
45
+ credentialLines.push({ value: trimmed.slice(0, 160), label: "credential mention", turn });
46
+ }
47
+ }
48
+ }
49
+ });
50
+ return {
51
+ secrets: dedupe(secrets),
52
+ urls: dedupe(urls),
53
+ credentialLines: dedupe(credentialLines),
54
+ };
55
+ }
56
+ //# sourceMappingURL=facts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.js","sourceRoot":"","sources":["../src/facts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Branded CLI output after sign-in — logomark + a rotating session-themed line.
3
+ */
4
+ /** Logomark + sign-in confirmation for browser OAuth. */
5
+ export declare function printLoginSuccess(displayName: string): void;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Branded CLI output after sign-in — logomark + a rotating session-themed line.
3
+ */
4
+ import pc from "picocolors";
5
+ const TAGLINES = [
6
+ "Context carried forward — pick up where you left off.",
7
+ "Your session survives the tool switch.",
8
+ "Handoffs without the amnesia.",
9
+ "One thread. Every tool.",
10
+ "Ready when the session limit hits.",
11
+ "The context you wrote stays yours.",
12
+ "Ship the thread, not just the code.",
13
+ "Same story, new terminal.",
14
+ "No re-explaining. Just continue.",
15
+ "Session continuity, on your terms.",
16
+ "From Claude to Codex without starting over.",
17
+ "Your work outlives the chat window.",
18
+ ];
19
+ function pickTagline() {
20
+ return TAGLINES[Math.floor(Math.random() * TAGLINES.length)];
21
+ }
22
+ /** Logomark + sign-in confirmation for browser OAuth. */
23
+ export function printLoginSuccess(displayName) {
24
+ const mark = pc.green;
25
+ const faint = pc.dim;
26
+ console.log("");
27
+ console.log(faint(" /"));
28
+ console.log(`${mark(" /")}${mark(" ──→")}`);
29
+ console.log(faint(" /"));
30
+ console.log(pc.bold(" supersession"));
31
+ console.log("");
32
+ console.log(pc.green(` ✓ Signed in as ${displayName}`));
33
+ console.log(faint(" Token saved to ~/.supersession/config.json"));
34
+ console.log("");
35
+ console.log(faint(` ${pickTagline()}`));
36
+ console.log("");
37
+ }
38
+ //# sourceMappingURL=greeting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greeting.js","sourceRoot":"","sources":["../src/greeting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,QAAQ,GAAG;IACf,uDAAuD;IACvD,wCAAwC;IACxC,+BAA+B;IAC/B,yBAAyB;IACzB,oCAAoC;IACpC,oCAAoC;IACpC,qCAAqC;IACrC,2BAA2B;IAC3B,kCAAkC;IAClC,oCAAoC;IACpC,6CAA6C;IAC7C,qCAAqC;CACtC,CAAC;AAEF,SAAS,WAAW;IAClB,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAE,CAAC;AAChE,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC;IACtB,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC;IAErB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
package/dist/nsf.d.ts CHANGED
@@ -40,6 +40,8 @@ export interface NsfProvenance {
40
40
  tool: string;
41
41
  /** The tool's native session id. */
42
42
  sessionId?: string;
43
+ /** Human title the source tool gave this session (e.g. Cursor's chat name). */
44
+ title?: string;
43
45
  /** Absolute working directory the session ran in. */
44
46
  cwd?: string;
45
47
  /** Git branch recorded at capture time, if any. */
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Codex CLI parser: rollout JSONL -> NSF.
3
+ *
4
+ * Grounded in the upstream format (verified 2026-07-15 against openai/codex
5
+ * codex-rs rollout recorder test fixtures), not a guess:
6
+ * - Files live at ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl
7
+ * - Each line: { timestamp, type, payload } (+ optional ordinal)
8
+ * - type "session_meta": payload has session_id/id, cwd, source; sibling
9
+ * `git` object may carry the branch.
10
+ * - type "response_item": payload is tagged by payload.type:
11
+ * "message" { role, content: [{type:"input_text"|"output_text", text}] }
12
+ * "function_call" { name, arguments (JSON string), call_id }
13
+ * "local_shell_call" { status, action: { command: [...] } }
14
+ * "reasoning", "function_call_output", ... -> gaps
15
+ * - type "event_msg" duplicates messages as UI events -> counted as gaps so
16
+ * turns aren't doubled.
17
+ * - type "compacted" is Codex's lossy in-place summarization -> a scar.
18
+ */
19
+ import type { NsfSession } from "../nsf.js";
20
+ export declare const CODEX_TOOL_ID = "codex";
21
+ /**
22
+ * Parse a Codex rollout JSONL file into NSF.
23
+ * @param filePath absolute path to the rollout-*.jsonl transcript.
24
+ */
25
+ export declare function parseCodex(filePath: string): NsfSession;
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Codex CLI parser: rollout JSONL -> NSF.
3
+ *
4
+ * Grounded in the upstream format (verified 2026-07-15 against openai/codex
5
+ * codex-rs rollout recorder test fixtures), not a guess:
6
+ * - Files live at ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl
7
+ * - Each line: { timestamp, type, payload } (+ optional ordinal)
8
+ * - type "session_meta": payload has session_id/id, cwd, source; sibling
9
+ * `git` object may carry the branch.
10
+ * - type "response_item": payload is tagged by payload.type:
11
+ * "message" { role, content: [{type:"input_text"|"output_text", text}] }
12
+ * "function_call" { name, arguments (JSON string), call_id }
13
+ * "local_shell_call" { status, action: { command: [...] } }
14
+ * "reasoning", "function_call_output", ... -> gaps
15
+ * - type "event_msg" duplicates messages as UI events -> counted as gaps so
16
+ * turns aren't doubled.
17
+ * - type "compacted" is Codex's lossy in-place summarization -> a scar.
18
+ */
19
+ import { readFileSync } from "node:fs";
20
+ import { NSF_VERSION } from "../nsf.js";
21
+ export const CODEX_TOOL_ID = "codex";
22
+ /** Codex injects wrapped context as fake user messages; they aren't the user. */
23
+ const INJECTED_USER_RE = /^<(user_instructions|environment_context|ENVIRONMENT_CONTEXT)/i;
24
+ function contentText(content) {
25
+ if (!Array.isArray(content))
26
+ return "";
27
+ return content
28
+ .map((c) => {
29
+ const o = c;
30
+ return (o?.type === "input_text" || o?.type === "output_text") && typeof o.text === "string"
31
+ ? o.text
32
+ : "";
33
+ })
34
+ .filter(Boolean)
35
+ .join("\n\n")
36
+ .trim();
37
+ }
38
+ /** Best-effort shell command out of function_call arguments / shell action. */
39
+ function commandFrom(args) {
40
+ if (typeof args !== "object" || args === null)
41
+ return undefined;
42
+ const cmd = args.command ?? args.cmd;
43
+ if (typeof cmd === "string")
44
+ return cmd;
45
+ if (Array.isArray(cmd))
46
+ return cmd.filter((x) => typeof x === "string").join(" ");
47
+ return undefined;
48
+ }
49
+ /** Paths named in an apply_patch envelope ("*** Update File: src/x.ts" etc). */
50
+ function patchPaths(patch) {
51
+ const out = [];
52
+ for (const m of patch.matchAll(/^\*\*\* (?:Update|Add|Delete) File: (.+)$/gm)) {
53
+ out.push(m[1].trim());
54
+ }
55
+ return out;
56
+ }
57
+ function functionCallActions(name, rawArguments) {
58
+ let args = rawArguments;
59
+ if (typeof rawArguments === "string") {
60
+ try {
61
+ args = JSON.parse(rawArguments);
62
+ }
63
+ catch {
64
+ args = undefined;
65
+ }
66
+ }
67
+ const o = (typeof args === "object" && args !== null ? args : {});
68
+ if (name === "apply_patch") {
69
+ const patch = typeof o.input === "string" ? o.input : typeof rawArguments === "string" ? rawArguments : "";
70
+ const paths = patchPaths(patch);
71
+ if (paths.length === 0)
72
+ return [{ kind: "edit", rawName: name }];
73
+ return paths.map((path) => ({ kind: "edit", rawName: name, path }));
74
+ }
75
+ const path = typeof o.path === "string" ? o.path : typeof o.file_path === "string" ? o.file_path : undefined;
76
+ const command = commandFrom(o);
77
+ const kind = /shell|exec/.test(name)
78
+ ? "run"
79
+ : /read|view/.test(name)
80
+ ? "read"
81
+ : /write|create/.test(name)
82
+ ? "write"
83
+ : /search|grep|glob|find/.test(name)
84
+ ? "search"
85
+ : "other";
86
+ return [{ kind, rawName: name, path, command }];
87
+ }
88
+ /**
89
+ * Parse a Codex rollout JSONL file into NSF.
90
+ * @param filePath absolute path to the rollout-*.jsonl transcript.
91
+ */
92
+ export function parseCodex(filePath) {
93
+ const raw = readFileSync(filePath, "utf8");
94
+ const turns = [];
95
+ const filesSeen = new Set();
96
+ const filesOrdered = [];
97
+ const gapCounts = new Map();
98
+ const addGap = (reason) => gapCounts.set(reason, (gapCounts.get(reason) ?? 0) + 1);
99
+ const provenance = {
100
+ tool: CODEX_TOOL_ID,
101
+ rawBytes: Buffer.byteLength(raw, "utf8"),
102
+ };
103
+ let compactions = 0;
104
+ // function_call actions attach to the pending assistant turn (Codex records
105
+ // calls as separate lines, unlike Claude Code's in-message blocks).
106
+ let pendingActions = [];
107
+ const flushActions = () => {
108
+ if (pendingActions.length === 0)
109
+ return;
110
+ turns.push({ role: "assistant", text: "", actions: pendingActions });
111
+ pendingActions = [];
112
+ };
113
+ for (const line of raw.split("\n")) {
114
+ const trimmed = line.trim();
115
+ if (!trimmed)
116
+ continue;
117
+ let rec;
118
+ try {
119
+ rec = JSON.parse(trimmed);
120
+ }
121
+ catch {
122
+ addGap("unparseable line");
123
+ continue;
124
+ }
125
+ const payload = rec.payload ?? {};
126
+ switch (rec.type) {
127
+ case "session_meta": {
128
+ const id = payload.id ?? payload.session_id;
129
+ provenance.sessionId ??= typeof id === "string" ? id : undefined;
130
+ provenance.cwd ??= typeof payload.cwd === "string" ? payload.cwd : undefined;
131
+ const git = rec.git ?? payload.git;
132
+ const branch = git?.branch;
133
+ provenance.gitBranch ??= typeof branch === "string" ? branch : undefined;
134
+ break;
135
+ }
136
+ case "compacted":
137
+ compactions++;
138
+ addGap("compaction/summary event");
139
+ break;
140
+ case "response_item": {
141
+ const ptype = payload.type;
142
+ if (ptype === "message") {
143
+ const role = payload.role === "user" ? "user" : payload.role === "assistant" ? "assistant" : undefined;
144
+ const text = contentText(payload.content);
145
+ if (!role || !text) {
146
+ addGap("empty turn");
147
+ break;
148
+ }
149
+ if (role === "user" && INJECTED_USER_RE.test(text)) {
150
+ addGap("injected context message");
151
+ break;
152
+ }
153
+ if (role === "assistant" && pendingActions.length > 0) {
154
+ // Attach the actions Codex logged since the last prose turn.
155
+ turns.push({
156
+ role,
157
+ text,
158
+ actions: pendingActions,
159
+ timestamp: rec.timestamp ? Date.parse(rec.timestamp) : undefined,
160
+ });
161
+ pendingActions = [];
162
+ }
163
+ else {
164
+ flushActions();
165
+ turns.push({
166
+ role,
167
+ text,
168
+ actions: [],
169
+ timestamp: rec.timestamp ? Date.parse(rec.timestamp) : undefined,
170
+ });
171
+ }
172
+ }
173
+ else if (ptype === "function_call") {
174
+ const name = typeof payload.name === "string" ? payload.name : "unknown";
175
+ const actions = functionCallActions(name, payload.arguments);
176
+ pendingActions.push(...actions);
177
+ for (const a of actions) {
178
+ if (a.path && !filesSeen.has(a.path)) {
179
+ filesSeen.add(a.path);
180
+ filesOrdered.push(a.path);
181
+ }
182
+ }
183
+ }
184
+ else if (ptype === "local_shell_call") {
185
+ const command = commandFrom(payload.action);
186
+ pendingActions.push({ kind: "run", rawName: "local_shell_call", command });
187
+ }
188
+ else {
189
+ addGap(`non-conversational response item (${String(ptype ?? "unknown")})`);
190
+ }
191
+ break;
192
+ }
193
+ case "event_msg":
194
+ // Duplicates of message content as UI events — skip to avoid doubled turns.
195
+ addGap("ui event record");
196
+ break;
197
+ default:
198
+ addGap(`non-message record (${rec.type ?? "unknown"})`);
199
+ }
200
+ }
201
+ flushActions();
202
+ provenance.compactions = compactions;
203
+ const gaps = [...gapCounts.entries()].map(([reason, count]) => ({ reason, count }));
204
+ return {
205
+ nsfVersion: NSF_VERSION,
206
+ provenance,
207
+ turns,
208
+ filesTouched: filesOrdered,
209
+ gaps,
210
+ };
211
+ }
212
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/parsers/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Cursor parser: global state.vscdb (SQLite) -> NSF.
3
+ *
4
+ * Grounded in the REAL on-disk schema (verified 2026-07-15 against a live
5
+ * Cursor install), not a guess:
6
+ * - DB: <appdata>/Cursor/User/globalStorage/state.vscdb
7
+ * - Table `composerHeaders` (composerId, workspaceId, lastUpdatedAt,
8
+ * isSubagent, recency, value JSON) — value carries `name` (the chat title),
9
+ * `workspaceIdentifier.uri.fsPath` (cwd) and `trackedGitRepos[].branches`.
10
+ * - Table `cursorDiskKV`:
11
+ * key `composerData:<composerId>` -> { fullConversationHeadersOnly:
12
+ * [{bubbleId, type}] } — the ordered conversation.
13
+ * key `bubbleId:<composerId>:<bubbleId>` -> the message:
14
+ * { type: 1(user)|2(assistant), text, createdAt (ISO),
15
+ * toolFormerData?: { name, rawArgs, status } }.
16
+ *
17
+ * Uses node:sqlite (built-in, Node >= 22.5) — read-only, no native deps. The
18
+ * DB can be multi-GB, so bubbles are fetched by key, never table-scanned.
19
+ */
20
+ import type { NsfSession } from "../nsf.js";
21
+ export declare const CURSOR_TOOL_ID = "cursor";
22
+ export declare function cursorDbPath(): string;
23
+ /** Newest non-subagent Cursor conversation for a working directory, if any. */
24
+ export declare function findCursorComposer(cwd: string): {
25
+ composerId: string;
26
+ mtimeMs: number;
27
+ } | undefined;
28
+ /**
29
+ * Parse one Cursor conversation into NSF.
30
+ * @param dbPath absolute path to Cursor's global state.vscdb
31
+ * @param composerId the conversation to parse (from findCursorComposer)
32
+ */
33
+ export declare function parseCursor(dbPath: string, composerId: string): NsfSession;