zelari-code 2.46.2 → 2.48.0

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/README.md +3 -3
  2. package/dist/cli/automations/browser/cookieDisk.js +56 -0
  3. package/dist/cli/automations/browser/cookieDisk.js.map +1 -0
  4. package/dist/cli/automations/browser/pageAdapter.js +130 -0
  5. package/dist/cli/automations/browser/pageAdapter.js.map +1 -0
  6. package/dist/cli/automations/browser/selectors.js +178 -0
  7. package/dist/cli/automations/browser/selectors.js.map +1 -0
  8. package/dist/cli/automations/browser/session.js +243 -0
  9. package/dist/cli/automations/browser/session.js.map +1 -0
  10. package/dist/cli/budget/budgetRuntime.js +9 -13
  11. package/dist/cli/budget/budgetRuntime.js.map +1 -1
  12. package/dist/cli/budget/essentialBashConfig.js +118 -0
  13. package/dist/cli/budget/essentialBashConfig.js.map +1 -0
  14. package/dist/cli/headless/runOneTurn.js +36 -6
  15. package/dist/cli/headless/runOneTurn.js.map +1 -1
  16. package/dist/cli/hooks/useChatTurn.js +30 -7
  17. package/dist/cli/hooks/useChatTurn.js.map +1 -1
  18. package/dist/cli/keyStore.js +2 -0
  19. package/dist/cli/keyStore.js.map +1 -1
  20. package/dist/cli/kraken/candidateRegistry.js +13 -0
  21. package/dist/cli/kraken/candidateRegistry.js.map +1 -1
  22. package/dist/cli/kraken/executor.js +200 -22
  23. package/dist/cli/kraken/executor.js.map +1 -1
  24. package/dist/cli/kraken/narrativeFloor.js +23 -0
  25. package/dist/cli/kraken/narrativeFloor.js.map +1 -0
  26. package/dist/cli/kraken/planner.js +27 -0
  27. package/dist/cli/kraken/planner.js.map +1 -1
  28. package/dist/cli/kraken/strictWaiver.js +22 -0
  29. package/dist/cli/kraken/strictWaiver.js.map +1 -0
  30. package/dist/cli/kraken/unresolvedGate.js +32 -0
  31. package/dist/cli/kraken/unresolvedGate.js.map +1 -0
  32. package/dist/cli/kraken/verificationBridge.js +67 -8
  33. package/dist/cli/kraken/verificationBridge.js.map +1 -1
  34. package/dist/cli/kraken/verifyHonestVerdict.js +30 -0
  35. package/dist/cli/kraken/verifyHonestVerdict.js.map +1 -0
  36. package/dist/cli/kraken/worktreeMergeRollback.js +277 -0
  37. package/dist/cli/kraken/worktreeMergeRollback.js.map +1 -0
  38. package/dist/cli/kraken/worktreeScheduling.js +11 -0
  39. package/dist/cli/kraken/worktreeScheduling.js.map +1 -1
  40. package/dist/cli/main.bundled.js +3278 -1483
  41. package/dist/cli/main.bundled.js.map +4 -4
  42. package/dist/cli/main.js +1 -1
  43. package/dist/cli/main.js.map +1 -1
  44. package/dist/cli/modelDiscovery.js +5 -1
  45. package/dist/cli/modelDiscovery.js.map +1 -1
  46. package/dist/cli/museOAuth.js +384 -0
  47. package/dist/cli/museOAuth.js.map +1 -0
  48. package/dist/cli/oauthDesktop.js +18 -1
  49. package/dist/cli/oauthDesktop.js.map +1 -1
  50. package/dist/cli/provider/openai-compatible.js +1 -0
  51. package/dist/cli/provider/openai-compatible.js.map +1 -1
  52. package/dist/cli/provider/resolveStream.js +2 -0
  53. package/dist/cli/provider/resolveStream.js.map +1 -1
  54. package/dist/cli/providerConfig.js +2 -0
  55. package/dist/cli/providerConfig.js.map +1 -1
  56. package/dist/cli/refreshRegistry.js +6 -0
  57. package/dist/cli/refreshRegistry.js.map +1 -1
  58. package/dist/cli/runHeadless.js +184 -100
  59. package/dist/cli/runHeadless.js.map +1 -1
  60. package/dist/cli/slashCommands.js +6 -6
  61. package/dist/cli/slashCommands.js.map +1 -1
  62. package/dist/cli/slashHandlers/krakenGraph.js +25 -7
  63. package/dist/cli/slashHandlers/krakenGraph.js.map +1 -1
  64. package/dist/cli/slashHandlers/provider.js +14 -4
  65. package/dist/cli/slashHandlers/provider.js.map +1 -1
  66. package/dist/cli/thinking.js +1 -0
  67. package/dist/cli/thinking.js.map +1 -1
  68. package/dist/cli/thinkingCapability.js +2 -0
  69. package/dist/cli/thinkingCapability.js.map +1 -1
  70. package/dist/cli/toolRegistry.js +22 -3
  71. package/dist/cli/toolRegistry.js.map +1 -1
  72. package/dist/cli/tools/bashWriteWatch.js +195 -0
  73. package/dist/cli/tools/bashWriteWatch.js.map +1 -0
  74. package/dist/cli/tools/krakenModel.js +50 -0
  75. package/dist/cli/tools/krakenModel.js.map +1 -1
  76. package/dist/cli/tools/krakenRadio.js +50 -5
  77. package/dist/cli/tools/krakenRadio.js.map +1 -1
  78. package/dist/cli/tools/krakenWorktree.js +35 -6
  79. package/dist/cli/tools/krakenWorktree.js.map +1 -1
  80. package/dist/cli/tools/taskTool.js +328 -34
  81. package/dist/cli/tools/taskTool.js.map +1 -1
  82. package/dist/cli/tools/verifyDebtSpine.js +117 -0
  83. package/dist/cli/tools/verifyDebtSpine.js.map +1 -0
  84. package/package.json +2 -2
