@steipete/oracle 0.14.0 → 0.14.1

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 (69) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/oracle-cli.js +8 -8
  3. package/dist/src/browser/actions/assistantResponse.js +2 -1
  4. package/dist/src/browser/actions/modelSelection.js +344 -29
  5. package/dist/src/browser/actions/thinkingTime.js +239 -46
  6. package/dist/src/browser/chatgptImages.js +126 -24
  7. package/dist/src/browser/index.js +63 -8
  8. package/dist/src/browser/projectSourcesRunner.js +2 -1
  9. package/dist/src/browser/prompt.js +151 -22
  10. package/dist/src/cli/browserConfig.js +2 -1
  11. package/dist/src/cli/browserDefaults.js +2 -1
  12. package/dist/src/cli/options.js +8 -0
  13. package/dist/src/mcp/tools/chatgptImage.js +8 -3
  14. package/dist/src/mcp/tools/consult.js +9 -8
  15. package/dist/src/mcp/types.js +11 -2
  16. package/dist/src/oracle/thinkingTime.js +40 -0
  17. package/dist/vendor/oracle-notifier/build-notifier.sh +0 -0
  18. package/package.json +32 -34
  19. package/vendor/oracle-notifier/build-notifier.sh +0 -0
  20. package/dist/bin/oracle.js +0 -569
  21. package/dist/docs-site/.nojekyll +0 -0
  22. package/dist/docs-site/CNAME +0 -1
  23. package/dist/docs-site/RELEASING.html +0 -410
  24. package/dist/docs-site/agents.html +0 -374
  25. package/dist/docs-site/anthropic.html +0 -368
  26. package/dist/docs-site/bridge.html +0 -400
  27. package/dist/docs-site/browser-mode.html +0 -593
  28. package/dist/docs-site/chromium-forks.html +0 -347
  29. package/dist/docs-site/cli-reference.html +0 -346
  30. package/dist/docs-site/configuration.html +0 -452
  31. package/dist/docs-site/favicon.svg +0 -14
  32. package/dist/docs-site/followup.html +0 -375
  33. package/dist/docs-site/gemini.html +0 -383
  34. package/dist/docs-site/grok.html +0 -325
  35. package/dist/docs-site/index.html +0 -360
  36. package/dist/docs-site/install.html +0 -335
  37. package/dist/docs-site/linux.html +0 -321
  38. package/dist/docs-site/llms.txt +0 -43
  39. package/dist/docs-site/manual-tests.html +0 -596
  40. package/dist/docs-site/mcp.html +0 -391
  41. package/dist/docs-site/multimodel.html +0 -364
  42. package/dist/docs-site/mythical-pro-agents.html +0 -360
  43. package/dist/docs-site/notifier.html +0 -338
  44. package/dist/docs-site/openai-endpoints.html +0 -387
  45. package/dist/docs-site/openrouter.html +0 -344
  46. package/dist/docs-site/quickstart.html +0 -369
  47. package/dist/docs-site/refactor/ux.html +0 -532
  48. package/dist/docs-site/sessions.html +0 -388
  49. package/dist/docs-site/social-card.png +0 -0
  50. package/dist/docs-site/social-card.svg +0 -79
  51. package/dist/docs-site/spec.html +0 -363
  52. package/dist/docs-site/testing.html +0 -320
  53. package/dist/docs-site/tui-debug.html +0 -326
  54. package/dist/docs-site/windows-work.html +0 -323
  55. package/dist/docs-site/windows.html +0 -320
  56. package/dist/src/browser/chromeCookies.js +0 -312
  57. package/dist/src/browser/keytarShim.js +0 -56
  58. package/dist/src/browser/windowsCookies.js +0 -219
  59. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
  60. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/Info.plist +0 -20
  61. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
  62. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/Resources/OracleIcon.icns +0 -0
  63. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/_CodeSignature/CodeResources +0 -128
  64. package/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
  65. package/vendor/oracle-notifier/OracleNotifier.app/Contents/Info.plist +0 -20
  66. package/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
  67. package/vendor/oracle-notifier/OracleNotifier.app/Contents/Resources/OracleIcon.icns +0 -0
  68. package/vendor/oracle-notifier/OracleNotifier.app/Contents/_CodeSignature/CodeResources +0 -128
  69. package/vendor/oracle-notifier/README.md +0 -26
