@lobehub/lobehub 2.0.0-next.257 → 2.0.0-next.259
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/CHANGELOG.md +50 -0
- package/apps/desktop/{electron-builder.js → electron-builder.mjs} +24 -11
- package/apps/desktop/electron.vite.config.ts +10 -4
- package/apps/desktop/native-deps.config.mjs +102 -0
- package/apps/desktop/package.json +8 -7
- package/apps/desktop/src/main/__mocks__/node-mac-permissions.ts +21 -0
- package/apps/desktop/src/main/__mocks__/setup.ts +8 -0
- package/apps/desktop/src/main/controllers/SystemCtr.ts +20 -159
- package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +58 -90
- package/apps/desktop/src/main/utils/permissions.ts +307 -0
- package/apps/desktop/tsconfig.json +2 -1
- package/apps/desktop/vitest.config.mts +1 -0
- package/changelog/v1.json +18 -0
- package/locales/en-US/setting.json +1 -0
- package/locales/zh-CN/setting.json +1 -0
- package/package.json +1 -1
- package/packages/builtin-tool-memory/package.json +2 -1
- package/packages/builtin-tool-memory/src/executor/index.ts +2 -30
- package/packages/database/src/schemas/agentCronJob.ts +53 -19
- package/packages/file-loaders/package.json +1 -1
- package/packages/prompts/src/prompts/userMemory/__snapshots__/formatSearchResults.test.ts.snap +65 -0
- package/packages/prompts/src/prompts/userMemory/formatSearchResults.test.ts +200 -0
- package/packages/prompts/src/prompts/userMemory/formatSearchResults.ts +164 -0
- package/packages/prompts/src/prompts/userMemory/index.ts +2 -0
- package/scripts/electronWorkflow/buildNextApp.mts +39 -1
- package/scripts/electronWorkflow/modifiers/nextConfig.mts +26 -0
- package/src/app/[variants]/(main)/chat/cron/[cronId]/index.tsx +12 -8
- package/src/app/[variants]/(main)/chat/profile/features/AgentCronJobs/CronJobForm.tsx +9 -7
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Inspector/ToolTitle.tsx +0 -9
- package/src/features/PageEditor/Copilot/index.tsx +0 -1
- package/apps/desktop/src/main/utils/fullDiskAccess.ts +0 -121
|
@@ -85,13 +85,15 @@ const AutoSaveHintSlot = memo(() => {
|
|
|
85
85
|
return <AutoSaveHint lastUpdatedTime={lastUpdatedTime} saveStatus={status} />;
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
+
// Standard cron format: minute hour day month weekday
|
|
88
89
|
const CRON_PATTERNS = [
|
|
89
|
-
{ label: 'agentCronJobs.interval.30min', value: '
|
|
90
|
-
{ label: 'agentCronJobs.interval.1hour', value: '0
|
|
90
|
+
{ label: 'agentCronJobs.interval.30min', value: '*/30 * * * *' },
|
|
91
|
+
{ label: 'agentCronJobs.interval.1hour', value: '0 * * * *' },
|
|
92
|
+
{ label: 'agentCronJobs.interval.2hours', value: '0 */2 * * *' },
|
|
91
93
|
{ label: 'agentCronJobs.interval.6hours', value: '0 */6 * * *' },
|
|
92
94
|
{ label: 'agentCronJobs.interval.12hours', value: '0 */12 * * *' },
|
|
93
|
-
{ label: 'agentCronJobs.interval.daily', value: '0 0
|
|
94
|
-
{ label: 'agentCronJobs.interval.weekly', value: '0 0
|
|
95
|
+
{ label: 'agentCronJobs.interval.daily', value: '0 0 * * *' },
|
|
96
|
+
{ label: 'agentCronJobs.interval.weekly', value: '0 0 * * 0' },
|
|
95
97
|
];
|
|
96
98
|
|
|
97
99
|
const WEEKDAY_OPTIONS = [
|
|
@@ -115,13 +117,15 @@ const WEEKDAY_LABELS: Record<number, string> = {
|
|
|
115
117
|
};
|
|
116
118
|
|
|
117
119
|
const getIntervalText = (cronPattern: string) => {
|
|
120
|
+
// Standard cron format mapping
|
|
118
121
|
const intervalMap: Record<string, string> = {
|
|
122
|
+
'*/30 * * * *': 'agentCronJobs.interval.30min',
|
|
123
|
+
'0 * * * *': 'agentCronJobs.interval.1hour',
|
|
119
124
|
'0 */12 * * *': 'agentCronJobs.interval.12hours',
|
|
120
|
-
'0 */
|
|
125
|
+
'0 */2 * * *': 'agentCronJobs.interval.2hours',
|
|
121
126
|
'0 */6 * * *': 'agentCronJobs.interval.6hours',
|
|
122
|
-
'0 0 * * *': 'agentCronJobs.interval.
|
|
123
|
-
'0 0
|
|
124
|
-
'0 0 0 * 0': 'agentCronJobs.interval.weekly',
|
|
127
|
+
'0 0 * * *': 'agentCronJobs.interval.daily',
|
|
128
|
+
'0 0 * * 0': 'agentCronJobs.interval.weekly',
|
|
125
129
|
};
|
|
126
130
|
|
|
127
131
|
return intervalMap[cronPattern] || cronPattern;
|
|
@@ -26,13 +26,15 @@ interface CronJobFormProps {
|
|
|
26
26
|
onSubmit: (data: CronJobFormData) => void;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// Standard cron format: minute hour day month weekday
|
|
29
30
|
const CRON_PATTERNS = [
|
|
30
|
-
{ label: 'agentCronJobs.interval.30min', value: '
|
|
31
|
-
{ label: 'agentCronJobs.interval.1hour', value: '0
|
|
32
|
-
{ label: 'agentCronJobs.interval.
|
|
33
|
-
{ label: 'agentCronJobs.interval.
|
|
34
|
-
{ label: 'agentCronJobs.interval.
|
|
35
|
-
{ label: 'agentCronJobs.interval.
|
|
31
|
+
{ label: 'agentCronJobs.interval.30min', value: '*/30 * * * *' }, // Every 30 minutes
|
|
32
|
+
{ label: 'agentCronJobs.interval.1hour', value: '0 * * * *' }, // Every hour
|
|
33
|
+
{ label: 'agentCronJobs.interval.2hours', value: '0 */2 * * *' }, // Every 2 hours
|
|
34
|
+
{ label: 'agentCronJobs.interval.6hours', value: '0 */6 * * *' }, // Every 6 hours
|
|
35
|
+
{ label: 'agentCronJobs.interval.12hours', value: '0 */12 * * *' }, // Every 12 hours
|
|
36
|
+
{ label: 'agentCronJobs.interval.daily', value: '0 0 * * *' }, // Daily at midnight
|
|
37
|
+
{ label: 'agentCronJobs.interval.weekly', value: '0 0 * * 0' }, // Weekly on Sunday
|
|
36
38
|
];
|
|
37
39
|
|
|
38
40
|
const WEEKDAY_OPTIONS = [
|
|
@@ -120,7 +122,7 @@ const CronJobForm = memo<CronJobFormProps>(({ editingJob, formRef, onSubmit }) =
|
|
|
120
122
|
<Form
|
|
121
123
|
form={form}
|
|
122
124
|
initialValues={{
|
|
123
|
-
cronPattern: '
|
|
125
|
+
cronPattern: '*/30 * * * *', // Default to every 30 minutes
|
|
124
126
|
weekdays: [],
|
|
125
127
|
}}
|
|
126
128
|
layout="vertical"
|
|
@@ -38,15 +38,6 @@ const ToolTitle = memo<ToolTitleProps>(({ identifier, apiName, isLoading, isAbor
|
|
|
38
38
|
const isBuiltinPlugin = builtinToolIdentifiers.includes(identifier);
|
|
39
39
|
const pluginTitle = pluginHelpers.getPluginTitle(pluginMeta) ?? t('unknownPlugin');
|
|
40
40
|
|
|
41
|
-
// Debug logging for LobeHub Skill title issue
|
|
42
|
-
console.log('[ToolTitle Debug]', {
|
|
43
|
-
apiName,
|
|
44
|
-
identifier,
|
|
45
|
-
isBuiltinPlugin,
|
|
46
|
-
pluginMeta,
|
|
47
|
-
pluginTitle,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
41
|
return (
|
|
51
42
|
<div
|
|
52
43
|
className={cx(
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Full Disk Access utilities for macOS
|
|
3
|
-
* Based on https://github.com/inket/FullDiskAccess
|
|
4
|
-
*/
|
|
5
|
-
import { shell } from 'electron';
|
|
6
|
-
import { macOS } from 'electron-is';
|
|
7
|
-
import fs from 'node:fs';
|
|
8
|
-
import os from 'node:os';
|
|
9
|
-
import path from 'node:path';
|
|
10
|
-
|
|
11
|
-
import { createLogger } from './logger';
|
|
12
|
-
|
|
13
|
-
const logger = createLogger('utils:fullDiskAccess');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Get the macOS major version number
|
|
17
|
-
* Returns 0 if not macOS or unable to determine
|
|
18
|
-
*
|
|
19
|
-
* Darwin version to macOS version mapping:
|
|
20
|
-
* - Darwin 23.x = macOS 14 (Sonoma)
|
|
21
|
-
* - Darwin 22.x = macOS 13 (Ventura)
|
|
22
|
-
* - Darwin 21.x = macOS 12 (Monterey)
|
|
23
|
-
* - Darwin 20.x = macOS 11 (Big Sur)
|
|
24
|
-
* - Darwin 19.x = macOS 10.15 (Catalina)
|
|
25
|
-
* - Darwin 18.x = macOS 10.14 (Mojave)
|
|
26
|
-
*/
|
|
27
|
-
export function getMacOSMajorVersion(): number {
|
|
28
|
-
if (!macOS()) return 0;
|
|
29
|
-
try {
|
|
30
|
-
const release = os.release(); // e.g., "23.0.0" for macOS 14 (Sonoma)
|
|
31
|
-
const darwinMajor = Number.parseInt(release.split('.')[0], 10);
|
|
32
|
-
if (darwinMajor >= 20) {
|
|
33
|
-
return darwinMajor - 9; // Darwin 20 = macOS 11, Darwin 21 = macOS 12, etc.
|
|
34
|
-
}
|
|
35
|
-
// For older versions, return 10 (covers Mojave and Catalina)
|
|
36
|
-
return 10;
|
|
37
|
-
} catch {
|
|
38
|
-
return 0;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Check if Full Disk Access is granted by attempting to read a protected directory.
|
|
44
|
-
*
|
|
45
|
-
* On macOS 12+ (Monterey, Ventura, Sonoma, Sequoia): checks ~/Library/Containers/com.apple.stocks
|
|
46
|
-
* On macOS 10.14-11 (Mojave, Catalina, Big Sur): checks ~/Library/Safari
|
|
47
|
-
*
|
|
48
|
-
* Reading these directories will also register the app in TCC database,
|
|
49
|
-
* making it appear in System Settings > Privacy & Security > Full Disk Access
|
|
50
|
-
*/
|
|
51
|
-
export function checkFullDiskAccess(): boolean {
|
|
52
|
-
if (!macOS()) return true;
|
|
53
|
-
|
|
54
|
-
const homeDir = os.homedir();
|
|
55
|
-
const macOSVersion = getMacOSMajorVersion();
|
|
56
|
-
|
|
57
|
-
// Determine which protected directory to check based on macOS version
|
|
58
|
-
let checkPath: string;
|
|
59
|
-
if (macOSVersion >= 12) {
|
|
60
|
-
// macOS 12+ (Monterey, Ventura, Sonoma, Sequoia)
|
|
61
|
-
checkPath = path.join(homeDir, 'Library', 'Containers', 'com.apple.stocks');
|
|
62
|
-
} else {
|
|
63
|
-
// macOS 10.14-11 (Mojave, Catalina, Big Sur)
|
|
64
|
-
checkPath = path.join(homeDir, 'Library', 'Safari');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
fs.readdirSync(checkPath);
|
|
69
|
-
logger.info(`[FullDiskAccess] Access granted (able to read ${checkPath})`);
|
|
70
|
-
return true;
|
|
71
|
-
} catch {
|
|
72
|
-
logger.info(`[FullDiskAccess] Access not granted (unable to read ${checkPath})`);
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Open Full Disk Access settings page in System Settings
|
|
79
|
-
*
|
|
80
|
-
* NOTE: Full Disk Access cannot be requested programmatically.
|
|
81
|
-
* User must manually add the app in System Settings.
|
|
82
|
-
* There is NO entitlement for Full Disk Access - it's purely TCC controlled.
|
|
83
|
-
*/
|
|
84
|
-
export async function openFullDiskAccessSettings(): Promise<void> {
|
|
85
|
-
if (!macOS()) {
|
|
86
|
-
logger.info('[FullDiskAccess] Not macOS, skipping');
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
logger.info('[FullDiskAccess] Opening Full Disk Access settings...');
|
|
91
|
-
|
|
92
|
-
// On macOS 13+ (Ventura), System Preferences is replaced by System Settings,
|
|
93
|
-
// and deep links may differ. We try multiple known schemes for compatibility.
|
|
94
|
-
const candidates = [
|
|
95
|
-
// macOS 13+ (Ventura and later) - System Settings
|
|
96
|
-
'x-apple.systempreferences:com.apple.settings.PrivacySecurity.extension?Privacy_AllFiles',
|
|
97
|
-
// macOS 13+ alternative format
|
|
98
|
-
'x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles',
|
|
99
|
-
];
|
|
100
|
-
|
|
101
|
-
for (const url of candidates) {
|
|
102
|
-
try {
|
|
103
|
-
logger.info(`[FullDiskAccess] Trying URL: ${url}`);
|
|
104
|
-
await shell.openExternal(url);
|
|
105
|
-
logger.info(`[FullDiskAccess] Successfully opened via ${url}`);
|
|
106
|
-
return;
|
|
107
|
-
} catch (error) {
|
|
108
|
-
logger.warn(`[FullDiskAccess] Failed with URL ${url}:`, error);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Fallback: open Privacy & Security pane
|
|
113
|
-
try {
|
|
114
|
-
const fallbackUrl = 'x-apple.systempreferences:com.apple.preference.security?Privacy';
|
|
115
|
-
logger.info(`[FullDiskAccess] Trying fallback URL: ${fallbackUrl}`);
|
|
116
|
-
await shell.openExternal(fallbackUrl);
|
|
117
|
-
logger.info('[FullDiskAccess] Opened Privacy & Security settings as fallback');
|
|
118
|
-
} catch (error) {
|
|
119
|
-
logger.error('[FullDiskAccess] Failed to open any Privacy settings:', error);
|
|
120
|
-
}
|
|
121
|
-
}
|