@nocoo/pew 0.8.0 → 1.1.1

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.
Files changed (84) hide show
  1. package/dist/cli.js +3 -3
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/login.js +1 -1
  4. package/dist/commands/login.js.map +1 -1
  5. package/dist/commands/session-sync.d.ts +4 -0
  6. package/dist/commands/session-sync.d.ts.map +1 -1
  7. package/dist/commands/session-sync.js +97 -317
  8. package/dist/commands/session-sync.js.map +1 -1
  9. package/dist/commands/sync.d.ts.map +1 -1
  10. package/dist/commands/sync.js +112 -330
  11. package/dist/commands/sync.js.map +1 -1
  12. package/dist/drivers/registry.d.ts +63 -0
  13. package/dist/drivers/registry.d.ts.map +1 -0
  14. package/dist/drivers/registry.js +88 -0
  15. package/dist/drivers/registry.js.map +1 -0
  16. package/dist/drivers/session/claude-session-driver.d.ts +10 -0
  17. package/dist/drivers/session/claude-session-driver.d.ts.map +1 -0
  18. package/dist/drivers/session/claude-session-driver.js +29 -0
  19. package/dist/drivers/session/claude-session-driver.js.map +1 -0
  20. package/dist/drivers/session/codex-session-driver.d.ts +10 -0
  21. package/dist/drivers/session/codex-session-driver.d.ts.map +1 -0
  22. package/dist/drivers/session/codex-session-driver.js +29 -0
  23. package/dist/drivers/session/codex-session-driver.js.map +1 -0
  24. package/dist/drivers/session/gemini-session-driver.d.ts +10 -0
  25. package/dist/drivers/session/gemini-session-driver.d.ts.map +1 -0
  26. package/dist/drivers/session/gemini-session-driver.js +29 -0
  27. package/dist/drivers/session/gemini-session-driver.js.map +1 -0
  28. package/dist/drivers/session/openclaw-session-driver.d.ts +10 -0
  29. package/dist/drivers/session/openclaw-session-driver.d.ts.map +1 -0
  30. package/dist/drivers/session/openclaw-session-driver.js +29 -0
  31. package/dist/drivers/session/openclaw-session-driver.js.map +1 -0
  32. package/dist/drivers/session/opencode-json-session-driver.d.ts +14 -0
  33. package/dist/drivers/session/opencode-json-session-driver.d.ts.map +1 -0
  34. package/dist/drivers/session/opencode-json-session-driver.js +51 -0
  35. package/dist/drivers/session/opencode-json-session-driver.js.map +1 -0
  36. package/dist/drivers/session/opencode-sqlite-session-driver.d.ts +23 -0
  37. package/dist/drivers/session/opencode-sqlite-session-driver.d.ts.map +1 -0
  38. package/dist/drivers/session/opencode-sqlite-session-driver.js +88 -0
  39. package/dist/drivers/session/opencode-sqlite-session-driver.js.map +1 -0
  40. package/dist/drivers/token/claude-token-driver.d.ts +11 -0
  41. package/dist/drivers/token/claude-token-driver.d.ts.map +1 -0
  42. package/dist/drivers/token/claude-token-driver.js +42 -0
  43. package/dist/drivers/token/claude-token-driver.js.map +1 -0
  44. package/dist/drivers/token/codex-token-driver.d.ts +11 -0
  45. package/dist/drivers/token/codex-token-driver.d.ts.map +1 -0
  46. package/dist/drivers/token/codex-token-driver.js +59 -0
  47. package/dist/drivers/token/codex-token-driver.js.map +1 -0
  48. package/dist/drivers/token/gemini-token-driver.d.ts +11 -0
  49. package/dist/drivers/token/gemini-token-driver.d.ts.map +1 -0
  50. package/dist/drivers/token/gemini-token-driver.js +57 -0
  51. package/dist/drivers/token/gemini-token-driver.js.map +1 -0
  52. package/dist/drivers/token/openclaw-token-driver.d.ts +11 -0
  53. package/dist/drivers/token/openclaw-token-driver.d.ts.map +1 -0
  54. package/dist/drivers/token/openclaw-token-driver.js +42 -0
  55. package/dist/drivers/token/openclaw-token-driver.js.map +1 -0
  56. package/dist/drivers/token/opencode-json-token-driver.d.ts +15 -0
  57. package/dist/drivers/token/opencode-json-token-driver.d.ts.map +1 -0
  58. package/dist/drivers/token/opencode-json-token-driver.js +73 -0
  59. package/dist/drivers/token/opencode-json-token-driver.js.map +1 -0
  60. package/dist/drivers/token/opencode-sqlite-token-driver.d.ts +25 -0
  61. package/dist/drivers/token/opencode-sqlite-token-driver.d.ts.map +1 -0
  62. package/dist/drivers/token/opencode-sqlite-token-driver.js +99 -0
  63. package/dist/drivers/token/opencode-sqlite-token-driver.js.map +1 -0
  64. package/dist/drivers/types.d.ts +202 -0
  65. package/dist/drivers/types.d.ts.map +1 -0
  66. package/dist/drivers/types.js +12 -0
  67. package/dist/drivers/types.js.map +1 -0
  68. package/dist/storage/base-cursor-store.d.ts +16 -0
  69. package/dist/storage/base-cursor-store.d.ts.map +1 -0
  70. package/dist/storage/base-cursor-store.js +33 -0
  71. package/dist/storage/base-cursor-store.js.map +1 -0
  72. package/dist/storage/cursor-store.d.ts +2 -6
  73. package/dist/storage/cursor-store.d.ts.map +1 -1
  74. package/dist/storage/cursor-store.js +4 -25
  75. package/dist/storage/cursor-store.js.map +1 -1
  76. package/dist/storage/session-cursor-store.d.ts +2 -6
  77. package/dist/storage/session-cursor-store.d.ts.map +1 -1
  78. package/dist/storage/session-cursor-store.js +4 -25
  79. package/dist/storage/session-cursor-store.js.map +1 -1
  80. package/dist/utils/file-changed.d.ts +35 -0
  81. package/dist/utils/file-changed.d.ts.map +1 -0
  82. package/dist/utils/file-changed.js +34 -0
  83. package/dist/utils/file-changed.js.map +1 -0
  84. package/package.json +2 -2
