pi-harness-runtime 0.9.6 → 0.9.10

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 (134) hide show
  1. package/CHANGELOG.md +41 -10
  2. package/README.md +42 -5
  3. package/footer-status.ts +108 -11
  4. package/harness/e2e/minimax-quota-scraper.ts +46 -4
  5. package/index.ts +272 -16
  6. package/mirror.ts +194 -18
  7. package/package.json +1 -1
  8. package/packages/a2a-adapter/package.json +1 -1
  9. package/packages/auth/package.json +1 -1
  10. package/packages/autonomous-refactor/package.json +1 -1
  11. package/packages/cache-strategy/package.json +1 -1
  12. package/packages/capability-registry/package.json +1 -1
  13. package/packages/checkpoint/package.json +1 -1
  14. package/packages/cli-plugin-sdk/package.json +1 -1
  15. package/packages/code-generation/package.json +1 -1
  16. package/packages/code-review/package.json +1 -1
  17. package/packages/codex-adapter/package.json +1 -1
  18. package/packages/context-compiler/package.json +1 -1
  19. package/packages/context-manager/package.json +1 -1
  20. package/packages/cookie-sanitizer/README.md +141 -0
  21. package/packages/cookie-sanitizer/dist/atomic-write.d.ts +38 -0
  22. package/packages/cookie-sanitizer/dist/atomic-write.d.ts.map +1 -0
  23. package/packages/cookie-sanitizer/dist/atomic-write.js +67 -0
  24. package/packages/cookie-sanitizer/dist/atomic-write.js.map +1 -0
  25. package/packages/cookie-sanitizer/dist/detect-format.d.ts +36 -0
  26. package/packages/cookie-sanitizer/dist/detect-format.d.ts.map +1 -0
  27. package/packages/cookie-sanitizer/dist/detect-format.js +88 -0
  28. package/packages/cookie-sanitizer/dist/detect-format.js.map +1 -0
  29. package/packages/cookie-sanitizer/dist/index.d.ts +41 -0
  30. package/packages/cookie-sanitizer/dist/index.d.ts.map +1 -0
  31. package/packages/cookie-sanitizer/dist/index.js +39 -0
  32. package/packages/cookie-sanitizer/dist/index.js.map +1 -0
  33. package/packages/cookie-sanitizer/dist/infer-provider.d.ts +29 -0
  34. package/packages/cookie-sanitizer/dist/infer-provider.d.ts.map +1 -0
  35. package/packages/cookie-sanitizer/dist/infer-provider.js +96 -0
  36. package/packages/cookie-sanitizer/dist/infer-provider.js.map +1 -0
  37. package/packages/cookie-sanitizer/dist/normalize.d.ts +26 -0
  38. package/packages/cookie-sanitizer/dist/normalize.d.ts.map +1 -0
  39. package/packages/cookie-sanitizer/dist/normalize.js +75 -0
  40. package/packages/cookie-sanitizer/dist/normalize.js.map +1 -0
  41. package/packages/cookie-sanitizer/dist/parse-json.d.ts +45 -0
  42. package/packages/cookie-sanitizer/dist/parse-json.d.ts.map +1 -0
  43. package/packages/cookie-sanitizer/dist/parse-json.js +108 -0
  44. package/packages/cookie-sanitizer/dist/parse-json.js.map +1 -0
  45. package/packages/cookie-sanitizer/dist/parse-netscape.d.ts +43 -0
  46. package/packages/cookie-sanitizer/dist/parse-netscape.d.ts.map +1 -0
  47. package/packages/cookie-sanitizer/dist/parse-netscape.js +99 -0
  48. package/packages/cookie-sanitizer/dist/parse-netscape.js.map +1 -0
  49. package/packages/cookie-sanitizer/dist/sync.d.ts +62 -0
  50. package/packages/cookie-sanitizer/dist/sync.d.ts.map +1 -0
  51. package/packages/cookie-sanitizer/dist/sync.js +266 -0
  52. package/packages/cookie-sanitizer/dist/sync.js.map +1 -0
  53. package/packages/cookie-sanitizer/dist/types.d.ts +100 -0
  54. package/packages/cookie-sanitizer/dist/types.d.ts.map +1 -0
  55. package/packages/cookie-sanitizer/dist/types.js +13 -0
  56. package/packages/cookie-sanitizer/dist/types.js.map +1 -0
  57. package/packages/cookie-sanitizer/dist/watcher.d.ts +51 -0
  58. package/packages/cookie-sanitizer/dist/watcher.d.ts.map +1 -0
  59. package/packages/cookie-sanitizer/dist/watcher.js +148 -0
  60. package/packages/cookie-sanitizer/dist/watcher.js.map +1 -0
  61. package/packages/cookie-sanitizer/package.json +27 -0
  62. package/packages/cookie-sanitizer/src/atomic-write.ts +79 -0
  63. package/packages/cookie-sanitizer/src/detect-format.ts +102 -0
  64. package/packages/cookie-sanitizer/src/index.ts +89 -0
  65. package/packages/cookie-sanitizer/src/infer-provider.ts +103 -0
  66. package/packages/cookie-sanitizer/src/normalize.ts +92 -0
  67. package/packages/cookie-sanitizer/src/parse-json.ts +122 -0
  68. package/packages/cookie-sanitizer/src/parse-netscape.ts +118 -0
  69. package/packages/cookie-sanitizer/src/sync.ts +304 -0
  70. package/packages/cookie-sanitizer/src/types.ts +101 -0
  71. package/packages/cookie-sanitizer/src/watcher.ts +180 -0
  72. package/packages/cookie-sanitizer/test/infer.test.ts +110 -0
  73. package/packages/cookie-sanitizer/test/normalize.test.ts +113 -0
  74. package/packages/cookie-sanitizer/test/parse.test.ts +204 -0
  75. package/packages/cookie-sanitizer/test/sync.test.ts +231 -0
  76. package/packages/cookie-sanitizer/test/watcher.test.ts +27 -0
  77. package/packages/cookie-sanitizer/tsconfig.json +8 -0
  78. package/packages/cost-optimizer/package.json +1 -1
  79. package/packages/django-plugin/package.json +1 -1
  80. package/packages/doc-generator/package.json +1 -1
  81. package/packages/evaluation-engine/package.json +1 -1
  82. package/packages/evaluation-runner/package.json +1 -1
  83. package/packages/experience-replay/package.json +1 -1
  84. package/packages/feedback-collector/package.json +1 -1
  85. package/packages/framework-detector/package.json +1 -1
  86. package/packages/framework-plugin-sdk/package.json +1 -1
  87. package/packages/frappe-plugin/package.json +1 -1
  88. package/packages/generic-web-plugin/package.json +1 -1
  89. package/packages/health-monitor/package.json +1 -1
  90. package/packages/laravel-plugin/package.json +1 -1
  91. package/packages/learning-engine/package.json +1 -1
  92. package/packages/mcp-adapter/package.json +1 -1
  93. package/packages/memory-engine/package.json +1 -1
  94. package/packages/model-registry/package.json +1 -1
  95. package/packages/nextjs-plugin/package.json +1 -1
  96. package/packages/notification/package.json +1 -1
  97. package/packages/observability/package.json +1 -1
  98. package/packages/performance-optimizer/package.json +1 -1
  99. package/packages/project-analyzer/package.json +1 -1
  100. package/packages/prompt-compiler/package.json +1 -1
  101. package/packages/prompt-versioning/package.json +1 -1
  102. package/packages/provider-adapter-sdk/package.json +1 -1
  103. package/packages/provider-router/package.json +1 -1
  104. package/packages/provider-selector/package.json +1 -1
  105. package/packages/providers/dist/index.d.ts +1 -0
  106. package/packages/providers/dist/index.d.ts.map +1 -1
  107. package/packages/providers/dist/index.js +1 -0
  108. package/packages/providers/dist/index.js.map +1 -1
  109. package/packages/providers/dist/provider-id.d.ts +39 -0
  110. package/packages/providers/dist/provider-id.d.ts.map +1 -0
  111. package/packages/providers/dist/provider-id.js +96 -0
  112. package/packages/providers/dist/provider-id.js.map +1 -0
  113. package/packages/providers/package.json +1 -1
  114. package/packages/providers/src/index.ts +1 -0
  115. package/packages/providers/src/provider-id.ts +110 -0
  116. package/packages/quota-manager/package.json +1 -1
  117. package/packages/rate-limiter/package.json +1 -1
  118. package/packages/react-vite-plugin/package.json +1 -1
  119. package/packages/release-manager/package.json +1 -1
  120. package/packages/requirement-compiler/package.json +1 -1
  121. package/packages/runtime/package.json +1 -1
  122. package/packages/scheduler/package.json +1 -1
  123. package/packages/session/package.json +1 -1
  124. package/packages/shared-context/package.json +1 -1
  125. package/packages/skill-registry/package.json +1 -1
  126. package/packages/sprint-planner/package.json +1 -1
  127. package/packages/task-compiler/package.json +1 -1
  128. package/packages/test-data-generator/package.json +1 -1
  129. package/packages/test-generator/package.json +1 -1
  130. package/packages/token-estimation/package.json +1 -1
  131. package/packages/token-optimizer/package.json +1 -1
  132. package/packages/tui/package.json +1 -1
  133. package/packages/types/package.json +1 -1
  134. package/packages/worktree/package.json +1 -1
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Provider inference — figure out which provider a cookie dump belongs to
3
+ * without the user having to organize by subfolder.
4
+ *
5
+ * Three inference passes, first hit wins:
6
+ * 1. Filename hint (e.g. `minimax-*.txt`, `*minimax.json` → "minimax")
7
+ * 2. Dominant domain (≥ 80% of cookies on `*.minimax.io` → "minimax")
8
+ * 3. Nothing → null (caller will surface a friendly error)
9
+ *
10
+ * Provider hint from SyncOptions overrides all of the above.
11
+ */
12
+ const FILENAME_HINTS = [
13
+ { pattern: /minimax/i, provider: "minimax" },
14
+ { pattern: /anthropic|claude/i, provider: "anthropic" },
15
+ { pattern: /openai|gpt|chatgpt/i, provider: "openai" },
16
+ { pattern: /glm|z\.ai|zhipuai/i, provider: "glm" },
17
+ { pattern: /openrouter/i, provider: "openrouter" },
18
+ ];
19
+ const DOMAIN_HINTS = [
20
+ { pattern: /\.minimax\.io$|^minimax\.io$/i, provider: "minimax" },
21
+ { pattern: /\.anthropic\.com$|^anthropic\.com$/i, provider: "anthropic" },
22
+ {
23
+ pattern: /\.openai\.com$|^openai\.com$|\.chatgpt\.com$|^chatgpt\.com$/i,
24
+ provider: "openai",
25
+ },
26
+ {
27
+ pattern: /\.z\.ai$|^z\.ai$|\.zhipuai\.cn$|^zhipuai\.cn$/i,
28
+ provider: "glm",
29
+ },
30
+ { pattern: /\.openrouter\.ai$|^openrouter\.ai$/i, provider: "openrouter" },
31
+ ];
32
+ /** Returns the first provider whose filename pattern matches, or null. */
33
+ export function inferProviderFromFilename(filename) {
34
+ if (!filename)
35
+ return null;
36
+ for (const { pattern, provider } of FILENAME_HINTS) {
37
+ if (pattern.test(filename))
38
+ return provider;
39
+ }
40
+ return null;
41
+ }
42
+ /** Returns the provider whose domain is the dominant (≥ 80%) match. */
43
+ export function inferProviderFromCookies(cookies) {
44
+ if (!Array.isArray(cookies) || cookies.length === 0)
45
+ return null;
46
+ const counts = new Map();
47
+ let total = 0;
48
+ for (const c of cookies) {
49
+ if (!c.domain)
50
+ continue;
51
+ total += 1;
52
+ for (const { pattern, provider } of DOMAIN_HINTS) {
53
+ if (pattern.test(c.domain.toLowerCase())) {
54
+ counts.set(provider, (counts.get(provider) ?? 0) + 1);
55
+ break;
56
+ }
57
+ }
58
+ }
59
+ if (total === 0)
60
+ return null;
61
+ const threshold = Math.ceil(total * 0.8); // ≥ 80 %
62
+ let best = null;
63
+ for (const [provider, count] of counts) {
64
+ if (count >= threshold && (!best || count > best.count)) {
65
+ best = { provider, count };
66
+ }
67
+ }
68
+ return best?.provider ?? null;
69
+ }
70
+ /**
71
+ * Combined inference: hint → filename → dominant domain → null.
72
+ *
73
+ * If `filename` is provided it takes priority over domain inference
74
+ * (filename hints are explicit). Domain inference is the fallback.
75
+ */
76
+ export function inferProvider(filename, cookies, hint) {
77
+ if (hint)
78
+ return hint;
79
+ if (filename) {
80
+ const fromName = inferProviderFromFilename(filename);
81
+ if (fromName)
82
+ return fromName;
83
+ }
84
+ return inferProviderFromCookies(cookies);
85
+ }
86
+ /**
87
+ * Build a list of provider rules used by other parts of the package.
88
+ * Exposed for UI display (e.g. "which providers does this sanitizer know?").
89
+ */
90
+ export function knownProviders() {
91
+ const set = new Set();
92
+ for (const { provider } of FILENAME_HINTS)
93
+ set.add(provider);
94
+ return Array.from(set);
95
+ }
96
+ //# sourceMappingURL=infer-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infer-provider.js","sourceRoot":"","sources":["../src/infer-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Normalize step — dedupe, drop invalid/expired, set provider.
3
+ *
4
+ * Rules (applied in order):
5
+ * 1. Drop cookies with empty `name` or `value`.
6
+ * 2. Drop cookies whose domain doesn't match the inferred provider.
7
+ * 3. Drop expired cookies (expires in the past, not session).
8
+ * 4. Dedupe by `(domain, name)` — keep the LAST entry (most recent wins).
9
+ * 5. Mark each surviving cookie with the provider id.
10
+ *
11
+ * SEC-001: Cookie values are not touched here, but never logged.
12
+ */
13
+ import type { CanonicalCookie, ProviderId } from "./types.js";
14
+ /** Returns true if the cookie's domain matches the given provider's domain scope. */
15
+ export declare function domainMatchesProvider(domain: string, provider: ProviderId): boolean;
16
+ /** Returns true if the cookie is expired (in the past). Session cookies never expire. */
17
+ export declare function isExpired(cookie: CanonicalCookie, nowSec?: number): boolean;
18
+ /**
19
+ * Normalize the union of all parsed cookies.
20
+ *
21
+ * @param cookies Raw cookies from all parsed files
22
+ * @param provider Inferred (or hinted) provider; used for domain filtering and tagging
23
+ * @param nowSec Override for the current Unix seconds (test seam)
24
+ */
25
+ export declare function normalize(cookies: CanonicalCookie[], provider: ProviderId, nowSec?: number): CanonicalCookie[];
26
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9D,qFAAqF;AACrF,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,UAAU,GAClB,OAAO,CA4BT;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CACxB,MAAM,EAAE,eAAe,EACvB,MAAM,GAAE,MAAsC,GAC5C,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,eAAe,EAAE,EAC1B,QAAQ,EAAE,UAAU,EACpB,MAAM,GAAE,MAAsC,GAC5C,eAAe,EAAE,CAqBnB"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Normalize step — dedupe, drop invalid/expired, set provider.
3
+ *
4
+ * Rules (applied in order):
5
+ * 1. Drop cookies with empty `name` or `value`.
6
+ * 2. Drop cookies whose domain doesn't match the inferred provider.
7
+ * 3. Drop expired cookies (expires in the past, not session).
8
+ * 4. Dedupe by `(domain, name)` — keep the LAST entry (most recent wins).
9
+ * 5. Mark each surviving cookie with the provider id.
10
+ *
11
+ * SEC-001: Cookie values are not touched here, but never logged.
12
+ */
13
+ /** Returns true if the cookie's domain matches the given provider's domain scope. */
14
+ export function domainMatchesProvider(domain, provider) {
15
+ if (!domain)
16
+ return false;
17
+ const d = domain.toLowerCase();
18
+ switch (provider) {
19
+ case "minimax":
20
+ return d === "minimax.io" || d.endsWith(".minimax.io");
21
+ case "anthropic":
22
+ return d === "anthropic.com" || d.endsWith(".anthropic.com");
23
+ case "openai":
24
+ return (d === "openai.com" ||
25
+ d.endsWith(".openai.com") ||
26
+ d === "chatgpt.com" ||
27
+ d.endsWith(".chatgpt.com"));
28
+ case "glm":
29
+ return (d === "z.ai" ||
30
+ d.endsWith(".z.ai") ||
31
+ d === "zhipuai.cn" ||
32
+ d.endsWith(".zhipuai.cn"));
33
+ case "openrouter":
34
+ return d === "openrouter.ai" || d.endsWith(".openrouter.ai");
35
+ default:
36
+ // Unknown provider — accept all and let downstream reject.
37
+ return true;
38
+ }
39
+ }
40
+ /** Returns true if the cookie is expired (in the past). Session cookies never expire. */
41
+ export function isExpired(cookie, nowSec = Math.floor(Date.now() / 1000)) {
42
+ if (cookie.expires == null)
43
+ return false; // session cookie
44
+ if (cookie.expires <= 0)
45
+ return false; // 0 = session in Netscape
46
+ return cookie.expires < nowSec;
47
+ }
48
+ /**
49
+ * Normalize the union of all parsed cookies.
50
+ *
51
+ * @param cookies Raw cookies from all parsed files
52
+ * @param provider Inferred (or hinted) provider; used for domain filtering and tagging
53
+ * @param nowSec Override for the current Unix seconds (test seam)
54
+ */
55
+ export function normalize(cookies, provider, nowSec = Math.floor(Date.now() / 1000)) {
56
+ if (!Array.isArray(cookies) || cookies.length === 0)
57
+ return [];
58
+ const dedup = new Map();
59
+ for (const c of cookies) {
60
+ // Rule 1: empty fields.
61
+ if (!c.name || !c.value)
62
+ continue;
63
+ // Rule 2: domain must match provider (skip for unknown provider).
64
+ if (provider && !domainMatchesProvider(c.domain, provider))
65
+ continue;
66
+ // Rule 3: expired.
67
+ if (isExpired(c, nowSec))
68
+ continue;
69
+ // Rule 4 + 5: dedupe by (domain, name); last wins. Tag with provider.
70
+ const key = `${c.domain}::${c.name}`;
71
+ dedup.set(key, { ...c, provider });
72
+ }
73
+ return Array.from(dedup.values());
74
+ }
75
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,qFAAqF;AACrF,MAAM,UAAU,qBAAqB,CACpC,MAAc,EACd,QAAoB;IAEpB,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,QAAQ,QAAQ,EAAE,CAAC;QAClB,KAAK,SAAS;YACb,OAAO,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QACxD,KAAK,WAAW;YACf,OAAO,CAAC,KAAK,eAAe,IAAI,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QAC9D,KAAK,QAAQ;YACZ,OAAO,CACN,CAAC,KAAK,YAAY;gBAClB,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;gBACzB,CAAC,KAAK,aAAa;gBACnB,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAC1B,CAAC;QACH,KAAK,KAAK;YACT,OAAO,CACN,CAAC,KAAK,MAAM;gBACZ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACnB,CAAC,KAAK,YAAY;gBAClB,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CACzB,CAAC;QACH,KAAK,YAAY;YAChB,OAAO,CAAC,KAAK,eAAe,IAAI,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QAC9D;YACC,2DAA2D;YAC3D,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,SAAS,CACxB,MAAuB,EACvB,MAAM,GAAW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAE9C,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC,CAAC,iBAAiB;IAC3D,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,0BAA0B;IACjE,OAAO,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACxB,OAA0B,EAC1B,QAAoB,EACpB,MAAM,GAAW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAE9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE/D,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEjD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACzB,wBAAwB;QACxB,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,SAAS;QAElC,kEAAkE;QAClE,IAAI,QAAQ,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC;YAAE,SAAS;QAErE,mBAAmB;QACnB,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC;YAAE,SAAS;QAEnC,sEAAsE;QACtE,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * EditThisCookie / Chrome devtools JSON cookie export parser.
3
+ *
4
+ * Browser extension "EditThisCookie" and Chrome devtools both export
5
+ * cookies in this canonical shape (Chrome/Edge/Chromium cookie store):
6
+ *
7
+ * ```json
8
+ * [
9
+ * {
10
+ * "domain": ".minimax.io",
11
+ * "expirationDate": 1760000000.123,
12
+ * "hostOnly": false,
13
+ * "httpOnly": true,
14
+ * "name": "_token",
15
+ * "path": "/",
16
+ * "sameSite": "no_restriction",
17
+ * "secure": true,
18
+ * "session": false,
19
+ * "storeId": "0",
20
+ * "value": "...",
21
+ * "id": 1
22
+ * }
23
+ * ]
24
+ * ```
25
+ *
26
+ * Some tools may export a single object (not an array). Handle both.
27
+ *
28
+ * SEC-001: Cookie VALUES are returned as strings in-memory. Never logged.
29
+ */
30
+ import type { CanonicalCookie } from "./types.js";
31
+ /**
32
+ * Parse EditThisCookie / Chrome devtools JSON export.
33
+ *
34
+ * Accepts:
35
+ * - top-level array of records
36
+ * - top-level single object
37
+ *
38
+ * Skips:
39
+ * - non-object entries
40
+ * - records without non-empty name+value
41
+ *
42
+ * Never throws; returns empty array on parse failure.
43
+ */
44
+ export declare function parseEditThisCookieJson(text: string): CanonicalCookie[];
45
+ //# sourceMappingURL=parse-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-json.d.ts","sourceRoot":"","sources":["../src/parse-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAclD;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE,CAyCvE"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * EditThisCookie / Chrome devtools JSON cookie export parser.
3
+ *
4
+ * Browser extension "EditThisCookie" and Chrome devtools both export
5
+ * cookies in this canonical shape (Chrome/Edge/Chromium cookie store):
6
+ *
7
+ * ```json
8
+ * [
9
+ * {
10
+ * "domain": ".minimax.io",
11
+ * "expirationDate": 1760000000.123,
12
+ * "hostOnly": false,
13
+ * "httpOnly": true,
14
+ * "name": "_token",
15
+ * "path": "/",
16
+ * "sameSite": "no_restriction",
17
+ * "secure": true,
18
+ * "session": false,
19
+ * "storeId": "0",
20
+ * "value": "...",
21
+ * "id": 1
22
+ * }
23
+ * ]
24
+ * ```
25
+ *
26
+ * Some tools may export a single object (not an array). Handle both.
27
+ *
28
+ * SEC-001: Cookie VALUES are returned as strings in-memory. Never logged.
29
+ */
30
+ /**
31
+ * Parse EditThisCookie / Chrome devtools JSON export.
32
+ *
33
+ * Accepts:
34
+ * - top-level array of records
35
+ * - top-level single object
36
+ *
37
+ * Skips:
38
+ * - non-object entries
39
+ * - records without non-empty name+value
40
+ *
41
+ * Never throws; returns empty array on parse failure.
42
+ */
43
+ export function parseEditThisCookieJson(text) {
44
+ if (typeof text !== "string" || text.length === 0)
45
+ return [];
46
+ let data;
47
+ try {
48
+ data = JSON.parse(text);
49
+ }
50
+ catch {
51
+ return [];
52
+ }
53
+ const records = [];
54
+ if (Array.isArray(data)) {
55
+ for (const item of data) {
56
+ if (item && typeof item === "object" && !Array.isArray(item)) {
57
+ records.push(item);
58
+ }
59
+ }
60
+ }
61
+ else if (data && typeof data === "object" && !Array.isArray(data)) {
62
+ records.push(data);
63
+ }
64
+ const cookies = [];
65
+ for (const r of records) {
66
+ const name = asString(r.name);
67
+ const value = asString(r.value);
68
+ if (!name || !value)
69
+ continue;
70
+ const expires = asExpires(r.expirationDate, r.session);
71
+ cookies.push({
72
+ name,
73
+ value,
74
+ domain: asString(r.domain) ?? "",
75
+ path: asString(r.path) ?? "/",
76
+ expires,
77
+ secure: asBool(r.secure) ?? false,
78
+ httpOnly: asBool(r.httpOnly) ?? false,
79
+ });
80
+ }
81
+ return cookies;
82
+ }
83
+ function asString(v) {
84
+ if (typeof v === "string" && v.length > 0)
85
+ return v;
86
+ return undefined;
87
+ }
88
+ function asBool(v) {
89
+ if (typeof v === "boolean")
90
+ return v;
91
+ if (v === 1 || v === "1" || v === "true" || v === "TRUE")
92
+ return true;
93
+ if (v === 0 || v === "0" || v === "false" || v === "FALSE")
94
+ return false;
95
+ return undefined;
96
+ }
97
+ function asExpires(v, session) {
98
+ if (session === true || session === "true")
99
+ return undefined;
100
+ if (typeof v === "number" && Number.isFinite(v)) {
101
+ // EditThisCookie uses unix-seconds (with millisecond decimals sometimes).
102
+ // If v > 1e12, it's milliseconds — convert.
103
+ const seconds = v > 1e12 ? Math.floor(v / 1000) : Math.floor(v);
104
+ return seconds > 0 ? seconds : undefined;
105
+ }
106
+ return undefined;
107
+ }
108
+ //# sourceMappingURL=parse-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-json.js","sourceRoot":"","sources":["../src/parse-json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Netscape-format cookie file parser.
3
+ *
4
+ * Format reference: https://curl.haxx.se/rfc/cookie_spec.html
5
+ *
6
+ * Each row is tab-separated, 7 columns:
7
+ * domain flag path secure expires name value
8
+ *
9
+ * - Lines starting with `# ` are comments (skipped).
10
+ * - Lines starting with `#HttpOnly_` are HTTP-only cookies
11
+ * (the leading `#HttpOnly_` is stripped, the rest is parsed normally).
12
+ * - Empty lines are skipped.
13
+ * - `expires` is Unix seconds; `0` or unparseable → session cookie.
14
+ * - Lines with fewer than 7 columns are skipped (malformed).
15
+ *
16
+ * SEC-001: Cookie values are returned as strings in-memory. They MUST
17
+ * never be logged. The scrubber in cookie-sanitizer applies value
18
+ * redaction before any path-touching log line.
19
+ */
20
+ import type { CanonicalCookie } from "./types.js";
21
+ /**
22
+ * Parse a Netscape-format cookie string into canonical records.
23
+ *
24
+ * Skips:
25
+ * - blank lines
26
+ * - comments (lines starting with `#` but not `#HttpOnly_`)
27
+ * - malformed rows (< 7 columns)
28
+ *
29
+ * Never throws; returns empty array if input is invalid.
30
+ */
31
+ export declare function parseNetscape(text: string): CanonicalCookie[];
32
+ /**
33
+ * Serialize a list of canonical cookies back to Netscape format.
34
+ * Used by atomic-write.ts to produce the canonical cache.
35
+ *
36
+ * Output uses the canonical column order:
37
+ * domain flag path secure expires name value
38
+ *
39
+ * `flag` is FALSE per curl spec (HttpOnly is encoded as `#HttpOnly_`).
40
+ * Cookie values are NEVER logged during the round-trip.
41
+ */
42
+ export declare function serializeNetscape(cookies: CanonicalCookie[]): string;
43
+ //# sourceMappingURL=parse-netscape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-netscape.d.ts","sourceRoot":"","sources":["../src/parse-netscape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAalD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE,CA8C7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAgBpE"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Netscape-format cookie file parser.
3
+ *
4
+ * Format reference: https://curl.haxx.se/rfc/cookie_spec.html
5
+ *
6
+ * Each row is tab-separated, 7 columns:
7
+ * domain flag path secure expires name value
8
+ *
9
+ * - Lines starting with `# ` are comments (skipped).
10
+ * - Lines starting with `#HttpOnly_` are HTTP-only cookies
11
+ * (the leading `#HttpOnly_` is stripped, the rest is parsed normally).
12
+ * - Empty lines are skipped.
13
+ * - `expires` is Unix seconds; `0` or unparseable → session cookie.
14
+ * - Lines with fewer than 7 columns are skipped (malformed).
15
+ *
16
+ * SEC-001: Cookie values are returned as strings in-memory. They MUST
17
+ * never be logged. The scrubber in cookie-sanitizer applies value
18
+ * redaction before any path-touching log line.
19
+ */
20
+ /**
21
+ * Parse a Netscape-format cookie string into canonical records.
22
+ *
23
+ * Skips:
24
+ * - blank lines
25
+ * - comments (lines starting with `#` but not `#HttpOnly_`)
26
+ * - malformed rows (< 7 columns)
27
+ *
28
+ * Never throws; returns empty array if input is invalid.
29
+ */
30
+ export function parseNetscape(text) {
31
+ if (typeof text !== "string" || text.length === 0)
32
+ return [];
33
+ const rows = [];
34
+ const lines = text.split(/\r?\n/);
35
+ for (const raw of lines) {
36
+ if (!raw)
37
+ continue;
38
+ let line = raw;
39
+ let httpOnly = false;
40
+ if (line.startsWith("#HttpOnly_")) {
41
+ httpOnly = true;
42
+ line = line.slice("#HttpOnly_".length);
43
+ }
44
+ else if (line.startsWith("#")) {
45
+ // Plain comment line (Netscape / curl spec).
46
+ continue;
47
+ }
48
+ const cols = line.split("\t");
49
+ if (cols.length < 7)
50
+ continue;
51
+ const [domain, _flag, cookiePath, secure, expires, name, value] = cols;
52
+ if (!name || !value)
53
+ continue;
54
+ rows.push({
55
+ domain: (domain ?? "").trim(),
56
+ path: (cookiePath ?? "/").trim() || "/",
57
+ secure: (secure ?? "FALSE").toUpperCase() === "TRUE",
58
+ httpOnly,
59
+ expires: parseInt(expires ?? "0", 10) || 0,
60
+ name: name.trim(),
61
+ value, // intentional: keep as-is for in-memory pipeline; never log
62
+ });
63
+ }
64
+ // Map to CanonicalCookie shape.
65
+ return rows.map((r) => ({
66
+ name: r.name,
67
+ value: r.value,
68
+ domain: r.domain,
69
+ path: r.path,
70
+ expires: r.expires === 0 ? undefined : r.expires,
71
+ secure: r.secure,
72
+ httpOnly: r.httpOnly,
73
+ }));
74
+ }
75
+ /**
76
+ * Serialize a list of canonical cookies back to Netscape format.
77
+ * Used by atomic-write.ts to produce the canonical cache.
78
+ *
79
+ * Output uses the canonical column order:
80
+ * domain flag path secure expires name value
81
+ *
82
+ * `flag` is FALSE per curl spec (HttpOnly is encoded as `#HttpOnly_`).
83
+ * Cookie values are NEVER logged during the round-trip.
84
+ */
85
+ export function serializeNetscape(cookies) {
86
+ const out = ["# Netscape HTTP Cookie File", ""];
87
+ for (const c of cookies) {
88
+ if (!c.name || !c.value)
89
+ continue;
90
+ const domain = c.domain ?? "";
91
+ const path = c.path ?? "/";
92
+ const secure = c.secure ? "TRUE" : "FALSE";
93
+ const expires = c.expires != null ? String(c.expires) : "0";
94
+ const line = [domain, "FALSE", path, secure, expires, c.name, c.value].join("\t");
95
+ out.push(c.httpOnly ? `#HttpOnly_${line}` : line);
96
+ }
97
+ return out.join("\n") + "\n";
98
+ }
99
+ //# sourceMappingURL=parse-netscape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-netscape.js","sourceRoot":"","sources":["../src/parse-netscape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Sync orchestrator — the heart of the sanitizer.
3
+ *
4
+ * Pipeline (per run):
5
+ * 1. Enumerate files in the drop folder (one level + one sublevel).
6
+ * 2. Read each file. Detect format. Parse.
7
+ * 3. Concatenate cookies from all parsed files.
8
+ * 4. Infer provider from filename + cookies.
9
+ * 5. Normalize (dedupe, expire, domain-match).
10
+ * 6. Serialize to Netscape and write to the canonical cache (atomic).
11
+ *
12
+ * Returns a SyncResult. Never throws — returns structured errors in `result.errors`.
13
+ *
14
+ * Sec-001: Cookie VALUES never appear in any log line. Diagnostics
15
+ * use file basenames and 64-char previews with values redacted.
16
+ */
17
+ import type { SyncOptions, SyncResult } from "./types.js";
18
+ /** Default drop-folder location. */
19
+ export declare const DEFAULT_DROP_DIR: string;
20
+ /**
21
+ * Enumerate readable files inside `dir`, up to MAX_DEPTH.
22
+ * Returns absolute paths. Skips dotfiles, editor temp files.
23
+ *
24
+ * `excludePath` (optional) — absolute path of a file to skip, e.g.
25
+ * the canonical cache file (so we never recursively read it).
26
+ */
27
+ export declare function enumerateDropFiles(dir: string, excludePath?: string): string[];
28
+ /**
29
+ * Read a single input file as text, capped at MAX_INPUT_BYTES.
30
+ * Returns null + a `reason` if the file can't be read.
31
+ */
32
+ export declare function readInputFile(filePath: string): {
33
+ text: string;
34
+ reason?: string;
35
+ };
36
+ /**
37
+ * Run the full sync pipeline.
38
+ *
39
+ * Options:
40
+ * - dropDir default: ~/.pi-harness-runtime/cookies/
41
+ * - cachePath default: ~/.config/<provider>-cookies.txt
42
+ * - providerHint override inference (skips filename/domain checks)
43
+ * - dryRun skip the actual file write (still returns would-be result)
44
+ *
45
+ * Returns a SyncResult. Never throws.
46
+ */
47
+ export declare function sync(opts?: SyncOptions): SyncResult;
48
+ /**
49
+ * Has-any-input check: true if the drop folder has anything readable.
50
+ * Cheap — does a single `readdirSync`; no parsing.
51
+ */
52
+ export declare function hasAnyCookieSource(dropDir?: string): boolean;
53
+ /**
54
+ * Convenience: cache path for the dominant provider in the drop folder,
55
+ * or null if nothing's there. Used by `footer-status.ts` to ask "should
56
+ * the footer hint point at this provider?"
57
+ */
58
+ export declare function inferCachePath(dropDir?: string): string | null;
59
+ export { inferProvider, inferProviderFromFilename, inferProviderFromCookies, } from "./infer-provider.js";
60
+ export { defaultCachePathFor } from "./atomic-write.js";
61
+ export type { SyncOptions, SyncResult, CanonicalCookie, ProviderId, DetectedFile, CookieFileFormat, WatcherEvent, } from "./types.js";
62
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAY3E,oCAAoC;AACpC,eAAO,MAAM,gBAAgB,QAI5B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,GAClB,MAAM,EAAE,CA6CV;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAmBA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,IAAI,GAAE,WAAgB,GAAG,UAAU,CAiHvD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,OAAO,GAAE,MAAyB,GAChC,OAAO,CAET;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC7B,OAAO,GAAE,MAAyB,GAChC,MAAM,GAAG,IAAI,CAqBf;AAED,OAAO,EACN,aAAa,EACb,yBAAyB,EACzB,wBAAwB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACZ,MAAM,YAAY,CAAC"}