package/README.md CHANGED
@@ -42,7 +42,7 @@ By **[Anathema Studio](https://anathema-studio.com/)** ·
42
42
 
43
43
  📖 **[Full user guide](./docs/GUIDA.md)** · **[Reference guide](./docs/GUIDE.md)** — install, TUI, slash commands, council, skills, workspace, headless, MCP, Desktop.
44
44
 
45
- **Zelari Code** is an open-source **coding orchestrator** for the terminal — the agent that doesn't trust itself. The default dispatch is the **kraken** super-agent (aliases `agent`/`single`) spawning explore/general/verify tentacles; a six-role **council** pipeline (Caronte, Nettuno, Gerione, Plutone, Minosse, Lucifero) is there when the work earns a second opinion; optional **zelari** missions loop until a deliverable is *proven* done — done means verified, not claimed. It ships a rich TUI (Ink + React), slash commands, plan/build phases, and provider-agnostic LLM streaming (OpenAI-compatible, xAI Grok, ChatGPT, Anthropic, GLM/Z.AI, MiniMax, DeepSeek). OAuth via `/login grok`, `/login chatgpt`, `/login anthropic`. The reusable runtime is published as **[`@zelari/core`](https://www.npmjs.com/package/@zelari/core)** (Apache-2.0).
45
+ **Zelari Code** is an open-source **coding orchestrator** for the terminal — the agent that doesn't trust itself. The default dispatch is the **kraken** super-agent (aliases `agent`/`single`) spawning explore/general/verify tentacles; a six-role **council** pipeline (Caronte, Nettuno, Gerione, Plutone, Minosse, Lucifero) is there when the work earns a second opinion; optional **zelari** missions loop until a deliverable is *proven* done — done means verified, not claimed. It ships a rich TUI (Ink + React), slash commands, plan/build phases, and provider-agnostic LLM streaming (OpenAI-compatible, xAI Grok, ChatGPT, Anthropic, Muse, GLM/Z.AI, MiniMax, DeepSeek). OAuth via `/login grok`, `/login chatgpt`, `/login anthropic`, `/login muse`. The reusable runtime is published as **[`@zelari/core`](https://www.npmjs.com/package/@zelari/core)** (Apache-2.0).
46
46
 
47
47
  ```bash
48
48
  # Zero install — runs from npm's cache (cold-cache start):
@@ -61,7 +61,7 @@ zelari-code
61
61
  | **npm** | **≥ 10** | Required to reproduce the workspace lockfile; use the version pinned by `packageManager`. |
62
62
  | **OS** | Linux, macOS, Windows 10/11 | Tested on Pop!_OS 24.04, macOS 15, Windows 11. Windows requires Git Bash (auto-detected). |
63
63
  | **Disk** | ~50 MB for the CLI + `@zelari/core` | Models are not bundled — provider APIs are remote. |
64
- | **Account + API key** | 1 of: xAI Grok, ChatGPT, Anthropic, OpenAI-compatible, GLM/Z.AI, MiniMax, DeepSeek | OAuth via `/login grok`, `/login chatgpt`, `/login anthropic`. |
64
+ | **Account + API key** | 1 of: xAI Grok, ChatGPT, Anthropic, Muse, OpenAI-compatible, GLM/Z.AI, MiniMax, DeepSeek | OAuth via `/login grok`, `/login chatgpt`, `/login anthropic`, `/login muse`. |
65
65
 
66
66
  ### Optional (advanced tools)
67
67
 
@@ -218,7 +218,7 @@ Full reference: **[docs/GUIDA.md](./docs/GUIDA.md#comandi-slash)** (all flags, e
218
218
  |---|---|
219
219
  | `/help` | List all commands + loaded skills |
220
220
  | `/exit` | Exit the CLI |
221
- | `/login <provider> [key]` | Set API key; `/login grok\|chatgpt\|anthropic` starts OAuth |
221
+ | `/login <provider> [key]` | Set API key; `/login grok\|chatgpt\|anthropic\|muse` starts OAuth |
222
222
  | `/provider`, `/provider <id>` | Show / switch LLM provider |
223
223
  | `/provider custom <url>` | Self-hosted endpoint (Ollama, LM Studio, …) |
224
224
  | `/model <name>`, `/models` | Set model / list discovered models |
@@ -0,0 +1,56 @@
1
+ /**
2
+ * cookieDisk.ts — login-state from the Chromium cookie DB WITHOUT launching a
3
+ * browser. Desktop used to poll `automation health` every 30s, which spawned
4
+ * Chromium on the same persistent profile and raced the cookie store
5
+ * (false `relogin_required`, locked profiles, failed publishes).
6
+ *
7
+ * Cookie *names* are plaintext in Chromium's SQLite even when values are
8
+ * encrypted. Presence of the channel's auth cookies is enough for health.
9
+ */
10
+ import { readFile } from 'node:fs/promises';
11
+ import path from 'node:path';
12
+ /** Chromium cookie DB locations under a persistent profile directory. */
13
+ export function cookieDbCandidates(profile) {
14
+ return [
15
+ path.join(profile, 'Default', 'Network', 'Cookies'),
16
+ path.join(profile, 'Default', 'Cookies'),
17
+ ];
18
+ }
19
+ function isLockError(err) {
20
+ const code = err?.code;
21
+ return code === 'EBUSY' || code === 'EPERM' || code === 'EACCES';
22
+ }
23
+ function containsName(haystack, name) {
24
+ return haystack.includes(Buffer.from(name, 'utf8'));
25
+ }
26
+ /**
27
+ * Probe auth-cookie names in the profile's cookie DB.
28
+ * - present: every `wanted` name is in the file
29
+ * - missing: a cookie DB exists but at least one name is absent
30
+ * - locked: Chromium has the file open (do NOT report logged-out)
31
+ * - absent: no cookie DB yet (fresh profile)
32
+ */
33
+ export async function probeSessionCookiesOnDisk(profile, wanted, read = (p) => readFile(p)) {
34
+ if (wanted.length === 0)
35
+ return 'absent';
36
+ let sawFile = false;
37
+ for (const file of cookieDbCandidates(profile)) {
38
+ try {
39
+ const buf = await read(file);
40
+ sawFile = true;
41
+ if (wanted.every((n) => containsName(buf, n)))
42
+ return 'present';
43
+ return 'missing';
44
+ }
45
+ catch (err) {
46
+ if (isLockError(err))
47
+ return 'locked';
48
+ const code = err?.code;
49
+ if (code === 'ENOENT')
50
+ continue;
51
+ throw err;
52
+ }
53
+ }
54
+ return sawFile ? 'missing' : 'absent';
55
+ }
56
+ //# sourceMappingURL=cookieDisk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookieDisk.js","sourceRoot":"","sources":["../../../../src/cli/automations/browser/cookieDisk.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,yEAAyE;AACzE,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,MAAM,IAAI,GAAI,GAAyC,EAAE,IAAI,CAAC;IAC9D,OAAO,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,CAAC;AACnE,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB,EAAE,IAAY;IAClD,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,MAAyB,EACzB,OAAyB,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE3C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAAE,OAAO,SAAS,CAAC;YAChE,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,GAAG,CAAC;gBAAE,OAAO,QAAQ,CAAC;YACtC,MAAM,IAAI,GAAI,GAAyC,EAAE,IAAI,CAAC;YAC9D,IAAI,IAAI,KAAK,QAAQ;gBAAE,SAAS;YAChC,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;AACxC,CAAC"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * automations/browser/pageAdapter.ts — the Playwright page/context adapter (F3.1/F3.2).
3
+ *
4
+ * The minimal structural seams the automation orchestration talks to, plus the
5
+ * thin adapters that narrow a real Playwright page/context onto them. Keeping
6
+ * this separate from session.ts holds each module under the size budget and
7
+ * keeps the "what the orchestration sees" contract in one place.
8
+ *
9
+ * Playwright itself is never imported here — only structural (duck-typed)
10
+ * interfaces — so the orchestration stays unit-testable with fake pages.
11
+ */
12
+ /** How long a fallback selector may take to appear before we call it absent. */
13
+ export const SELECTOR_TIMEOUT_MS = 5_000;
14
+ /** Adapt a real Playwright page onto the orchestration's BrowserPageLike seam. */
15
+ export function adaptPage(p) {
16
+ return {
17
+ goto: (url, opts) => p.goto(url, opts),
18
+ url: () => p.url(),
19
+ close: () => p.close(),
20
+ bringToFront: async () => {
21
+ await p.bringToFront?.();
22
+ },
23
+ hasSelector: async (selector, timeoutMs = SELECTOR_TIMEOUT_MS) => {
24
+ try {
25
+ if ((await p.$(selector)) !== null)
26
+ return true;
27
+ await p.waitForSelector(selector, { timeout: timeoutMs });
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ },
34
+ waitForSelector: (selector, opts) => p.waitForSelector(selector, opts),
35
+ click: (selector, opts) => p.click(selector, opts),
36
+ typeText: (selector, text, opts) => p.type(selector, text, { delay: opts?.delayMs }),
37
+ press: (key) => p.keyboard.press(key),
38
+ setInputFiles: (selector, files) => p.setInputFiles(selector, files),
39
+ screenshot: (path) => p.screenshot({ path }),
40
+ hrefs: async (selector) => p.$$eval(selector, (els) => els.map((e) => String(e.href ?? ''))),
41
+ linkTexts: async (selector) => p.$$eval(selector, (els) => els.map((e) => {
42
+ const a = e;
43
+ const article = typeof a.closest === 'function' ? a.closest('article') : null;
44
+ const text = (article?.textContent ?? a.textContent ?? '').trim();
45
+ return { href: String(a.href ?? ''), text };
46
+ })),
47
+ articlePermalinks: async () => p.$$eval("div[role='article']", (els) => {
48
+ const shapes = /(\/posts\/|permalink\.php|story\.php|\/share\/p\/)/;
49
+ const out = [];
50
+ for (const e of els) {
51
+ const el = e;
52
+ const anchor = Array.from(el.querySelectorAll('a[href]'))
53
+ .map((a) => String(a.href ?? ''))
54
+ .find((h) => shapes.test(h));
55
+ const text = (el.textContent ?? '').replace(/\s+/g, ' ').slice(0, 600);
56
+ if (anchor !== undefined && anchor.length > 0)
57
+ out.push({ href: anchor, text });
58
+ }
59
+ return out;
60
+ }),
61
+ controls: (selector) => p.$$eval(selector, (els) => els
62
+ .map((e) => {
63
+ const el = e;
64
+ const attr = (n) => typeof el.getAttribute === 'function' ? (el.getAttribute(n) ?? undefined) : undefined;
65
+ return {
66
+ tag: String(el.tagName ?? '').toLowerCase(),
67
+ role: attr('role'),
68
+ aria: attr('aria-label'),
69
+ testid: attr('data-testid'),
70
+ text: String(el.textContent ?? '').replace(/\s+/g, ' ').trim().slice(0, 100),
71
+ disabled: typeof el.hasAttribute === 'function' && el.hasAttribute('disabled') ? true : undefined,
72
+ };
73
+ })
74
+ .slice(0, 100)),
75
+ clickText: (scopeSelector, texts) => p.$$eval(scopeSelector, (els, labels) => {
76
+ const norm = (s) => String(s ?? '').replace(/\s+/g, ' ').trim().toLowerCase();
77
+ const wanted = labels.map((l) => norm(l));
78
+ const vis = (node) => {
79
+ const r = node.getBoundingClientRect();
80
+ const st = getComputedStyle(node);
81
+ return (r.width > 2 &&
82
+ r.height > 2 &&
83
+ st.visibility !== 'hidden' &&
84
+ st.display !== 'none' &&
85
+ Number(st.opacity) > 0.1);
86
+ };
87
+ let hit = null;
88
+ for (const e of els) {
89
+ const el = e;
90
+ const aria = typeof el.getAttribute === 'function' ? el.getAttribute('aria-label') : null;
91
+ const inner = String(el.innerText ?? el.textContent ?? '');
92
+ const ariaN = norm(aria);
93
+ const textN = norm(inner);
94
+ if (!wanted.some((w) => w === ariaN || w === textN))
95
+ continue;
96
+ if (typeof el.hasAttribute === 'function' && (el.hasAttribute('disabled') || el.getAttribute?.('aria-disabled') === 'true'))
97
+ continue;
98
+ if (!vis(el))
99
+ continue;
100
+ if (typeof el.click !== 'function')
101
+ continue;
102
+ hit = { click: el.click.bind(el), aria, text: inner };
103
+ }
104
+ if (!hit)
105
+ return null;
106
+ hit.click();
107
+ return norm(hit.aria ?? hit.text);
108
+ }, texts),
109
+ };
110
+ }
111
+ /** Adapt a real Playwright persistent context onto PersistentContextLike. */
112
+ export function adaptContext(ctx) {
113
+ return {
114
+ newPage: async () => adaptPage(await ctx.newPage()),
115
+ pages: () => ctx.pages().map(adaptPage),
116
+ close: () => ctx.close(),
117
+ cookies: typeof ctx.cookies === 'function'
118
+ ? async () => (await ctx.cookies?.()) ?? []
119
+ : undefined,
120
+ onClose: (cb) => {
121
+ try {
122
+ ctx.on('close', cb);
123
+ }
124
+ catch {
125
+ // 'close' unsupported on a partial fake — the timeout still bounds us.
126
+ }
127
+ },
128
+ };
129
+ }
130
+ //# sourceMappingURL=pageAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pageAdapter.js","sourceRoot":"","sources":["../../../../src/cli/automations/browser/pageAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,gFAAgF;AAChF,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAmGzC,kFAAkF;AAClF,MAAM,UAAU,SAAS,CAAC,CAAa;IACrC,OAAO;QACL,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;QACtC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;QAClB,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE;QACtB,YAAY,EAAE,KAAK,IAAI,EAAE;YACvB,MAAM,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC;QAC3B,CAAC;QACD,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,GAAG,mBAAmB,EAAE,EAAE;YAC/D,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,IAAI;oBAAE,OAAO,IAAI,CAAC;gBAChD,MAAM,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC1D,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,eAAe,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC;QACtE,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC;QAClD,QAAQ,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACpF,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;QACrC,aAAa,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC;QACpE,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC;QAC5C,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CACxB,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAE,CAAuB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1F,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAC5B,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CACzB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACZ,MAAM,CAAC,GAAG,CAIT,CAAC;YACF,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9E,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAClE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC,CAAC,CACH;QACH,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAC5B,CAAC,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,GAAG,EAAE,EAAE;YACtC,MAAM,MAAM,GAAG,oDAAoD,CAAC;YACpE,MAAM,GAAG,GAA0C,EAAE,CAAC;YACtD,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;gBACpB,MAAM,EAAE,GAAG,CAAY,CAAC;gBACxB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;qBACtD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAE,CAAuB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;qBACvD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/B,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACvE,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;oBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAClF,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC;QACJ,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CACrB,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CACzB,GAAG;aACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,EAAE,GAAG,CAKV,CAAC;YACF,MAAM,IAAI,GAAG,CAAC,CAAS,EAAsB,EAAE,CAC7C,OAAO,EAAE,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACxF,OAAO;gBACL,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE;gBAC3C,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;gBAClB,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC;gBACxB,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC;gBAC3B,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;gBAC5E,QAAQ,EAAE,OAAO,EAAE,CAAC,YAAY,KAAK,UAAU,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;aAClG,CAAC;QACJ,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CACjB;QACH,SAAS,EAAE,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,CAClC,CAAC,CAAC,MAAM,CACN,aAAa,EACb,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YACd,MAAM,IAAI,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACvF,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,GAAG,GAAG,CAAC,IAAa,EAAW,EAAE;gBACrC,MAAM,CAAC,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBACvC,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,CACL,CAAC,CAAC,KAAK,GAAG,CAAC;oBACX,CAAC,CAAC,MAAM,GAAG,CAAC;oBACZ,EAAE,CAAC,UAAU,KAAK,QAAQ;oBAC1B,EAAE,CAAC,OAAO,KAAK,MAAM;oBACrB,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,GAAG,CACzB,CAAC;YACJ,CAAC,CAAC;YACF,IAAI,GAAG,GAII,IAAI,CAAC;YAChB,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;gBACpB,MAAM,EAAE,GAAG,CAMV,CAAC;gBACF,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC1F,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;gBAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC;oBAAE,SAAS;gBAC9D,IAAI,OAAO,EAAE,CAAC,YAAY,KAAK,UAAU,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,YAAY,EAAE,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC;oBAAE,SAAS;gBACtI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,SAAS;gBACvB,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,UAAU;oBAAE,SAAS;gBAC7C,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YACxD,CAAC;YACD,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACtB,GAAG,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC,EACD,KAAK,CACN;KACJ,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,GAAkB;IAC7C,OAAO;QACL,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;QACnD,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;QACvC,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE;QACxB,OAAO,EACL,OAAO,GAAG,CAAC,OAAO,KAAK,UAAU;YAC/B,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,EAAE;YAC3C,CAAC,CAAC,SAAS;QACf,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACd,IAAI,CAAC;gBACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,uEAAuE;YACzE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * automations/browser/selectors.ts — per-channel login selectors (F3.1).
3
+ *
4
+ * The selectors are DATA, not code: one JSON file per channel under
5
+ * `./selectors/<channel>.json`, editable at runtime (no recompile). A broken
6
+ * CSS/selector set is diagnosed by `zelari-code automation probe <channel>`,
7
+ * never by shipping new code. Each list (`loggedIn` / `loggedOut`) is an
8
+ * ordered fallback chain — the FIRST matching label wins.
9
+ *
10
+ * Resolution order for the data directory: explicit `dir` override →
11
+ * `ZELARI_BROWSER_SELECTORS_DIR` → next to this module → the source tree
12
+ * (dev: bundled CLI running from the repo root). Unknown channel ⇒ hard error.
13
+ */
14
+ import { existsSync } from 'node:fs';
15
+ import { readFile } from 'node:fs/promises';
16
+ import path from 'node:path';
17
+ import { fileURLToPath } from 'node:url';
18
+ import { z } from 'zod';
19
+ /** Channels that have a browser session manager. Keep in sync with ./selectors. */
20
+ export const SUPPORTED_CHANNELS = ['x', 'facebook'];
21
+ /** Zod enum reused by the CLI for `--channel` / positional parsing. */
22
+ export const ChannelSchema = z.enum(SUPPORTED_CHANNELS);
23
+ /** One labelled selector in a fallback chain. */
24
+ export const SelectorEntrySchema = z.object({
25
+ label: z.string().min(1),
26
+ selector: z.string().min(1),
27
+ });
28
+ /**
29
+ * Composer/publish fallback chains (F3.2). Every field is an ordered chain; the
30
+ * ones the flow cannot run without (`textbox`, `postButton`) are required, the
31
+ * rest are optional so a channel that only supports login (or a channel whose
32
+ * publish support lands later) still validates.
33
+ */
34
+ export const PublishSelectorsSchema = z.object({
35
+ /** Click target that opens the composer from the home timeline. */
36
+ composeEntry: z.array(SelectorEntrySchema).min(1).optional(),
37
+ /** The contenteditable tweet textbox (required to type). */
38
+ textbox: z.array(SelectorEntrySchema).min(1),
39
+ /** The "Post" button (required to publish). */
40
+ postButton: z.array(SelectorEntrySchema).min(1),
41
+ /**
42
+ * Multi-step composer "Next" buttons (it "Avanti", en "Next", …): clicked
43
+ * BETWEEN typing and the post button when Facebook renders the stepped
44
+ * composer — the final "Pubblica/Post" only appears after advancing.
45
+ */
46
+ advanceButtons: z.array(SelectorEntrySchema).min(1).optional(),
47
+ /** Post-publish toast "View" link — the PRIMARY permalink source. */
48
+ toastView: z.array(SelectorEntrySchema).min(1).optional(),
49
+ /** Media file input (optional; missing ⇒ text-only with a warning). */
50
+ fileInput: z.array(SelectorEntrySchema).min(1).optional(),
51
+ /** Nav link to the author's own profile — the FALLBACK permalink source. */
52
+ profileLink: z.array(SelectorEntrySchema).min(1).optional(),
53
+ /** Post anchors on the profile — the FALLBACK permalink source. */
54
+ profilePost: z.array(SelectorEntrySchema).min(1).optional(),
55
+ /**
56
+ * Post-navigation logged-OUT markers (F3.3 hardening): when any of these is
57
+ * present after loading the composer landing page, the cookies passed the
58
+ * local gate but the SERVER rejected the session — the run must stop with
59
+ * ReloginRequired BEFORE any click/typing (localized: 'Accedi', 'Log in', …).
60
+ */
61
+ loggedOutMarkers: z.array(SelectorEntrySchema).min(1).optional(),
62
+ });
63
+ /** The parsed shape of one `selectors/<channel>.json` file. */
64
+ export const ChannelSelectorsSchema = z.object({
65
+ channel: z.string().min(1),
66
+ loginUrl: z.string().min(1),
67
+ /** Ordered fallback chain: first present selector means "logged in". */
68
+ loggedIn: z.array(SelectorEntrySchema).min(1),
69
+ /** Ordered fallback chain: first present selector means "logged out". */
70
+ loggedOut: z.array(SelectorEntrySchema).min(1),
71
+ /**
72
+ * Locale-proof PRIMARY login signal: session/auth cookie names — logged in
73
+ * iff ALL of them are present in the persistent profile (X `auth_token`,
74
+ * Facebook `c_user`+`xs`). DOM selectors stay as the fallback because
75
+ * aria-labels get translated and the DOMs are A/B-shuffled.
76
+ */
77
+ sessionCookies: z.array(z.string().min(1)).min(1).optional(),
78
+ /**
79
+ * GDPR cookie-wall "allow all" buttons (localized). EU accounts see this
80
+ * interstitial BEFORE the feed renders — login/health/publish flows dismiss
81
+ * it (the same consent the user gave in the headed session) or every
82
+ * downstream selector would miss. Optional ⇒ older files still validate.
83
+ */
84
+ consentButtons: z.array(SelectorEntrySchema).min(1).optional(),
85
+ /** Composer/publish chains (F3.2). Optional ⇒ facebook.json still validates. */
86
+ publish: PublishSelectorsSchema.optional(),
87
+ notes: z.string().optional(),
88
+ /** Free-form note (e.g. "UNVERIFIED-GUESSES" for the publish chains). */
89
+ _comment: z.string().optional(),
90
+ });
91
+ /** Type guard for a supported channel id. */
92
+ export function isSupportedChannel(channel) {
93
+ return SUPPORTED_CHANNELS.includes(channel);
94
+ }
95
+ /**
96
+ * Selectors-dir candidates derived from the MODULE location by walking up to the
97
+ * package root (bounded). This is what makes the bundled CLI cwd-INDEPENDENT: the
98
+ * dev bundle sits at `<pkgRoot>/dist/cli/main.bundled.js`, so the source data at
99
+ * `<pkgRoot>/src/cli/automations/browser/selectors` is a couple of levels up —
100
+ * regardless of the `process.cwd()` a spawner (e.g. the Desktop, whose cwd is the
101
+ * user's workdir, not the repo root) chose. Exported for the unit test.
102
+ */
103
+ export function moduleRelativeSelectorsDirs(here) {
104
+ const out = [];
105
+ let cur = here;
106
+ for (let i = 0; i < 8; i += 1) {
107
+ const parent = path.dirname(cur);
108
+ if (parent === cur)
109
+ break; // filesystem root
110
+ out.push(path.join(parent, 'src', 'cli', 'automations', 'browser', 'selectors'));
111
+ out.push(path.join(parent, 'dist', 'cli', 'automations', 'browser', 'selectors'));
112
+ cur = parent;
113
+ }
114
+ return out;
115
+ }
116
+ /**
117
+ * Locate the directory holding `selectors/*.json`.
118
+ * Explicit `dir` wins; then the env override; then the candidates that work in
119
+ * src (vitest), in a bundled CLI run from ANY cwd (module-relative walk up), and
120
+ * the `process.cwd()` source tree as a last resort.
121
+ */
122
+ export function selectorsDir(dir) {
123
+ if (dir && dir.length > 0)
124
+ return dir;
125
+ const env = process.env.ZELARI_BROWSER_SELECTORS_DIR?.trim();
126
+ if (env)
127
+ return env;
128
+ const here = path.dirname(fileURLToPath(import.meta.url));
129
+ const candidates = [
130
+ path.join(here, 'selectors'), // src/cli/automations/browser/selectors (tsx/vitest)
131
+ path.join(here, 'automations', 'browser', 'selectors'), // dist/cli (bundled asset)
132
+ // Bundled CLI spawned from another cwd: reach the source tree relative to
133
+ // THIS module (the Desktop sets cwd = the user's workdir, not the repo root).
134
+ ...moduleRelativeSelectorsDirs(here),
135
+ path.join(process.cwd(), 'src', 'cli', 'automations', 'browser', 'selectors'),
136
+ ];
137
+ for (const c of candidates) {
138
+ if (existsSync(c))
139
+ return c;
140
+ }
141
+ return candidates[0];
142
+ }
143
+ /**
144
+ * Load + validate the selectors for `channel`. Throws a descriptive Error on an
145
+ * unknown channel, a missing file, malformed JSON, a schema mismatch, or a file
146
+ * whose `channel` field does not match the requested one — the probe surfaces
147
+ * these verbatim.
148
+ */
149
+ export async function loadSelectors(channel, dir) {
150
+ if (!isSupportedChannel(channel)) {
151
+ throw new Error(`unknown social channel: ${channel} (supported: ${SUPPORTED_CHANNELS.join(', ')})`);
152
+ }
153
+ const file = path.join(selectorsDir(dir), `${channel}.json`);
154
+ let raw;
155
+ try {
156
+ raw = await readFile(file, 'utf-8');
157
+ }
158
+ catch {
159
+ throw new Error(`selectors file not found: ${file}`);
160
+ }
161
+ let parsedJson;
162
+ try {
163
+ parsedJson = JSON.parse(raw);
164
+ }
165
+ catch (e) {
166
+ throw new Error(`selectors file is malformed JSON: ${file} (${e instanceof Error ? e.message : String(e)})`);
167
+ }
168
+ const parsed = ChannelSelectorsSchema.safeParse(parsedJson);
169
+ if (!parsed.success) {
170
+ const issues = parsed.error.issues.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`).join('; ');
171
+ throw new Error(`selectors file is invalid: ${file} (${issues})`);
172
+ }
173
+ if (parsed.data.channel !== channel) {
174
+ throw new Error(`selectors file ${file} declares channel "${parsed.data.channel}", expected "${channel}"`);
175
+ }
176
+ return parsed.data;
177
+ }
178
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../src/cli/automations/browser/selectors.ts"],"names":[],"mappings":"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"}