@zenalexa/unicli 0.216.3 → 1.0.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 (121) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +13 -5
  3. package/README.zh-CN.md +12 -5
  4. package/dist/adapters/_electron/desktop-shared.d.ts.map +1 -1
  5. package/dist/adapters/_electron/desktop-shared.js +13 -0
  6. package/dist/adapters/_electron/desktop-shared.js.map +1 -1
  7. package/dist/adapters/_electron/shared.d.ts +1 -0
  8. package/dist/adapters/_electron/shared.d.ts.map +1 -1
  9. package/dist/adapters/_electron/shared.js +49 -2
  10. package/dist/adapters/_electron/shared.js.map +1 -1
  11. package/dist/browser/bridge.d.ts +3 -1
  12. package/dist/browser/bridge.d.ts.map +1 -1
  13. package/dist/browser/bridge.js +47 -23
  14. package/dist/browser/bridge.js.map +1 -1
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +4 -1
  17. package/dist/cli.js.map +1 -1
  18. package/dist/commands/browser-operator-runtime.d.ts.map +1 -1
  19. package/dist/commands/browser-operator-runtime.js +4 -2
  20. package/dist/commands/browser-operator-runtime.js.map +1 -1
  21. package/dist/commands/browser-operator.d.ts.map +1 -1
  22. package/dist/commands/browser-operator.js +110 -38
  23. package/dist/commands/browser-operator.js.map +1 -1
  24. package/dist/commands/describe.d.ts.map +1 -1
  25. package/dist/commands/describe.js +20 -1
  26. package/dist/commands/describe.js.map +1 -1
  27. package/dist/commands/dispatch.d.ts +3 -0
  28. package/dist/commands/dispatch.d.ts.map +1 -1
  29. package/dist/commands/dispatch.js +70 -4
  30. package/dist/commands/dispatch.js.map +1 -1
  31. package/dist/core/schema-v2.d.ts +2 -2
  32. package/dist/discovery/loader.d.ts.map +1 -1
  33. package/dist/discovery/loader.js +2 -0
  34. package/dist/discovery/loader.js.map +1 -1
  35. package/dist/engine/browser/action-evidence.d.ts +28 -0
  36. package/dist/engine/browser/action-evidence.d.ts.map +1 -0
  37. package/dist/engine/browser/action-evidence.js +320 -0
  38. package/dist/engine/browser/action-evidence.js.map +1 -0
  39. package/dist/engine/browser/evidence.d.ts +63 -0
  40. package/dist/engine/browser/evidence.d.ts.map +1 -0
  41. package/dist/engine/browser/evidence.js +301 -0
  42. package/dist/engine/browser/evidence.js.map +1 -0
  43. package/dist/engine/capability-policy.d.ts +39 -0
  44. package/dist/engine/capability-policy.d.ts.map +1 -0
  45. package/dist/engine/capability-policy.js +195 -0
  46. package/dist/engine/capability-policy.js.map +1 -0
  47. package/dist/engine/executor.d.ts +3 -3
  48. package/dist/engine/executor.d.ts.map +1 -1
  49. package/dist/engine/executor.js.map +1 -1
  50. package/dist/engine/kernel/execute.d.ts +4 -1
  51. package/dist/engine/kernel/execute.d.ts.map +1 -1
  52. package/dist/engine/kernel/execute.js +92 -10
  53. package/dist/engine/kernel/execute.js.map +1 -1
  54. package/dist/engine/kernel/types.d.ts +2 -0
  55. package/dist/engine/kernel/types.d.ts.map +1 -1
  56. package/dist/engine/operation-policy.d.ts +52 -0
  57. package/dist/engine/operation-policy.d.ts.map +1 -0
  58. package/dist/engine/operation-policy.js +360 -0
  59. package/dist/engine/operation-policy.js.map +1 -0
  60. package/dist/engine/session/events.d.ts +22 -0
  61. package/dist/engine/session/events.d.ts.map +1 -0
  62. package/dist/engine/session/events.js +66 -0
  63. package/dist/engine/session/events.js.map +1 -0
  64. package/dist/engine/session/run-loop.d.ts +11 -0
  65. package/dist/engine/session/run-loop.d.ts.map +1 -0
  66. package/dist/engine/session/run-loop.js +173 -0
  67. package/dist/engine/session/run-loop.js.map +1 -0
  68. package/dist/engine/session/store.d.ts +19 -0
  69. package/dist/engine/session/store.d.ts.map +1 -0
  70. package/dist/engine/session/store.js +84 -0
  71. package/dist/engine/session/store.js.map +1 -0
  72. package/dist/engine/session/types.d.ts +37 -0
  73. package/dist/engine/session/types.d.ts.map +1 -0
  74. package/dist/engine/session/types.js +2 -0
  75. package/dist/engine/session/types.js.map +1 -0
  76. package/dist/engine/steps/fetch-text.d.ts +1 -1
  77. package/dist/engine/steps/fetch-text.d.ts.map +1 -1
  78. package/dist/engine/steps/fetch-text.js +52 -18
  79. package/dist/engine/steps/fetch-text.js.map +1 -1
  80. package/dist/engine/steps/fetch.d.ts +1 -0
  81. package/dist/engine/steps/fetch.d.ts.map +1 -1
  82. package/dist/engine/steps/fetch.js +7 -1
  83. package/dist/engine/steps/fetch.js.map +1 -1
  84. package/dist/engine/steps/parse-rss.d.ts.map +1 -1
  85. package/dist/engine/steps/parse-rss.js +9 -4
  86. package/dist/engine/steps/parse-rss.js.map +1 -1
  87. package/dist/engine/template.d.ts.map +1 -1
  88. package/dist/engine/template.js +2 -1
  89. package/dist/engine/template.js.map +1 -1
  90. package/dist/engine/text-normalize.d.ts +6 -0
  91. package/dist/engine/text-normalize.d.ts.map +1 -0
  92. package/dist/engine/text-normalize.js +63 -0
  93. package/dist/engine/text-normalize.js.map +1 -0
  94. package/dist/fast-path.d.ts.map +1 -1
  95. package/dist/fast-path.js +207 -8
  96. package/dist/fast-path.js.map +1 -1
  97. package/dist/main.d.ts +1 -1
  98. package/dist/main.js +1 -1
  99. package/dist/manifest.json +3357 -600
  100. package/dist/mcp/dispatch.d.ts +3 -3
  101. package/dist/mcp/dispatch.d.ts.map +1 -1
  102. package/dist/mcp/dispatch.js +6 -5
  103. package/dist/mcp/dispatch.js.map +1 -1
  104. package/dist/output/error-map.d.ts.map +1 -1
  105. package/dist/output/error-map.js +21 -0
  106. package/dist/output/error-map.js.map +1 -1
  107. package/dist/protocol/acp-helpers.d.ts +2 -2
  108. package/dist/protocol/acp-helpers.d.ts.map +1 -1
  109. package/dist/protocol/acp-helpers.js +5 -4
  110. package/dist/protocol/acp-helpers.js.map +1 -1
  111. package/dist/registry.d.ts +3 -1
  112. package/dist/registry.d.ts.map +1 -1
  113. package/dist/registry.js +2 -0
  114. package/dist/registry.js.map +1 -1
  115. package/dist/types.d.ts +9 -1
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/types.js.map +1 -1
  118. package/package.json +16 -16
  119. package/src/adapters/36kr/news.yaml +4 -1
  120. package/src/adapters/_electron/desktop-shared.ts +14 -0
  121. package/src/adapters/_electron/shared.ts +54 -2