@@ -0,0 +1,33 @@
1
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ /**
4
+ * Generic base class for persisting cursor state to disk as JSON.
5
+ *
6
+ * Both `CursorStore` (token cursors) and `SessionCursorStore` (session cursors)
7
+ * share identical load/save logic — only the filename and empty-state factory differ.
8
+ */
9
+ export class BaseCursorStore {
10
+ filePath;
11
+ emptyState;
12
+ constructor(filePath, emptyState) {
13
+ this.filePath = filePath;
14
+ this.emptyState = emptyState;
15
+ }
16
+ /** Load cursor state from disk. Returns empty state if file doesn't exist or is corrupted. */
17
+ async load() {
18
+ try {
19
+ const raw = await readFile(this.filePath, "utf-8");
20
+ return JSON.parse(raw);
21
+ }
22
+ catch {
23
+ return this.emptyState();
24
+ }
25
+ }
26
+ /** Save cursor state to disk, creating the directory if needed. */
27
+ async save(state) {
28
+ const dir = dirname(this.filePath);
29
+ await mkdir(dir, { recursive: true });
30
+ await writeFile(this.filePath, JSON.stringify(state, null, 2) + "\n");
31
+ }
32
+ }
33
+ //# sourceMappingURL=base-cursor-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-cursor-store.js","sourceRoot":"","sources":["../../src/storage/base-cursor-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IACjB,QAAQ,CAAS;IACT,UAAU,CAAU;IAErC,YAAY,QAAgB,EAAE,UAAmB;QAC/C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,8FAA8F;IAC9F,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,IAAI,CAAC,KAAQ;QACjB,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxE,CAAC;CACF"}
@@ -1,14 +1,10 @@
1
1
  import type { CursorState } from "@pew/core";
