@aurora-foundation/obsidian-next 0.4.8 → 0.4.10

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 (61) hide show
  1. package/dist/chunk-2JWDGXTR.js +42 -0
  2. package/dist/chunk-3UCL6RYE.js +7272 -0
  3. package/dist/chunk-3VZGPA3N.js +42 -0
  4. package/dist/chunk-3XR3GZLX.js +7809 -0
  5. package/dist/chunk-6YJSTQKN.js +7817 -0
  6. package/dist/chunk-7XFP3ZUD.js +42 -0
  7. package/dist/chunk-ASDVTRIQ.js +7805 -0
  8. package/dist/chunk-BAKREPY2.js +439 -0
  9. package/dist/chunk-BFRO5BO2.js +42 -0
  10. package/dist/chunk-CHNVBJN3.js +7272 -0
  11. package/dist/chunk-DAR45YDV.js +42 -0
  12. package/dist/chunk-FNXAI27K.js +7812 -0
  13. package/dist/chunk-HKPL675M.js +42 -0
  14. package/dist/chunk-INEXRRON.js +42 -0
  15. package/dist/chunk-ISO6GNIB.js +429 -0
  16. package/dist/chunk-MGDY5JUY.js +581 -0
  17. package/dist/chunk-OFTKVOQ2.js +7828 -0
  18. package/dist/chunk-PD4ZKYTJ.js +7838 -0
  19. package/dist/chunk-PQSPCOJ7.js +7616 -0
  20. package/dist/chunk-QSEH5NXV.js +7807 -0
  21. package/dist/chunk-RUEIA6Z5.js +42 -0
  22. package/dist/chunk-S5IDXE2L.js +42 -0
  23. package/dist/chunk-UG3HWGIO.js +42 -0
  24. package/dist/chunk-UOESII6R.js +42 -0
  25. package/dist/chunk-VWMT4HCP.js +7668 -0
  26. package/dist/chunk-YFQI44IA.js +42 -0
  27. package/dist/chunk-ZR7MEF3B.js +7605 -0
  28. package/dist/context-NI6N46WG.js +10 -0
  29. package/dist/index.js +585 -345
  30. package/dist/memory-GXW2OA2T.js +13 -0
  31. package/dist/resume-EA6ISWW2.js +15 -0
  32. package/dist/resume-EIM5FN42.js +15 -0
  33. package/dist/resume-FBVK6NAI.js +15 -0
  34. package/dist/resume-H6J5PQIA.js +15 -0
  35. package/dist/resume-JDDVTMM4.js +15 -0
  36. package/dist/resume-JFYYR7DJ.js +15 -0
  37. package/dist/resume-KGFAZY34.js +15 -0
  38. package/dist/resume-MF5TM2ZB.js +15 -0
  39. package/dist/resume-O6PLICAA.js +15 -0
  40. package/dist/resume-PZU3PWCJ.js +15 -0
  41. package/dist/resume-YD76GI2J.js +15 -0
  42. package/dist/resume-YKAKOXWV.js +15 -0
  43. package/dist/session-37MDDCWV.js +14 -0
  44. package/dist/session-56ZI3GZV.js +14 -0
  45. package/dist/session-5OFIDWGU.js +14 -0
  46. package/dist/session-7LPACLRV.js +14 -0
  47. package/dist/session-CJ6HSKDI.js +14 -0
  48. package/dist/session-CUXGN26I.js +14 -0
  49. package/dist/session-DCGNGGMV.js +14 -0
  50. package/dist/session-LEVSW6JH.js +14 -0
  51. package/dist/session-MHZAYMLC.js +14 -0
  52. package/dist/session-NNU7OW5K.js +14 -0
  53. package/dist/session-R5UG5PZR.js +14 -0
  54. package/dist/session-T64DMDAU.js +14 -0
  55. package/dist/settings-4ALCRT5S.js +8 -0
  56. package/dist/skills/defaults/clipboard.mjs +46 -0
  57. package/dist/skills/defaults/notify.mjs +36 -0
  58. package/dist/skills/defaults/open_app.mjs +53 -0
  59. package/dist/skills/defaults/speak.mjs +47 -0
  60. package/dist/skills/defaults/spotify_control.mjs +187 -0
  61. package/package.json +7 -4
