neoagent 3.1.1-beta.2 → 3.1.1-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extensions/chrome-browser/manifest.json +1 -1
- package/extensions/chrome-browser/protocol.mjs +36 -0
- package/flutter_app/lib/main_app_shell.dart +9 -3
- package/flutter_app/lib/main_controller.dart +49 -0
- package/flutter_app/lib/main_models.dart +55 -0
- package/flutter_app/lib/main_operations.dart +530 -2
- package/flutter_app/lib/main_settings.dart +301 -1
- package/flutter_app/lib/main_shared.dart +7 -2
- package/flutter_app/lib/main_timeline.dart +82 -11
- package/flutter_app/lib/src/backend_client.dart +50 -0
- package/landing/index.html +3 -0
- package/landing/status.html +178 -0
- package/lib/schema_migrations.js +23 -0
- package/package.json +1 -1
- package/server/db/database.js +6 -0
- package/server/http/routes.js +2 -0
- package/server/http/static.js +1 -0
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +76806 -75964
- package/server/routes/public_status.js +12 -0
- package/server/routes/settings.js +14 -0
- package/server/routes/social_reach.js +88 -0
- package/server/routes/tasks.js +17 -0
- package/server/services/ai/tools.js +60 -1
- package/server/services/browser/extension/protocol.js +1 -0
- package/server/services/manager.js +14 -0
- package/server/services/memory/consolidation.js +2 -0
- package/server/services/memory/manager.js +70 -8
- package/server/services/memory/retention.js +66 -0
- package/server/services/memory/routing.js +68 -0
- package/server/services/messaging/access_policy.js +39 -2
- package/server/services/messaging/manager.js +9 -4
- package/server/services/public_status.js +103 -0
- package/server/services/runtime/settings.js +6 -0
- package/server/services/social_reach/channels/base.js +56 -0
- package/server/services/social_reach/channels/github.js +75 -0
- package/server/services/social_reach/channels/index.js +34 -0
- package/server/services/social_reach/channels/linkedin.js +34 -0
- package/server/services/social_reach/channels/rss.js +58 -0
- package/server/services/social_reach/channels/unsupported.js +49 -0
- package/server/services/social_reach/channels/v2ex.js +85 -0
- package/server/services/social_reach/channels/web.js +40 -0
- package/server/services/social_reach/channels/xueqiu.js +101 -0
- package/server/services/social_reach/channels/youtube.js +42 -0
- package/server/services/social_reach/index.js +7 -0
- package/server/services/social_reach/platforms.js +162 -0
- package/server/services/social_reach/service.js +163 -0
- package/server/services/social_reach/store.js +89 -0
- package/server/services/social_reach/utils.js +95 -0
- package/server/services/tasks/delivery_targets.js +260 -0
- package/server/utils/whatsapp.js +33 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"version_name": "2.4.1-beta.8",
|
|
6
6
|
"description": "Connect this Chrome browser to NeoAgent for browser automation.",
|
|
7
7
|
"minimum_chrome_version": "118",
|
|
8
|
-
"permissions": ["alarms", "debugger", "storage", "tabs"],
|
|
8
|
+
"permissions": ["alarms", "cookies", "debugger", "storage", "tabs"],
|
|
9
9
|
"host_permissions": ["http://*/*", "https://*/*"],
|
|
10
10
|
"icons": {
|
|
11
11
|
"16": "icons/icon16.png",
|
|
@@ -12,6 +12,7 @@ export const COMMANDS = Object.freeze({
|
|
|
12
12
|
SCREENSHOT: 'screenshot',
|
|
13
13
|
CLOSE: 'close',
|
|
14
14
|
GET_PAGE_INFO: 'getPageInfo',
|
|
15
|
+
GET_COOKIES: 'getCookies',
|
|
15
16
|
});
|
|
16
17
|
|
|
17
18
|
function chromeCall(chromeApi, namespace, method, ...args) {
|
|
@@ -221,6 +222,41 @@ export function createBrowserProtocol(chromeApi) {
|
|
|
221
222
|
|
|
222
223
|
async function run(command, payload = {}) {
|
|
223
224
|
switch (command) {
|
|
225
|
+
case COMMANDS.GET_COOKIES: {
|
|
226
|
+
const domains = Array.isArray(payload.domains)
|
|
227
|
+
? payload.domains.map((item) => String(item || '').replace(/^\./, '').toLowerCase()).filter(Boolean)
|
|
228
|
+
: [];
|
|
229
|
+
if (domains.length === 0) throw new Error('At least one cookie domain is required.');
|
|
230
|
+
const all = [];
|
|
231
|
+
for (const domain of domains) {
|
|
232
|
+
const cookies = await chromeCall(chromeApi, 'cookies', 'getAll', { domain });
|
|
233
|
+
all.push(...(Array.isArray(cookies) ? cookies : []));
|
|
234
|
+
}
|
|
235
|
+
const seen = new Set();
|
|
236
|
+
const filtered = all.filter((cookie) => {
|
|
237
|
+
const cookieDomain = String(cookie?.domain || '').replace(/^\./, '').toLowerCase();
|
|
238
|
+
const allowed = domains.some((domain) => cookieDomain === domain || cookieDomain.endsWith(`.${domain}`));
|
|
239
|
+
if (!allowed) return false;
|
|
240
|
+
const key = `${cookie.name}\n${cookie.domain}\n${cookie.path}`;
|
|
241
|
+
if (seen.has(key)) return false;
|
|
242
|
+
seen.add(key);
|
|
243
|
+
return true;
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
platform: String(payload.platform || ''),
|
|
247
|
+
domains,
|
|
248
|
+
cookies: filtered.map((cookie) => ({
|
|
249
|
+
name: cookie.name,
|
|
250
|
+
value: cookie.value,
|
|
251
|
+
domain: cookie.domain,
|
|
252
|
+
path: cookie.path,
|
|
253
|
+
secure: cookie.secure === true,
|
|
254
|
+
httpOnly: cookie.httpOnly === true,
|
|
255
|
+
sameSite: cookie.sameSite || null,
|
|
256
|
+
expirationDate: cookie.expirationDate || null,
|
|
257
|
+
})),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
224
260
|
case COMMANDS.LAUNCH:
|
|
225
261
|
await attach();
|
|
226
262
|
return pageSnapshot({ screenshot: false });
|
|
@@ -357,8 +357,9 @@ class _LocalInstallWidgetState extends State<_LocalInstallWidget> {
|
|
|
357
357
|
if (!mounted) return;
|
|
358
358
|
setState(() {
|
|
359
359
|
_phase = exit == 0 ? _LocalInstallPhase.done : _LocalInstallPhase.failed;
|
|
360
|
-
if (exit != 0)
|
|
360
|
+
if (exit != 0) {
|
|
361
361
|
_errorMsg = 'Installation failed (exit $exit). Check the log above.';
|
|
362
|
+
}
|
|
362
363
|
});
|
|
363
364
|
}
|
|
364
365
|
|
|
@@ -471,8 +472,9 @@ class _LocalInstallWidgetState extends State<_LocalInstallWidget> {
|
|
|
471
472
|
final proc = _proc;
|
|
472
473
|
proc?.kill(ProcessSignal.sigterm);
|
|
473
474
|
await proc?.exitCode;
|
|
474
|
-
if (mounted)
|
|
475
|
+
if (mounted) {
|
|
475
476
|
setState(() => _phase = _LocalInstallPhase.ready);
|
|
477
|
+
}
|
|
476
478
|
},
|
|
477
479
|
child: const Text('Cancel'),
|
|
478
480
|
),
|
|
@@ -1607,7 +1609,11 @@ class _HomeViewState extends State<HomeView> {
|
|
|
1607
1609
|
titleSpacing: 0,
|
|
1608
1610
|
leadingWidth: 44,
|
|
1609
1611
|
centerTitle: false,
|
|
1610
|
-
title: Text(
|
|
1612
|
+
title: Text(
|
|
1613
|
+
controller.selectedSection.navigationTitle,
|
|
1614
|
+
maxLines: 1,
|
|
1615
|
+
overflow: TextOverflow.ellipsis,
|
|
1616
|
+
),
|
|
1611
1617
|
titleTextStyle: Theme.of(
|
|
1612
1618
|
context,
|
|
1613
1619
|
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w700),
|
|
@@ -182,6 +182,7 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
182
182
|
List<AiWidgetItem> widgets = const <AiWidgetItem>[];
|
|
183
183
|
List<McpServerItem> mcpServers = const <McpServerItem>[];
|
|
184
184
|
Map<String, dynamic> browserRuntime = const <String, dynamic>{};
|
|
185
|
+
Map<String, dynamic> socialReachStatus = const <String, dynamic>{};
|
|
185
186
|
Map<String, dynamic> browserExtensionStatus = const <String, dynamic>{};
|
|
186
187
|
List<Map<String, dynamic>> browserExtensionTokens =
|
|
187
188
|
const <Map<String, dynamic>>[];
|
|
@@ -2316,6 +2317,9 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
2316
2317
|
final browserFuture = _backendClient
|
|
2317
2318
|
.fetchBrowserStatus(backendUrl)
|
|
2318
2319
|
.catchError((_) => const <String, dynamic>{});
|
|
2320
|
+
final socialReachFuture = _backendClient
|
|
2321
|
+
.fetchSocialReachStatus(backendUrl)
|
|
2322
|
+
.catchError((_) => const <String, dynamic>{});
|
|
2319
2323
|
final browserExtensionFuture = _backendClient
|
|
2320
2324
|
.fetchBrowserExtensionStatus(backendUrl)
|
|
2321
2325
|
.catchError((_) => const <String, dynamic>{});
|
|
@@ -2371,6 +2375,7 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
2371
2375
|
final mcpResponse = await mcpFuture;
|
|
2372
2376
|
final recordingsResponse = await recordingsFuture;
|
|
2373
2377
|
final browserResponse = await browserFuture;
|
|
2378
|
+
final socialReachResponse = await socialReachFuture;
|
|
2374
2379
|
final browserExtensionResponse = await browserExtensionFuture;
|
|
2375
2380
|
final androidResponse = await androidFuture;
|
|
2376
2381
|
final desktopResponse = await desktopFuture;
|
|
@@ -2468,6 +2473,7 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
2468
2473
|
RecordingSessionItem.fromJson,
|
|
2469
2474
|
);
|
|
2470
2475
|
browserRuntime = Map<String, dynamic>.from(browserResponse);
|
|
2476
|
+
socialReachStatus = Map<String, dynamic>.from(socialReachResponse);
|
|
2471
2477
|
browserExtensionStatus = Map<String, dynamic>.from(
|
|
2472
2478
|
browserExtensionResponse,
|
|
2473
2479
|
);
|
|
@@ -2796,6 +2802,23 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
2796
2802
|
notifyListeners();
|
|
2797
2803
|
}
|
|
2798
2804
|
|
|
2805
|
+
Future<List<TaskDeliveryTarget>> fetchTaskDeliveryTargets({
|
|
2806
|
+
String? query,
|
|
2807
|
+
String? platform,
|
|
2808
|
+
String? agentId,
|
|
2809
|
+
}) async {
|
|
2810
|
+
final rows = await _backendClient.fetchTaskDeliveryTargets(
|
|
2811
|
+
backendUrl,
|
|
2812
|
+
query: query,
|
|
2813
|
+
platform: platform,
|
|
2814
|
+
agentId: agentId ?? _scopedAgentId,
|
|
2815
|
+
);
|
|
2816
|
+
return rows
|
|
2817
|
+
.map(TaskDeliveryTarget.fromJson)
|
|
2818
|
+
.where((target) => target.platform.isNotEmpty && target.to.isNotEmpty)
|
|
2819
|
+
.toList(growable: false);
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2799
2822
|
Future<void> refreshWidgets({bool all = false}) async {
|
|
2800
2823
|
widgets = _decodeModelList(
|
|
2801
2824
|
'widgets',
|
|
@@ -5875,6 +5898,32 @@ class NeoAgentController extends ChangeNotifier {
|
|
|
5875
5898
|
}
|
|
5876
5899
|
}
|
|
5877
5900
|
|
|
5901
|
+
Future<Map<String, dynamic>> refreshSocialReachStatus() async {
|
|
5902
|
+
final response = await _backendClient.fetchSocialReachStatus(backendUrl);
|
|
5903
|
+
socialReachStatus = Map<String, dynamic>.from(response);
|
|
5904
|
+
notifyListeners();
|
|
5905
|
+
return socialReachStatus;
|
|
5906
|
+
}
|
|
5907
|
+
|
|
5908
|
+
Future<Map<String, dynamic>> importSocialReachCookies(String platform) async {
|
|
5909
|
+
final response = await _backendClient.importSocialReachCookies(
|
|
5910
|
+
backendUrl,
|
|
5911
|
+
platform,
|
|
5912
|
+
tokenId: selectedBrowserExtensionTokenId,
|
|
5913
|
+
);
|
|
5914
|
+
await refreshSocialReachStatus();
|
|
5915
|
+
return response;
|
|
5916
|
+
}
|
|
5917
|
+
|
|
5918
|
+
Future<Map<String, dynamic>> clearSocialReachCookies(String platform) async {
|
|
5919
|
+
final response = await _backendClient.clearSocialReachCookies(
|
|
5920
|
+
backendUrl,
|
|
5921
|
+
platform,
|
|
5922
|
+
);
|
|
5923
|
+
await refreshSocialReachStatus();
|
|
5924
|
+
return response;
|
|
5925
|
+
}
|
|
5926
|
+
|
|
5878
5927
|
Future<void> disconnectMessagingPlatform(String platform) async {
|
|
5879
5928
|
final busyKey = '$platform:disconnect';
|
|
5880
5929
|
if (_busyMessagingPlatformKeys.contains(busyKey)) {
|
|
@@ -643,6 +643,61 @@ class MessagingMessage {
|
|
|
643
643
|
}
|
|
644
644
|
}
|
|
645
645
|
|
|
646
|
+
class TaskDeliveryTarget {
|
|
647
|
+
const TaskDeliveryTarget({
|
|
648
|
+
required this.platform,
|
|
649
|
+
required this.platformLabel,
|
|
650
|
+
required this.to,
|
|
651
|
+
required this.label,
|
|
652
|
+
required this.subtitle,
|
|
653
|
+
required this.source,
|
|
654
|
+
required this.connected,
|
|
655
|
+
required this.supportsDelivery,
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
factory TaskDeliveryTarget.fromJson(Map<dynamic, dynamic> json) {
|
|
659
|
+
final platform = json['platform']?.toString() ?? '';
|
|
660
|
+
final to = json['to']?.toString() ?? '';
|
|
661
|
+
return TaskDeliveryTarget(
|
|
662
|
+
platform: platform,
|
|
663
|
+
platformLabel:
|
|
664
|
+
json['platformLabel']?.toString().ifEmpty(platform.toUpperCase()) ??
|
|
665
|
+
platform.toUpperCase(),
|
|
666
|
+
to: to,
|
|
667
|
+
label: json['label']?.toString().ifEmpty(to) ?? to,
|
|
668
|
+
subtitle: json['subtitle']?.toString() ?? '',
|
|
669
|
+
source: json['source']?.toString().ifEmpty('discovered') ?? 'discovered',
|
|
670
|
+
connected: json['connected'] != false,
|
|
671
|
+
supportsDelivery: json['supportsDelivery'] != false,
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
final String platform;
|
|
676
|
+
final String platformLabel;
|
|
677
|
+
final String to;
|
|
678
|
+
final String label;
|
|
679
|
+
final String subtitle;
|
|
680
|
+
final String source;
|
|
681
|
+
final bool connected;
|
|
682
|
+
final bool supportsDelivery;
|
|
683
|
+
|
|
684
|
+
String get id => '$platform:$to';
|
|
685
|
+
bool get selectable => connected && supportsDelivery;
|
|
686
|
+
|
|
687
|
+
String get sourceLabel {
|
|
688
|
+
switch (source) {
|
|
689
|
+
case 'default':
|
|
690
|
+
return 'Default';
|
|
691
|
+
case 'recent':
|
|
692
|
+
return 'Recent';
|
|
693
|
+
case 'manual':
|
|
694
|
+
return 'Manual';
|
|
695
|
+
default:
|
|
696
|
+
return 'Discovered';
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
646
701
|
class MessagingQrState {
|
|
647
702
|
const MessagingQrState({required this.platform, required this.qr});
|
|
648
703
|
|