2
+ import { BaseCursorStore } from "./base-cursor-store.js";
2
3
  /**
3
4
  * Persists incremental parsing cursors to disk.
4
5
  * Stored at ~/.config/pew/cursors.json
5
6
  */
6
- export declare class CursorStore {
7
- readonly filePath: string;
7
+ export declare class CursorStore extends BaseCursorStore<CursorState> {
8
8
  constructor(storeDir: string);
9
- /** Load cursor state from disk. Returns empty state if file doesn't exist or is corrupted. */
10
- load(): Promise<CursorState>;
11
- /** Save cursor state to disk, creating the directory if needed. */
12
- save(state: CursorState): Promise<void>;
13
9
  }
14
10
  //# sourceMappingURL=cursor-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-store.d.ts","sourceRoot":"","sources":["../../src/storage/cursor-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAS7C;;;GAGG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;IAI5B,8FAA8F;IACxF,IAAI,IAAI,OAAO,CAAC,WAAW,CAAC;IASlC,mEAAmE;IAC7D,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAK9C"}
1
+ {"version":3,"file":"cursor-store.d.ts","sourceRoot":"","sources":["../../src/storage/cursor-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD;;;GAGG;AACH,qBAAa,WAAY,SAAQ,eAAe,CAAC,WAAW,CAAC;gBAC/C,QAAQ,EAAE,MAAM;CAM7B"}
@@ -1,34 +1,13 @@
1
- import { readFile, writeFile, mkdir } from "node:fs/promises";
2
- import { join, dirname } from "node:path";
1
+ import { join } from "node:path";
2
+ import { BaseCursorStore } from "./base-cursor-store.js";
3
3
  const CURSORS_FILE = "cursors.json";
4
- /** Creates a fresh empty cursor state */
5
- function emptyCursorState() {
6
- return { version: 1, files: {}, updatedAt: null };
7
- }
8
4
  /**
9
5
  * Persists incremental parsing cursors to disk.
10
6
  * Stored at ~/.config/pew/cursors.json
11
7
  */
12
- export class CursorStore {
13
- filePath;
8
+ export class CursorStore extends BaseCursorStore {
14
9
  constructor(storeDir) {
15
- this.filePath = join(storeDir, CURSORS_FILE);
16
- }
17
- /** Load cursor state from disk. Returns empty state if file doesn't exist or is corrupted. */
18
- async load() {
19
- try {
20
- const raw = await readFile(this.filePath, "utf-8");
21
- return JSON.parse(raw);
22
- }
23
- catch {
24
- return emptyCursorState();
25
- }
26
- }
27
- /** Save cursor state to disk, creating the directory if needed. */
28
- async save(state) {
29
- const dir = dirname(this.filePath);
30
- await mkdir(dir, { recursive: true });
31
- await writeFile(this.filePath, JSON.stringify(state, null, 2) + "\n");
10
+ super(join(storeDir, CURSORS_FILE), () => ({ version: 1, files: {}, updatedAt: null }));
32
11
  }
33
12
  }
34
13
  //# sourceMappingURL=cursor-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-store.js","sourceRoot":"","sources":["../../src/storage/cursor-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,YAAY,GAAG,cAAc,CAAC;AAEpC,yCAAyC;AACzC,SAAS,gBAAgB;IACvB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,WAAW;IACb,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,8FAA8F;IAC9F,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,gBAAgB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,IAAI,CAAC,KAAkB;QAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxE,CAAC;CACF"}
1
+ {"version":3,"file":"cursor-store.js","sourceRoot":"","sources":["../../src/storage/cursor-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,YAAY,GAAG,cAAc,CAAC;AAEpC;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,eAA4B;IAC3D,YAAY,QAAgB;QAC1B,KAAK,CACH,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,EAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CACnD,CAAC;IACJ,CAAC;CACF"}
@@ -1,14 +1,10 @@
1
1
  import type { SessionCursorState } from "@pew/core";
2
+ import { BaseCursorStore } from "./base-cursor-store.js";
2
3
  /**
3
4
  * Persists session file cursors (mtime + size dual-check) to disk.
4
5
  * Stored at ~/.config/pew/session-cursors.json
5
6
  */
6
- export declare class SessionCursorStore {
7
- readonly filePath: string;
7
+ export declare class SessionCursorStore extends BaseCursorStore<SessionCursorState> {
8
8
  constructor(storeDir: string);
9
- /** Load cursor state from disk. Returns empty state if file doesn't exist or is corrupted. */
10
- load(): Promise<SessionCursorState>;
11
- /** Save cursor state to disk, creating the directory if needed. */
12
- save(state: SessionCursorState): Promise<void>;
13
9
  }
14
10
  //# sourceMappingURL=session-cursor-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-cursor-store.d.ts","sourceRoot":"","sources":["../../src/storage/session-cursor-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AASpD;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;IAI5B,8FAA8F;IACxF,IAAI,IAAI,OAAO,CAAC,kBAAkB,CAAC;IASzC,mEAAmE;IAC7D,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CAKrD"}
1
+ {"version":3,"file":"session-cursor-store.d.ts","sourceRoot":"","sources":["../../src/storage/session-cursor-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,eAAe,CAAC,kBAAkB,CAAC;gBAC7D,QAAQ,EAAE,MAAM;CAM7B"}
@@ -1,34 +1,13 @@
1
- import { readFile, writeFile, mkdir } from "node:fs/promises";
2
- import { join, dirname } from "node:path";
1
+ import { join } from "node:path";
2
+ import { BaseCursorStore } from "./base-cursor-store.js";
3
3
  const CURSORS_FILE = "session-cursors.json";
4
- /** Creates a fresh empty session cursor state */
5
- function emptyCursorState() {
6
- return { version: 1, files: {}, updatedAt: null };
7
- }
8
4
  /**
9
5
  * Persists session file cursors (mtime + size dual-check) to disk.
10
6
  * Stored at ~/.config/pew/session-cursors.json
11
7
  */
12
- export class SessionCursorStore {
13
- filePath;
8
+ export class SessionCursorStore extends BaseCursorStore {
14
9
  constructor(storeDir) {
15
- this.filePath = join(storeDir, CURSORS_FILE);
16
- }
17
- /** Load cursor state from disk. Returns empty state if file doesn't exist or is corrupted. */
18
- async load() {
19
- try {
20
- const raw = await readFile(this.filePath, "utf-8");
21
- return JSON.parse(raw);
22
- }
23
- catch {
24
- return emptyCursorState();
25
- }
26
- }
27
- /** Save cursor state to disk, creating the directory if needed. */
28
- async save(state) {
29
- const dir = dirname(this.filePath);
30
- await mkdir(dir, { recursive: true });
31
- await writeFile(this.filePath, JSON.stringify(state, null, 2) + "\n");
10
+ super(join(storeDir, CURSORS_FILE), () => ({ version: 1, files: {}, updatedAt: null }));
32
11
  }
33
12
  }
34
13
  //# sourceMappingURL=session-cursor-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-cursor-store.js","sourceRoot":"","sources":["../../src/storage/session-cursor-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAE5C,iDAAiD;AACjD,SAAS,gBAAgB;IACvB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IACpB,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,8FAA8F;IAC9F,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAuB,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,gBAAgB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,IAAI,CAAC,KAAyB;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxE,CAAC;CACF"}
1
+ {"version":3,"file":"session-cursor-store.js","sourceRoot":"","sources":["../../src/storage/session-cursor-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAE5C;;;GAGG;AACH,MAAM,OAAO,kBAAmB,SAAQ,eAAmC;IACzE,YAAY,QAAgB;QAC1B,KAAK,CACH,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,EAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CACnD,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Fast-skip change detection for file-based cursors.
3
+ *
4
+ * Compares inode + mtimeMs + size to detect whether a file has changed
5
+ * since the last cursor was written. All three must match for the file
6
+ * to be considered unchanged.
7
+ *
8
+ * This replaces the scattered inline checks across sync.ts and the
9
+ * session-sync.ts `fileChanged()` helper.
10
+ */
11
+ /** Minimal fingerprint needed for change detection */
12
+ export interface FileFingerprint {
13
+ inode: number;
14
+ mtimeMs: number;
15
+ size: number;
16
+ }
17
+ /**
18
+ * Returns true if the file has NOT changed since the cursor was written.
19
+ *
20
+ * A file is unchanged when all three fields match:
21
+ * - inode (same physical file — detects rotation/replacement)
22
+ * - mtimeMs (no writes since last scan)
23
+ * - size (paranoia — catches in-place overwrites with same mtime)
24
+ *
25
+ * Returns false (= file changed) when:
26
+ * - prev is undefined (first scan, no cursor yet)
27
+ * - prev is missing mtimeMs/size (old cursor format, gradual migration)
28
+ * - any of the three fields differ
29
+ */
30
+ export declare function fileUnchanged(prev: {
31
+ inode: number;
32
+ mtimeMs?: number;
33
+ size?: number;
34
+ } | undefined, curr: FileFingerprint): boolean;
35
+ //# sourceMappingURL=file-changed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-changed.d.ts","sourceRoot":"","sources":["../../src/utils/file-changed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACpE,IAAI,EAAE,eAAe,GACpB,OAAO,CAST"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Fast-skip change detection for file-based cursors.
3
+ *
4
+ * Compares inode + mtimeMs + size to detect whether a file has changed
5
+ * since the last cursor was written. All three must match for the file
6
+ * to be considered unchanged.
7
+ *
8
+ * This replaces the scattered inline checks across sync.ts and the
9
+ * session-sync.ts `fileChanged()` helper.
10
+ */
11
+ /**
12
+ * Returns true if the file has NOT changed since the cursor was written.
13
+ *
14
+ * A file is unchanged when all three fields match:
15
+ * - inode (same physical file — detects rotation/replacement)
16
+ * - mtimeMs (no writes since last scan)
17
+ * - size (paranoia — catches in-place overwrites with same mtime)
18
+ *
19
+ * Returns false (= file changed) when:
20
+ * - prev is undefined (first scan, no cursor yet)
21
+ * - prev is missing mtimeMs/size (old cursor format, gradual migration)
22
+ * - any of the three fields differ
23
+ */
24
+ export function fileUnchanged(prev, curr) {
25
+ if (!prev)
26
+ return false;
27
+ // Old cursors may lack mtimeMs/size — treat as changed for gradual migration
28
+ if (prev.mtimeMs === undefined || prev.size === undefined)
29
+ return false;
30
+ return (prev.inode === curr.inode &&
31
+ prev.mtimeMs === curr.mtimeMs &&
32
+ prev.size === curr.size);
33
+ }
34
+ //# sourceMappingURL=file-changed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-changed.js","sourceRoot":"","sources":["../../src/utils/file-changed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAoE,EACpE,IAAqB;IAErB,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,6EAA6E;IAC7E,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxE,OAAO,CACL,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK;QACzB,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO;QAC7B,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CACxB,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nocoo/pew",
3
- "version": "0.8.0",
4
- "description": "Track token usage from your local AI coding tools",
3
+ "version": "1.1.1",
4
+ "description": "The contribution graph for AI-native developers",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "pew": "dist/bin.js"