@@ -0,0 +1,42 @@
1
+ import {
2
+ session
3
+ } from "./chunk-FNXAI27K.js";
4
+ import {
5
+ bus
6
+ } from "./chunk-WQM6FFSD.js";
7
+
8
+ // src/commands/resume.ts
9
+ async function resumeCommand(args) {
10
+ if (args.length > 0) {
11
+ const sessionId = args[0];
12
+ try {
13
+ const result = await session.restore(sessionId);
14
+ if (result.success) {
15
+ bus.emitAgent({
16
+ type: "thought",
17
+ content: `Resumed session: ${sessionId}`
18
+ });
19
+ } else {
20
+ bus.emitAgent({
21
+ type: "error",
22
+ message: `Failed to resume session: ${result.error}`
23
+ });
24
+ }
25
+ } catch (err) {
26
+ bus.emitAgent({
27
+ type: "error",
28
+ message: `Error resuming session: ${err}`
29
+ });
30
+ }
31
+ return;
32
+ }
33
+ bus.emitAgent({
34
+ type: "view_request",
35
+ viewId: "sessions",
36
+ command: "resume"
37
+ });
38
+ }
39
+
40
+ export {
41
+ resumeCommand
42
+ };
@@ -0,0 +1,42 @@
1
+ import {
2
+ session
3
+ } from "./chunk-VWMT4HCP.js";
4
+ import {
5
+ bus
6
+ } from "./chunk-WQM6FFSD.js";
7
+
8
+ // src/commands/resume.ts
9
+ async function resumeCommand(args) {
10
+ if (args.length > 0) {
11
+ const sessionId = args[0];
12
+ try {
13
+ const result = await session.restore(sessionId);
14
+ if (result.success) {
15
+ bus.emitAgent({
16
+ type: "thought",
17
+ content: `Resumed session: ${sessionId}`
18
+ });
19
+ } else {
20
+ bus.emitAgent({
21
+ type: "error",
22
+ message: `Failed to resume session: ${result.error}`
23
+ });
24
+ }
25
+ } catch (err) {
26
+ bus.emitAgent({
27
+ type: "error",
28
+ message: `Error resuming session: ${err}`
29
+ });
30
+ }
31
+ return;
32
+ }
33
+ bus.emitAgent({
34
+ type: "view_request",
35
+ viewId: "sessions",
36
+ command: "resume"
37
+ });
38
+ }
39
+
40
+ export {
41
+ resumeCommand
42
+ };
@@ -0,0 +1,429 @@
1
+ // src/core/settings.ts
2
+ import fs from "fs/promises";
3
+ import path from "path";
4
+ import os from "os";
5
+ import { z } from "zod";
6
+
7
+ // src/core/settings-cache.ts
8
+ import { EventEmitter } from "events";
9
+ var DEFAULT_CACHE_OPTIONS = {
10
+ ttl: 5e3,
11
+ // 5 seconds (balance freshness vs performance)
12
+ maxSize: 100,
13
+ // 100 entries max
14
+ enabled: true
15
+ // Cache enabled by default
16
+ };
17
+ var SettingsCache = class extends EventEmitter {
18
+ cache = /* @__PURE__ */ new Map();
19
+ options;
20
+ hits = 0;
21
+ misses = 0;
22
+ constructor(options = {}) {
23
+ super();
24
+ this.options = { ...DEFAULT_CACHE_OPTIONS, ...options };
25
+ }
26
+ /**
27
+ * Get cached value or execute loader if miss/expired
28
+ */
29
+ async get(key, loader, ttl) {
30
+ if (!this.options.enabled) {
31
+ return await loader();
32
+ }
33
+ const cached = this.cache.get(key);
34
+ const now = Date.now();
35
+ const effectiveTtl = ttl ?? this.options.ttl;
36
+ if (cached && now - cached.timestamp < effectiveTtl) {
37
+ this.hits++;
38
+ cached.hits++;
39
+ this.emit("hit", { key, hits: cached.hits });
40
+ return cached.value;
41
+ }
42
+ this.misses++;
43
+ this.emit("miss", { key });
44
+ const value = await loader();
45
+ this.set(key, value, effectiveTtl);
46
+ return value;
47
+ }
48
+ /**
49
+ * Set cache entry (internal use)
50
+ */
51
+ set(key, value, ttl = this.options.ttl) {
52
+ if (this.cache.size >= this.options.maxSize) {
53
+ this.evictLRU();
54
+ }
55
+ this.cache.set(key, {
56
+ value,
57
+ timestamp: Date.now(),
58
+ hits: 0
59
+ });
60
+ this.emit("set", { key, size: this.cache.size });
61
+ }
62
+ /**
63
+ * Invalidate specific key or pattern
64
+ */
65
+ invalidate(keyOrPattern) {
66
+ if (typeof keyOrPattern === "string") {
67
+ this.cache.delete(keyOrPattern);
68
+ this.emit("invalidate", { key: keyOrPattern });
69
+ } else {
70
+ const keysToDelete = [];
71
+ for (const key of this.cache.keys()) {
72
+ if (keyOrPattern.test(key)) {
73
+ keysToDelete.push(key);
74
+ }
75
+ }
76
+ keysToDelete.forEach((k) => this.cache.delete(k));
77
+ this.emit("invalidate", { pattern: keyOrPattern.source, count: keysToDelete.length });
78
+ }
79
+ }
80
+ /**
81
+ * Clear entire cache
82
+ */
83
+ clear() {
84
+ const size = this.cache.size;
85
+ this.cache.clear();
86
+ this.hits = 0;
87
+ this.misses = 0;
88
+ this.emit("clear", { size });
89
+ }
90
+ /**
91
+ * Evict least-recently-used entry (lowest hit count)
92
+ */
93
+ evictLRU() {
94
+ let lruKey = null;
95
+ let minHits = Infinity;
96
+ for (const [key, entry] of this.cache.entries()) {
97
+ if (entry.hits < minHits) {
98
+ minHits = entry.hits;
99
+ lruKey = key;
100
+ }
101
+ }
102
+ if (lruKey) {
103
+ this.cache.delete(lruKey);
104
+ this.emit("evict", { key: lruKey, hits: minHits });
105
+ }
106
+ }
107
+ /**
108
+ * Get cache statistics (for monitoring/debugging)
109
+ */
110
+ getStats() {
111
+ const total = this.hits + this.misses;
112
+ const hitRate = total > 0 ? this.hits / total * 100 : 0;
113
+ return {
114
+ hits: this.hits,
115
+ misses: this.misses,
116
+ hitRate: hitRate.toFixed(2) + "%",
117
+ size: this.cache.size,
118
+ maxSize: this.options.maxSize,
119
+ enabled: this.options.enabled
120
+ };
121
+ }
122
+ /**
123
+ * Enable/disable cache dynamically
124
+ */
125
+ setEnabled(enabled) {
126
+ this.options.enabled = enabled;
127
+ if (!enabled) {
128
+ this.clear();
129
+ }
130
+ this.emit("toggle", { enabled });
131
+ }
132
+ };
133
+ var settingsCache = new SettingsCache({
134
+ ttl: 5e3,
135
+ // 5 seconds TTL
136
+ maxSize: 100,
137
+ // 100 entries
138
+ enabled: true
139
+ // Enabled by default
140
+ });
141
+ async function cachedSettings(key, loader, ttl) {
142
+ return settingsCache.get(key, loader, ttl);
143
+ }
144
+ function invalidateSettingsCache() {
145
+ settingsCache.invalidate(/^settings:/);
146
+ }
147
+
148
+ // src/core/settings.ts
149
+ var SETTINGS_DIR = ".obsidian-next";
150
+ var SETTINGS_FILE = "settings.json";
151
+ var SettingsSchema = z.object({
152
+ // Execution mode
153
+ mode: z.enum(["auto", "plan", "safe"]).default("safe"),
154
+ // Auto-accept settings
155
+ autoAccept: z.object({
156
+ enabled: z.boolean().default(false),
157
+ readOperations: z.boolean().default(true),
158
+ safeCommands: z.boolean().default(true)
159
+ }).default({}),
160
+ // Tool permissions
161
+ permissions: z.object({
162
+ // Patterns always allowed without prompt: "tool:pattern"
163
+ allow: z.array(z.string()).default([]),
164
+ // Patterns allowed without prompt AND without sandbox
165
+ allowUnsandboxed: z.array(z.string()).default([]),
166
+ // Patterns always blocked
167
+ deny: z.array(z.string()).default([])
168
+ }).default({}),
169
+ // Security settings
170
+ security: z.object({
171
+ // PII redaction before sending to LLM
172
+ piiRedaction: z.boolean().default(true),
173
+ // Audit logging of all commands
174
+ auditLogging: z.boolean().default(true),
175
+ // Key storage backend preference
176
+ keyBackend: z.enum(["auto", "keychain", "secret-tool", "encrypted-file", "env"]).default("auto")
177
+ }).default({}),
178
+ // UI preferences
179
+ ui: z.object({
180
+ syntaxHighlight: z.boolean().default(true),
181
+ diffColors: z.boolean().default(true),
182
+ showLineNumbers: z.boolean().default(true),
183
+ // Owl animation settings
184
+ owlAnimation: z.object({
185
+ enabled: z.boolean().default(false),
186
+ flyWhenIdle: z.boolean().default(false),
187
+ idleTimeout: z.number().default(6e4),
188
+ // 60s before idle animation
189
+ sleepTimeout: z.number().default(3e5)
190
+ // 5m before sleep animation
191
+ }).default({})
192
+ }).default({}),
193
+ // Remote Gateway (Telegram)
194
+ telegram: z.object({
195
+ enabled: z.boolean().default(false),
196
+ botToken: z.string().optional(),
197
+ allowedUserIds: z.array(z.string()).default([])
198
+ }).default({})
199
+ });
200
+ var DEFAULT_SETTINGS = {
201
+ mode: "safe",
202
+ autoAccept: {
203
+ enabled: false,
204
+ readOperations: false,
205
+ safeCommands: false
206
+ },
207
+ permissions: {
208
+ allow: [],
209
+ // Empty - user builds their own allow list
210
+ allowUnsandboxed: [],
211
+ deny: []
212
+ },
213
+ security: {
214
+ piiRedaction: true,
215
+ // Enabled by default - protects user privacy
216
+ auditLogging: true,
217
+ // Enabled by default - for accountability
218
+ keyBackend: "auto"
219
+ // Auto-detect best available backend
220
+ },
221
+ ui: {
222
+ syntaxHighlight: true,
223
+ diffColors: true,
224
+ showLineNumbers: true,
225
+ owlAnimation: {
226
+ enabled: false,
227
+ flyWhenIdle: false,
228
+ idleTimeout: 6e4,
229
+ // 60s before idle animation
230
+ sleepTimeout: 3e5
231
+ // 5m before sleep animation
232
+ }
233
+ },
234
+ telegram: {
235
+ enabled: false,
236
+ allowedUserIds: []
237
+ }
238
+ };
239
+ var SettingsManager = class {
240
+ settingsPath;
241
+ cache = null;
242
+ sessionAllow = /* @__PURE__ */ new Set();
243
+ sessionUnsandboxed = /* @__PURE__ */ new Set();
244
+ sessionDeny = /* @__PURE__ */ new Set();
245
+ constructor() {
246
+ this.settingsPath = path.join(os.homedir(), SETTINGS_DIR, SETTINGS_FILE);
247
+ }
248
+ async load() {
249
+ if (this.cache) return this.cache;
250
+ return this.reload();
251
+ }
252
+ async reload() {
253
+ try {
254
+ const data = await fs.readFile(this.settingsPath, "utf-8");
255
+ const parsed = JSON.parse(data);
256
+ this.cache = SettingsSchema.parse({ ...DEFAULT_SETTINGS, ...parsed });
257
+ } catch {
258
+ this.cache = DEFAULT_SETTINGS;
259
+ await this.save(DEFAULT_SETTINGS);
260
+ }
261
+ return this.cache;
262
+ }
263
+ /**
264
+ * Add a permission to the allow list (called when user approves a command)
265
+ */
266
+ async addAllowedPermission(tool, command) {
267
+ const s = await this.load();
268
+ const pattern = `${tool}:${command}`;
269
+ if (!s.permissions.allow.includes(pattern)) {
270
+ s.permissions.allow.push(pattern);
271
+ await this.save({ permissions: s.permissions });
272
+ }
273
+ }
274
+ /**
275
+ * Add a permission to the unsandboxed allow list
276
+ */
277
+ async addUnsandboxedPermission(tool, command) {
278
+ const s = await this.load();
279
+ const pattern = `${tool}:${command}`;
280
+ if (!s.permissions.allowUnsandboxed.includes(pattern)) {
281
+ s.permissions.allowUnsandboxed.push(pattern);
282
+ if (!s.permissions.allow.includes(pattern)) {
283
+ s.permissions.allow.push(pattern);
284
+ }
285
+ await this.save({ permissions: s.permissions });
286
+ }
287
+ }
288
+ /**
289
+ * Add a permission to the session-only allow/deny list
290
+ */
291
+ async addSessionPermission(tool, command, approved, bypass = false) {
292
+ const pattern = `${tool}:${command}`;
293
+ if (approved) {
294
+ this.sessionAllow.add(pattern);
295
+ this.sessionDeny.delete(pattern);
296
+ if (bypass) {
297
+ this.sessionUnsandboxed.add(pattern);
298
+ }
299
+ } else {
300
+ this.sessionDeny.add(pattern);
301
+ this.sessionAllow.delete(pattern);
302
+ this.sessionUnsandboxed.delete(pattern);
303
+ }
304
+ }
305
+ /**
306
+ * Add a permission to the deny list
307
+ */
308
+ async addDeniedPermission(tool, command) {
309
+ const s = await this.load();
310
+ const pattern = `${tool}:${command}`;
311
+ if (!s.permissions.deny.includes(pattern)) {
312
+ s.permissions.deny.push(pattern);
313
+ await this.save({ permissions: s.permissions });
314
+ }
315
+ }
316
+ async save(newSettings) {
317
+ const current = await this.load();
318
+ const merged = { ...current, ...newSettings };
319
+ if (newSettings.autoAccept) {
320
+ merged.autoAccept = { ...current.autoAccept, ...newSettings.autoAccept };
321
+ }
322
+ if (newSettings.permissions) {
323
+ merged.permissions = {
324
+ ...current.permissions,
325
+ ...newSettings.permissions
326
+ };
327
+ }
328
+ if (newSettings.security) {
329
+ merged.security = { ...current.security, ...newSettings.security };
330
+ }
331
+ if (newSettings.ui) {
332
+ merged.ui = { ...current.ui, ...newSettings.ui };
333
+ }
334
+ const validated = SettingsSchema.parse(merged);
335
+ const dir = path.dirname(this.settingsPath);
336
+ await fs.mkdir(dir, { recursive: true });
337
+ await fs.writeFile(this.settingsPath, JSON.stringify(validated, null, 2));
338
+ this.cache = validated;
339
+ invalidateSettingsCache();
340
+ }
341
+ async get(key) {
342
+ const s = await this.load();
343
+ return s[key];
344
+ }
345
+ async set(key, value) {
346
+ await this.save({ [key]: value });
347
+ }
348
+ /**
349
+ * Check if a tool:command pattern is authorized for THIS SESSION only
350
+ */
351
+ async isSessionAuthorized(tool, command) {
352
+ const pattern = `${tool}:${command}`;
353
+ return this.sessionAllow.has(pattern);
354
+ }
355
+ /**
356
+ * Check if a tool:command pattern is allowed (session or persistent)
357
+ */
358
+ async isAllowed(tool, command) {
359
+ const pattern = `${tool}:${command}`;
360
+ if (this.sessionAllow.has(pattern)) {
361
+ return true;
362
+ }
363
+ const s = await this.load();
364
+ for (const deny of s.permissions.deny) {
365
+ if (this.matchPattern(pattern, deny)) {
366
+ return false;
367
+ }
368
+ }
369
+ for (const allow of s.permissions.allow) {
370
+ if (this.matchPattern(pattern, allow)) {
371
+ return true;
372
+ }
373
+ }
374
+ return false;
375
+ }
376
+ /**
377
+ * Check if a tool:command pattern is allowed to bypass sandbox
378
+ */
379
+ async isUnsandboxed(tool, command) {
380
+ const pattern = `${tool}:${command}`;
381
+ if (this.sessionUnsandboxed.has(pattern)) {
382
+ return true;
383
+ }
384
+ const s = await this.load();
385
+ for (const allow of s.permissions.allowUnsandboxed) {
386
+ if (this.matchPattern(pattern, allow)) {
387
+ return true;
388
+ }
389
+ }
390
+ return false;
391
+ }
392
+ /**
393
+ * Check if a tool:command pattern is explicitly denied
394
+ */
395
+ async isDenied(tool, command) {
396
+ const pattern = `${tool}:${command}`;
397
+ if (this.sessionDeny.has(pattern)) {
398
+ return true;
399
+ }
400
+ const s = await this.load();
401
+ for (const deny of s.permissions.deny) {
402
+ if (this.matchPattern(pattern, deny)) {
403
+ return true;
404
+ }
405
+ }
406
+ return false;
407
+ }
408
+ /**
409
+ * Simple glob-like pattern matching
410
+ * Supports * as wildcard
411
+ */
412
+ matchPattern(value, pattern) {
413
+ const regex = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
414
+ return new RegExp(`^${regex}$`).test(value);
415
+ }
416
+ clearCache() {
417
+ this.cache = null;
418
+ }
419
+ getPath() {
420
+ return this.settingsPath;
421
+ }
422
+ };
423
+ var settings = new SettingsManager();
424
+
425
+ export {
426
+ cachedSettings,
427
+ SettingsSchema,
428
+ settings
429
+ };