@@ -43,6 +43,20 @@ export interface AIChatConfig {
43
43
  displayName?: string;
44
44
  }
45
45
 
46
+ function normalizeModelText(value: string): string {
47
+ return value.trim().toLowerCase().replace(/\s+/g, " ");
48
+ }
49
+
50
+ export function isRequestedModelActive(
51
+ currentModelText: string,
52
+ requestedModel: string,
53
+ ): boolean {
54
+ const observed = normalizeModelText(currentModelText);
55
+ const requested = normalizeModelText(requestedModel);
56
+ if (!observed || !requested || observed === "unknown") return false;
57
+ return observed === requested || observed.includes(requested);
58
+ }
59
+
46
60
  /**
47
61
  * Register standard AI chat commands for an Electron app.
48
62
  * Each app gets: ask, send, read, model, status, new, screenshot, dump
@@ -60,6 +74,10 @@ export function registerAIChatCommands(
60
74
  sendButtonSelector,
61
75
  displayName = site,
62
76
  } = config;
77
+ const desktopCommandMeta = {
78
+ adapter_path: `src/adapters/${site}/${site}.ts`,
79
+ target_surface: "desktop" as const,
80
+ };
63
81
 
64
82
  /** Escape single quotes in selectors for use in evaluate strings */
65
83
  const esc = (s: string): string => s.replace(/'/g, "\\'");
@@ -70,6 +88,7 @@ export function registerAIChatCommands(
70
88
  name: "ask",
71
89
  description: `Send a prompt to ${displayName} and wait for response`,
72
90
  strategy: Strategy.PUBLIC,
91
+ ...desktopCommandMeta,
73
92
  args: [
74
93
  {
75
94
  name: "prompt",
@@ -114,6 +133,7 @@ export function registerAIChatCommands(
114
133
  name: "send",
115
134
  description: `Send text to ${displayName} without waiting`,
116
135
  strategy: Strategy.PUBLIC,
136
+ ...desktopCommandMeta,
117
137
  args: [{ name: "text", required: true, positional: true }],
118
138
  func: async (_page: unknown, kwargs: Record<string, unknown>) => {
119
139
  const p = await connectElectronApp(site);
@@ -135,6 +155,7 @@ export function registerAIChatCommands(
135
155
  name: "read",
136
156
  description: `Read the last response from ${displayName}`,
137
157
  strategy: Strategy.PUBLIC,
158
+ ...desktopCommandMeta,
138
159
  func: async () => {
139
160
  const p = await connectElectronApp(site);
140
161
  const text = (await p.evaluate(
@@ -151,13 +172,40 @@ export function registerAIChatCommands(
151
172
  name: "model",
152
173
  description: `Read or switch the current model in ${displayName}`,
153
174
  strategy: Strategy.PUBLIC,
175
+ ...desktopCommandMeta,
154
176
  args: [{ name: "name", required: false, positional: true }],
155
- func: async (_page: unknown, _kwargs: Record<string, unknown>) => {
177
+ func: async (_page: unknown, kwargs: Record<string, unknown>) => {
156
178
  const p = await connectElectronApp(site);
179
+ const requested =
180
+ typeof kwargs.name === "string" ? kwargs.name.trim() : "";
181
+ if (requested) {
182
+ await p.click(modelSelector);
183
+ await p.wait(0.5);
184
+ await p.evaluate(`(() => {
185
+ const wanted = ${JSON.stringify(requested.toLowerCase())};
186
+ const nodes = Array.from(document.querySelectorAll('button,[role="button"],[role="menuitem"],[role="option"],li,div,span'));
187
+ const candidate = nodes.find((node) => {
188
+ const text = (node.textContent || '').trim().toLowerCase();
189
+ return text === wanted || text.includes(wanted);
190
+ });
191
+ if (!candidate) return false;
192
+ candidate.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
193
+ return true;
194
+ })()`);
195
+ await p.wait(0.8);
196
+ }
157
197
  const current = (await p.evaluate(
158
198
  `document.querySelector('${esc(modelSelector)}')?.innerText ?? 'unknown'`,
159
199
  )) as string;
160
- return [{ model: current }];
200
+ return requested
201
+ ? [
202
+ {
203
+ model: current,
204
+ requested,
205
+ switched: isRequestedModelActive(current, requested),
206
+ },
207
+ ]
208
+ : [{ model: current }];
161
209
  },
162
210
  });
163
211
  }
@@ -168,6 +216,7 @@ export function registerAIChatCommands(
168
216
  name: "status",
169
217
  description: `Check ${displayName} app status`,
170
218
  strategy: Strategy.PUBLIC,
219
+ ...desktopCommandMeta,
171
220
  func: async () => {
172
221
  const p = await connectElectronApp(site);
173
222
  const title = await p.title();
@@ -188,6 +237,7 @@ export function registerAIChatCommands(
188
237
  name: "new",
189
238
  description: `Start a new conversation in ${displayName}`,
190
239
  strategy: Strategy.PUBLIC,
240
+ ...desktopCommandMeta,
191
241
  func: async () => {
192
242
  const p = await connectElectronApp(site);
193
243
  if (newChatSelector.startsWith("key:")) {
@@ -213,6 +263,7 @@ export function registerAIChatCommands(
213
263
  name: "screenshot",
214
264
  description: `Capture screenshot of ${displayName}`,
215
265
  strategy: Strategy.PUBLIC,
266
+ ...desktopCommandMeta,
216
267
  args: [
217
268
  {
218
269
  name: "path",
@@ -235,6 +286,7 @@ export function registerAIChatCommands(
235
286
  name: "dump",
236
287
  description: `Dump full page content from ${displayName}`,
237
288
  strategy: Strategy.PUBLIC,
289
+ ...desktopCommandMeta,
238
290
  func: async () => {
239
291
  const p = await connectElectronApp(site);
240
292
  const snapshot = await p.snapshot({ compact: true });