@@ -1,56 +0,0 @@
1
- const defaultLabels = [
2
- { service: 'Chrome Safe Storage', account: 'Chrome' },
3
- { service: 'Chromium Safe Storage', account: 'Chromium' },
4
- { service: 'Microsoft Edge Safe Storage', account: 'Microsoft Edge' },
5
- { service: 'Brave Safe Storage', account: 'Brave' },
6
- { service: 'Vivaldi Safe Storage', account: 'Vivaldi' },
7
- ];
8
- function loadEnvLabels() {
9
- const raw = process.env.ORACLE_KEYCHAIN_LABELS;
10
- if (!raw)
11
- return [];
12
- try {
13
- const parsed = JSON.parse(raw);
14
- if (Array.isArray(parsed)) {
15
- return parsed
16
- .map((entry) => (entry && typeof entry === 'object' ? entry : null))
17
- .filter((entry) => Boolean(entry?.service && entry?.account));
18
- }
19
- }
20
- catch {
21
- // ignore invalid env payload
22
- }
23
- return [];
24
- }
25
- const fallbackLabels = [...loadEnvLabels(), ...defaultLabels];
26
- const disableKeytar = process.env.ORACLE_DISABLE_KEYTAR === '1' || process.env.CI === 'true';
27
- let keytar;
28
- if (disableKeytar) {
29
- keytar = {
30
- getPassword: async () => null,
31
- setPassword: async () => undefined,
32
- deletePassword: async () => false,
33
- };
34
- }
35
- else {
36
- const keytarModule = await import('keytar');
37
- keytar = (keytarModule.default ?? keytarModule);
38
- const originalGetPassword = keytar.getPassword.bind(keytar);
39
- keytar.getPassword = async (service, account) => {
40
- const primary = await originalGetPassword(service, account);
41
- if (primary) {
42
- return primary;
43
- }
44
- for (const label of fallbackLabels) {
45
- if (label.service === service && label.account === account) {
46
- continue; // already tried
47
- }
48
- const value = await originalGetPassword(label.service, label.account);
49
- if (value) {
50
- return value;
51
- }
52
- }
53
- return null;
54
- };
55
- }
56
- export default keytar;
@@ -1,219 +0,0 @@
1
- import crypto from 'node:crypto';
2
- import fs from 'node:fs/promises';
3
- import { existsSync, promises as fsp } from 'node:fs';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import sqlite3 from 'sqlite3';
7
- import { createRequire } from 'node:module';
8
- import { spawnSync } from 'node:child_process';
9
- let cachedUnprotect = null;
10
- function getUnprotectData() {
11
- if (cachedUnprotect) {
12
- return cachedUnprotect;
13
- }
14
- try {
15
- // win-dpapi is CommonJS; require it explicitly and support both named/default shapes.
16
- const dpapiModule = createRequire(import.meta.url)('win-dpapi');
17
- const unprotect = dpapiModule?.Dpapi?.unprotectData ??
18
- dpapiModule?.default?.unprotectData ??
19
- ((_) => {
20
- throw new Error('win-dpapi unprotectData not available');
21
- });
22
- cachedUnprotect = unprotect;
23
- return unprotect;
24
- }
25
- catch (error) {
26
- if (process.platform !== 'win32') {
27
- // On macOS/Linux we don't need DPAPI; return a function that makes misuse obvious.
28
- cachedUnprotect = () => {
29
- throw new Error('win-dpapi is unavailable on non-Windows platforms');
30
- };
31
- return cachedUnprotect;
32
- }
33
- throw error;
34
- }
35
- }
36
- export async function loadWindowsCookies(dbPath, filterNames) {
37
- if (process.platform !== 'win32') {
38
- throw new Error('loadWindowsCookies is only supported on Windows');
39
- }
40
- const localStatePath = await locateLocalState(dbPath);
41
- const cookiesCopy = await copyLockedFile(dbPath, 'Cookies'); // name the copy exactly "Cookies"
42
- const cookiesDirForFallback = await ensureCookiesDirForFallback(cookiesCopy);
43
- const localStateCopy = await copyLockedFile(localStatePath, 'Local State');
44
- const aesKey = await extractWindowsAesKey(localStateCopy);
45
- const rows = await readChromeCookiesDb(cookiesCopy, filterNames);
46
- const cookies = [];
47
- for (const row of rows) {
48
- const enc = row.encrypted_value && row.encrypted_value.length > 0 ? row.encrypted_value : Buffer.from(row.value ?? '', 'utf8');
49
- const decrypted = enc.length > 0 ? decryptCookie(enc, aesKey) : '';
50
- cookies.push({
51
- name: row.name,
52
- value: decrypted,
53
- domain: row.host_key?.startsWith('.') ? row.host_key.slice(1) : row.host_key,
54
- path: row.path ?? '/',
55
- expires: normalizeExpiration(row.expires_utc),
56
- secure: Boolean(row.is_secure),
57
- httpOnly: Boolean(row.is_httponly),
58
- });
59
- }
60
- if (process.env.ORACLE_DEBUG_COOKIES === '1') {
61
- // eslint-disable-next-line no-console
62
- console.log(`[cookies] windows decrypt decoded ${cookies.length} cookies from ${cookiesCopy} (fallback dir ${cookiesDirForFallback})`);
63
- }
64
- return cookies.filter((c) => c.value);
65
- }
66
- function decryptCookie(value, aesKey) {
67
- const prefix = value.slice(0, 3).toString();
68
- // Chrome prefixes AES-GCM encrypted cookies with version markers like v10/v11/v20; treat all v** the same.
69
- if (/^v\d{2}$/u.test(prefix)) {
70
- const iv = value.slice(3, 15);
71
- const tag = value.slice(value.length - 16);
72
- const data = value.slice(15, value.length - 16);
73
- const decipher = crypto.createDecipheriv('aes-256-gcm', aesKey, iv);
74
- decipher.setAuthTag(tag);
75
- const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
76
- return decrypted.toString('utf8');
77
- }
78
- const unprotectData = getUnprotectData();
79
- const unprotected = unprotectData(value, undefined, 'CurrentUser');
80
- return Buffer.from(unprotected).toString('utf8');
81
- }
82
- async function locateLocalState(dbPath) {
83
- // Prefer sibling Local State near the profile path; fall back to default location.
84
- const guess = path.resolve(path.join(path.dirname(dbPath), '..', 'Local State'));
85
- if (existsSync(guess))
86
- return guess;
87
- const localState = path.join(os.homedir(), 'AppData', 'Local', 'Google', 'Chrome', 'User Data', 'Local State');
88
- if (existsSync(localState))
89
- return localState;
90
- throw new Error('Chrome Local State not found for AES key');
91
- }
92
- async function extractWindowsAesKey(localStatePath) {
93
- const raw = await fs.readFile(localStatePath, 'utf8');
94
- const state = JSON.parse(raw);
95
- const encKeyB64 = state?.os_crypt?.encrypted_key;
96
- if (!encKeyB64)
97
- throw new Error('encrypted_key missing in Local State');
98
- const encKey = Buffer.from(encKeyB64, 'base64');
99
- const dpapiBlob = encKey.slice(5); // strip "DPAPI"
100
- const unprotectData = getUnprotectData();
101
- const unprotected = unprotectData(dpapiBlob, undefined, 'CurrentUser');
102
- return Buffer.from(unprotected);
103
- }
104
- async function readChromeCookiesDb(dbPath, filterNames) {
105
- const db = await openSqlite(dbPath);
106
- const placeholders = filterNames && filterNames.size > 0 ? `AND name IN (${Array.from(filterNames).map(() => '?').join(',')})` : '';
107
- const params = filterNames ? Array.from(filterNames) : [];
108
- const sql = `SELECT name,value,encrypted_value,host_key,path,expires_utc,is_secure,is_httponly FROM cookies WHERE host_key LIKE '%chatgpt.com%' ${placeholders}`;
109
- try {
110
- return await allSqlite(db, sql, params);
111
- }
112
- finally {
113
- db.close();
114
- }
115
- }
116
- function openSqlite(dbPath) {
117
- return new Promise((resolve, reject) => {
118
- const db = new sqlite3.Database(dbPath, sqlite3.OPEN_READONLY, (err) => {
119
- if (err)
120
- reject(err);
121
- else
122
- resolve(db);
123
- });
124
- });
125
- }
126
- async function copyLockedFile(sourcePath, targetName) {
127
- const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'oracle-cookie-'));
128
- const tempPath = targetName ? path.join(tempDir, targetName) : path.join(tempDir, path.basename(sourcePath));
129
- const psScript = `
130
- $src = '${sourcePath.replace(/'/g, "''")}'
131
- $dst = '${tempPath.replace(/'/g, "''")}'
132
- try {
133
- $fs = [System.IO.File]::Open($src, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
134
- $bytes = New-Object byte[] $fs.Length
135
- $null = $fs.Read($bytes, 0, $fs.Length)
136
- $fs.Close()
137
- [System.IO.File]::WriteAllBytes($dst, $bytes)
138
- exit 0
139
- } catch {
140
- exit 1
141
- }
142
- `;
143
- const encoded = Buffer.from(psScript, 'utf16le').toString('base64');
144
- const result = spawnSync('powershell.exe', ['-NoProfile', '-NonInteractive', '-EncodedCommand', encoded], {
145
- timeout: 15000,
146
- encoding: 'utf8',
147
- });
148
- if (result.status !== 0) {
149
- // Fallback: best-effort normal copy
150
- await fs.copyFile(sourcePath, tempPath);
151
- }
152
- if (process.env.ORACLE_DEBUG_COOKIES === '1') {
153
- // eslint-disable-next-line no-console
154
- console.log(`[cookies] copied locked file ${sourcePath} -> ${tempPath}`);
155
- }
156
- return tempPath;
157
- }
158
- // Create a directory containing a file named "Cookies" for chrome-cookies-secure fallback
159
- export async function ensureCookiesDirForFallback(cookieFile) {
160
- const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'oracle-cookies-secure-'));
161
- const target = path.join(dir, 'Cookies');
162
- await fs.copyFile(cookieFile, target);
163
- return dir;
164
- }
165
- function allSqlite(db, sql, params) {
166
- return new Promise((resolve, reject) => {
167
- db.all(sql, params, (err, rows) => {
168
- if (err)
169
- reject(err);
170
- else
171
- resolve((rows ?? []));
172
- });
173
- });
174
- }
175
- function normalizeExpiration(expires) {
176
- if (!expires || Number.isNaN(expires)) {
177
- return undefined;
178
- }
179
- const value = Number(expires);
180
- if (value <= 0)
181
- return undefined;
182
- if (value > 1_000_000_000_000) {
183
- return Math.round(value / 1_000_000 - 11644473600);
184
- }
185
- if (value > 1_000_000_000) {
186
- return Math.round(value / 1000);
187
- }
188
- return Math.round(value);
189
- }
190
- export async function materializeCookieFile(sourcePath) {
191
- if (process.platform !== 'win32')
192
- return sourcePath;
193
- const resolved = await resolveDirectoryCandidate(sourcePath);
194
- const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'oracle-cookies-'));
195
- const tempPath = path.join(tempDir, 'Cookies');
196
- await fs.copyFile(resolved, tempPath);
197
- return tempPath;
198
- }
199
- async function resolveDirectoryCandidate(inputPath) {
200
- const stat = await fs.stat(inputPath).catch(() => null);
201
- if (!stat?.isDirectory())
202
- return inputPath;
203
- const network = path.join(inputPath, 'Network', 'Cookies');
204
- const direct = path.join(inputPath, 'Cookies');
205
- if (await fileExists(network))
206
- return network;
207
- if (await fileExists(direct))
208
- return direct;
209
- return inputPath;
210
- }
211
- async function fileExists(candidate) {
212
- try {
213
- const stat = await fsp.stat(candidate);
214
- return stat.isFile();
215
- }
216
- catch {
217
- return false;
218
- }
219
- }
@@ -1,20 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleIdentifier</key>
6
- <string>com.steipete.oracle.notifier</string>
7
- <key>CFBundleName</key>
8
- <string>OracleNotifier</string>
9
- <key>CFBundleDisplayName</key>
10
- <string>Oracle Notifier</string>
11
- <key>CFBundleExecutable</key>
12
- <string>OracleNotifier</string>
13
- <key>CFBundleIconFile</key>
14
- <string>OracleIcon</string>
15
- <key>CFBundlePackageType</key>
16
- <string>APPL</string>
17
- <key>LSMinimumSystemVersion</key>
18
- <string>13.0</string>
19
- </dict>
20
- </plist>
@@ -1,128 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>files</key>
6
- <dict>
7
- <key>Resources/OracleIcon.icns</key>
8
- <data>
9
- edUHAMetayIv3xtc3Vb92VXRLfM=
10
- </data>
11
- </dict>
12
- <key>files2</key>
13
- <dict>
14
- <key>Resources/OracleIcon.icns</key>
15
- <dict>
16
- <key>hash2</key>
17
- <data>
18
- AVPJK/6w6IOsDLmZTW4hL+Za+/4wHMxZiIp0t6m3NRA=
19
- </data>
20
- </dict>
21
- </dict>
22
- <key>rules</key>
23
- <dict>
24
- <key>^Resources/</key>
25
- <true/>
26
- <key>^Resources/.*\.lproj/</key>
27
- <dict>
28
- <key>optional</key>
29
- <true/>
30
- <key>weight</key>
31
- <real>1000</real>
32
- </dict>
33
- <key>^Resources/.*\.lproj/locversion.plist$</key>
34
- <dict>
35
- <key>omit</key>
36
- <true/>
37
- <key>weight</key>
38
- <real>1100</real>
39
- </dict>
40
- <key>^Resources/Base\.lproj/</key>
41
- <dict>
42
- <key>weight</key>
43
- <real>1010</real>
44
- </dict>
45
- <key>^version.plist$</key>
46
- <true/>
47
- </dict>
48
- <key>rules2</key>
49
- <dict>
50
- <key>.*\.dSYM($|/)</key>
51
- <dict>
52
- <key>weight</key>
53
- <real>11</real>
54
- </dict>
55
- <key>^(.*/)?\.DS_Store$</key>
56
- <dict>
57
- <key>omit</key>
58
- <true/>
59
- <key>weight</key>
60
- <real>2000</real>
61
- </dict>
62
- <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
63
- <dict>
64
- <key>nested</key>
65
- <true/>
66
- <key>weight</key>
67
- <real>10</real>
68
- </dict>
69
- <key>^.*</key>
70
- <true/>
71
- <key>^Info\.plist$</key>
72
- <dict>
73
- <key>omit</key>
74
- <true/>
75
- <key>weight</key>
76
- <real>20</real>
77
- </dict>
78
- <key>^PkgInfo$</key>
79
- <dict>
80
- <key>omit</key>
81
- <true/>
82
- <key>weight</key>
83
- <real>20</real>
84
- </dict>
85
- <key>^Resources/</key>
86
- <dict>
87
- <key>weight</key>
88
- <real>20</real>
89
- </dict>
90
- <key>^Resources/.*\.lproj/</key>
91
- <dict>
92
- <key>optional</key>
93
- <true/>
94
- <key>weight</key>
95
- <real>1000</real>
96
- </dict>
97
- <key>^Resources/.*\.lproj/locversion.plist$</key>
98
- <dict>
99
- <key>omit</key>
100
- <true/>
101
- <key>weight</key>
102
- <real>1100</real>
103
- </dict>
104
- <key>^Resources/Base\.lproj/</key>
105
- <dict>
106
- <key>weight</key>
107
- <real>1010</real>
108
- </dict>
109
- <key>^[^/]+$</key>
110
- <dict>
111
- <key>nested</key>
112
- <true/>
113
- <key>weight</key>
114
- <real>10</real>
115
- </dict>
116
- <key>^embedded\.provisionprofile$</key>
117
- <dict>
118
- <key>weight</key>
119
- <real>20</real>
120
- </dict>
121
- <key>^version\.plist$</key>
122
- <dict>
123
- <key>weight</key>
124
- <real>20</real>
125
- </dict>
126
- </dict>
127
- </dict>
128
- </plist>
@@ -1,20 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleIdentifier</key>
6
- <string>com.steipete.oracle.notifier</string>
7
- <key>CFBundleName</key>
8
- <string>OracleNotifier</string>
9
- <key>CFBundleDisplayName</key>
10
- <string>Oracle Notifier</string>
11
- <key>CFBundleExecutable</key>
12
- <string>OracleNotifier</string>
13
- <key>CFBundleIconFile</key>
14
- <string>OracleIcon</string>
15
- <key>CFBundlePackageType</key>
16
- <string>APPL</string>
17
- <key>LSMinimumSystemVersion</key>
18
- <string>13.0</string>
19
- </dict>
20
- </plist>
@@ -1,128 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>files</key>
6
- <dict>
7
- <key>Resources/OracleIcon.icns</key>
8
- <data>
9
- edUHAMetayIv3xtc3Vb92VXRLfM=
10
- </data>
11
- </dict>
12
- <key>files2</key>
13
- <dict>
14
- <key>Resources/OracleIcon.icns</key>
15
- <dict>
16
- <key>hash2</key>
17
- <data>
18
- AVPJK/6w6IOsDLmZTW4hL+Za+/4wHMxZiIp0t6m3NRA=
19
- </data>
20
- </dict>
21
- </dict>
22
- <key>rules</key>
23
- <dict>
24
- <key>^Resources/</key>
25
- <true/>
26
- <key>^Resources/.*\.lproj/</key>
27
- <dict>
28
- <key>optional</key>
29
- <true/>
30
- <key>weight</key>
31
- <real>1000</real>
32
- </dict>
33
- <key>^Resources/.*\.lproj/locversion.plist$</key>
34
- <dict>
35
- <key>omit</key>
36
- <true/>
37
- <key>weight</key>
38
- <real>1100</real>
39
- </dict>
40
- <key>^Resources/Base\.lproj/</key>
41
- <dict>
42
- <key>weight</key>
43
- <real>1010</real>
44
- </dict>
45
- <key>^version.plist$</key>
46
- <true/>
47
- </dict>
48
- <key>rules2</key>
49
- <dict>
50
- <key>.*\.dSYM($|/)</key>
51
- <dict>
52
- <key>weight</key>
53
- <real>11</real>
54
- </dict>
55
- <key>^(.*/)?\.DS_Store$</key>
56
- <dict>
57
- <key>omit</key>
58
- <true/>
59
- <key>weight</key>
60
- <real>2000</real>
61
- </dict>
62
- <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
63
- <dict>
64
- <key>nested</key>
65
- <true/>
66
- <key>weight</key>
67
- <real>10</real>
68
- </dict>
69
- <key>^.*</key>
70
- <true/>
71
- <key>^Info\.plist$</key>
72
- <dict>
73
- <key>omit</key>
74
- <true/>
75
- <key>weight</key>
76
- <real>20</real>
77
- </dict>
78
- <key>^PkgInfo$</key>
79
- <dict>
80
- <key>omit</key>
81
- <true/>
82
- <key>weight</key>
83
- <real>20</real>
84
- </dict>
85
- <key>^Resources/</key>
86
- <dict>
87
- <key>weight</key>
88
- <real>20</real>
89
- </dict>
90
- <key>^Resources/.*\.lproj/</key>
91
- <dict>
92
- <key>optional</key>
93
- <true/>
94
- <key>weight</key>
95
- <real>1000</real>
96
- </dict>
97
- <key>^Resources/.*\.lproj/locversion.plist$</key>
98
- <dict>
99
- <key>omit</key>
100
- <true/>
101
- <key>weight</key>
102
- <real>1100</real>
103
- </dict>
104
- <key>^Resources/Base\.lproj/</key>
105
- <dict>
106
- <key>weight</key>
107
- <real>1010</real>
108
- </dict>
109
- <key>^[^/]+$</key>
110
- <dict>
111
- <key>nested</key>
112
- <true/>
113
- <key>weight</key>
114
- <real>10</real>
115
- </dict>
116
- <key>^embedded\.provisionprofile$</key>
117
- <dict>
118
- <key>weight</key>
119
- <real>20</real>
120
- </dict>
121
- <key>^version\.plist$</key>
122
- <dict>
123
- <key>weight</key>
124
- <real>20</real>
125
- </dict>
126
- </dict>
127
- </dict>
128
- </plist>
@@ -1,26 +0,0 @@
1
- # Oracle Notifier helper (macOS, arm64)
2
-
3
- Builds a tiny signed helper app for macOS notifications with the Oracle icon.
4
-
5
- ## Build
6
-
7
- ```bash
8
- cd vendor/oracle-notifier
9
- # Optional: notarize by setting App Store Connect key credentials
10
- export APP_STORE_CONNECT_API_KEY_P8="$(cat AuthKey_XXXXXX.p8)" # with literal newlines or \n escaped
11
- export APP_STORE_CONNECT_KEY_ID=XXXXXX
12
- export APP_STORE_CONNECT_ISSUER_ID=YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY
13
- ./build-notifier.sh
14
- ```
15
-
16
- - Requires Xcode command line tools (swiftc) and a macOS Developer ID certificate. Without a valid cert, the build fails (no ad-hoc fallback).
17
- - If `APP_STORE_CONNECT_*` vars are set, the script notarizes and staples the ticket.
18
- - Output: `OracleNotifier.app` (arm64 only), bundled with `OracleIcon.icns`.
19
-
20
- ## Usage
21
-
22
- The CLI prefers this helper on macOS; if it fails or is missing, it falls back to toasted-notifier/terminal-notifier.
23
-
24
- ## Permissions
25
-
26
- After first run, allow notifications for “Oracle Notifier” in System Settings → Notifications.