mulmoclaude 1.2.0 → 1.4.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.
- package/README.md +1 -1
- package/client/assets/{PluginScopedRoot-CjiZ2FJI.js → PluginScopedRoot-DYk4nRpW.js} +1 -1
- package/client/assets/index-7QnbsZZr.css +2 -0
- package/client/assets/{index-yQkLdtMk.js → index-C3SRVT2p.js} +84 -85
- package/client/assets/{marp-Bs_qwoKZ.js → marp-DxctLEy1.js} +12 -3
- package/client/index.html +3 -3
- package/package.json +7 -6
- package/server/agent/attachmentConverter.ts +0 -25
- package/server/agent/mcp-server.ts +27 -8
- package/server/api/auth/viewToken.ts +16 -8
- package/server/api/routes/agent.ts +49 -11
- package/server/api/routes/collections.ts +274 -102
- package/server/api/routes/files.ts +57 -54
- package/server/api/routes/mulmo-script.ts +257 -895
- package/server/api/routes/wiki/history.ts +17 -19
- package/server/build/dispatcher.mjs +2 -2
- package/server/events/collection-change.ts +1 -5
- package/server/events/file-change.ts +1 -6
- package/server/events/pub-sub/index.ts +15 -2
- package/server/events/relay-client.ts +6 -1
- package/server/events/session-store/index.ts +11 -2
- package/server/index.ts +51 -78
- package/server/plugins/diagnostics.ts +0 -6
- package/server/plugins/mulmoscript-server.ts +58 -0
- package/server/prompts/system/system.md +2 -3
- package/server/remoteHost/handlers/getCollection.ts +5 -4
- package/server/remoteHost/handlers/getFeed.ts +10 -5
- package/server/remoteHost/handlers/googleCalendar.ts +50 -3
- package/server/remoteHost/handlers/index.ts +3 -1
- package/server/services/translation/index.ts +10 -3
- package/server/utils/errors.ts +7 -21
- package/server/utils/files/html-store.ts +2 -16
- package/server/utils/files/journal-io.ts +0 -12
- package/server/utils/files/plugins-io.ts +2 -11
- package/server/utils/files/safe.ts +39 -0
- package/server/utils/httpError.ts +6 -0
- package/server/utils/text.ts +7 -23
- package/server/utils/time.ts +0 -3
- package/server/workspace/collections/index.ts +6 -4
- package/server/workspace/collections/remoteView.ts +31 -22
- package/server/workspace/collections/watcher.ts +1 -0
- package/server/workspace/custom-dirs.ts +16 -6
- package/server/workspace/journal/state.ts +1 -9
- package/server/workspace/memory/topic-index-hook.ts +0 -9
- package/server/workspace/memory/topic-io.ts +0 -4
- package/server/workspace/reference-dirs.ts +8 -3
- package/server/workspace/skills/external/catalog.ts +24 -13
- package/server/workspace/skills/writer.ts +20 -16
- package/server/workspace/wiki-pages/snapshot.ts +13 -12
- package/src/components/SettingsGoogleTab.vue +4 -1
- package/src/components/StackView.vue +12 -1
- package/src/composables/collections/uiHost.ts +2 -1
- package/src/composables/useChatScroll.ts +18 -6
- package/src/composables/useFileDropZone.ts +3 -15
- package/src/composables/useFileSelection.ts +4 -1
- package/src/composables/useStickToBottom.ts +51 -0
- package/src/config/apiRoutes.ts +20 -0
- package/src/config/roles.ts +0 -4
- package/src/lang/de.ts +0 -30
- package/src/lang/en.ts +0 -30
- package/src/lang/es.ts +0 -30
- package/src/lang/fr.ts +0 -30
- package/src/lang/ja.ts +0 -30
- package/src/lang/ko.ts +0 -30
- package/src/lang/pt-BR.ts +0 -30
- package/src/lang/zh.ts +0 -30
- package/src/plugins/accounting/index.ts +0 -2
- package/src/plugins/api.ts +0 -6
- package/src/plugins/canvas/index.ts +0 -2
- package/src/plugins/chart/index.ts +0 -2
- package/src/plugins/editImages/index.ts +0 -2
- package/src/plugins/generateImage/index.ts +0 -2
- package/src/plugins/manageSkills/index.ts +0 -2
- package/src/plugins/markdown/index.ts +0 -2
- package/src/plugins/photoLocations/index.ts +0 -2
- package/src/plugins/presentCollection/index.ts +0 -2
- package/src/plugins/presentForm/index.ts +0 -2
- package/src/plugins/presentHtml/index.ts +0 -2
- package/src/plugins/presentMulmoScript/definition.ts +11 -116
- package/src/plugins/presentMulmoScript/index.ts +62 -12
- package/src/plugins/presentSVG/index.ts +0 -2
- package/src/plugins/skill/index.ts +0 -3
- package/src/plugins/spreadsheet/engine/parser.ts +0 -103
- package/src/plugins/spreadsheet/index.ts +0 -2
- package/src/plugins/textResponse/index.ts +0 -3
- package/src/plugins/wiki/index.ts +0 -2
- package/src/types/notification.ts +0 -10
- package/src/utils/api.ts +0 -4
- package/src/utils/dom/scrollable.ts +15 -0
- package/src/utils/errors.ts +7 -38
- package/client/assets/index-D5nJbMO1.css +0 -2
- package/server/api/routes/mulmoScriptValidate.ts +0 -101
- package/server/utils/mulmoErrorCapture.ts +0 -93
- package/src/plugins/presentMulmoScript/Preview.vue +0 -23
- package/src/plugins/presentMulmoScript/View.vue +0 -1949
- package/src/plugins/presentMulmoScript/helpers.ts +0 -206
|
@@ -452,6 +452,53 @@ function pipeWithErrorHandling(stream: ReadStream, res: Response<ErrorResponse>)
|
|
|
452
452
|
stream.pipe(res);
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
// Apply the UI-visibility filters (hidden dirs, sensitive files,
|
|
456
|
+
// symlinks, .gitignore matches) to a single directory entry and stat
|
|
457
|
+
// it. Returns the resolved child paths + stat, or null when the entry
|
|
458
|
+
// should not surface. The recursive walk and the shallow lazy-expand
|
|
459
|
+
// path share this so the filter policy lives in exactly one place.
|
|
460
|
+
async function resolveVisibleChild(
|
|
461
|
+
entry: Dirent,
|
|
462
|
+
absPath: string,
|
|
463
|
+
relPath: string,
|
|
464
|
+
localFilter: GitignoreFilter | undefined,
|
|
465
|
+
): Promise<{ childRel: string; childAbs: string; childStat: Stats } | null> {
|
|
466
|
+
if (HIDDEN_DIRS.has(entry.name)) return null;
|
|
467
|
+
if (!entry.isDirectory() && isSensitivePath(entry.name)) return null;
|
|
468
|
+
if (entry.isSymbolicLink()) return null;
|
|
469
|
+
const childRel = relPath ? path.join(relPath, entry.name) : entry.name;
|
|
470
|
+
// .gitignore check: for directories, append trailing / so
|
|
471
|
+
// directory-only patterns (e.g. "node_modules/") match.
|
|
472
|
+
if (localFilter) {
|
|
473
|
+
const testPath = entry.isDirectory() ? `${childRel}/` : childRel;
|
|
474
|
+
if (localFilter.ignores(testPath)) return null;
|
|
475
|
+
}
|
|
476
|
+
const childAbs = path.join(absPath, entry.name);
|
|
477
|
+
const childStat = await statSafeAsync(childAbs);
|
|
478
|
+
if (!childStat) return null;
|
|
479
|
+
return { childRel, childAbs, childStat };
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Await a directory's child-node promises, drop the filtered-out nulls,
|
|
483
|
+
// sort (dirs before files, alphabetical within type), and wrap them in
|
|
484
|
+
// the parent's `dir` TreeNode. Shared by the recursive and shallow
|
|
485
|
+
// builders so the assembly + ordering is defined once.
|
|
486
|
+
async function assembleDirNode(childPromises: Promise<TreeNode | null>[], relPath: string, modifiedMs: number): Promise<TreeNode> {
|
|
487
|
+
const resolved = await Promise.all(childPromises);
|
|
488
|
+
const children = resolved.filter((childNode): childNode is TreeNode => childNode !== null);
|
|
489
|
+
children.sort((leftChild, rightChild) => {
|
|
490
|
+
if (leftChild.type !== rightChild.type) return leftChild.type === "dir" ? -1 : 1;
|
|
491
|
+
return leftChild.name.localeCompare(rightChild.name);
|
|
492
|
+
});
|
|
493
|
+
return {
|
|
494
|
+
name: relPath ? path.basename(relPath) : "",
|
|
495
|
+
path: relPath,
|
|
496
|
+
type: "dir",
|
|
497
|
+
modifiedMs,
|
|
498
|
+
children,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
455
502
|
// Async workspace tree walker — recurses through the workspace with
|
|
456
503
|
// the same security filters as the original sync implementation
|
|
457
504
|
// (hidden dirs, sensitive files, symlinks all rejected) and the same
|
|
@@ -489,55 +536,23 @@ export async function buildTreeAsync(absPath: string, relPath: string, gitFilter
|
|
|
489
536
|
// root .gitignore (it's for git, not the UI). Pass a fresh empty
|
|
490
537
|
// filter so children pick up THEIR .gitignore files.
|
|
491
538
|
const localFilter = gitFilter ? gitFilter.childForDir(absPath) : new GitignoreFilter();
|
|
492
|
-
// Build every surviving child concurrently
|
|
493
|
-
//
|
|
494
|
-
// and entries that fail to stat.
|
|
539
|
+
// Build every surviving child concurrently, recursing into the ones
|
|
540
|
+
// that pass the visibility filter.
|
|
495
541
|
const childPromises: Promise<TreeNode | null>[] = entries.map(async (entry): Promise<TreeNode | null> => {
|
|
496
|
-
|
|
497
|
-
if (!
|
|
498
|
-
|
|
499
|
-
const childRel = relPath ? path.join(relPath, entry.name) : entry.name;
|
|
500
|
-
// .gitignore check: for directories, append trailing / so
|
|
501
|
-
// directory-only patterns (e.g. "node_modules/") match.
|
|
502
|
-
if (localFilter) {
|
|
503
|
-
const testPath = entry.isDirectory() ? `${childRel}/` : childRel;
|
|
504
|
-
if (localFilter.ignores(testPath)) return null;
|
|
505
|
-
}
|
|
506
|
-
const childAbs = path.join(absPath, entry.name);
|
|
507
|
-
const childStat = await statSafeAsync(childAbs);
|
|
508
|
-
if (!childStat) return null;
|
|
509
|
-
return buildTreeAsync(childAbs, childRel, localFilter);
|
|
510
|
-
});
|
|
511
|
-
const resolved = await Promise.all(childPromises);
|
|
512
|
-
const children = resolved.filter((childNode): childNode is TreeNode => childNode !== null);
|
|
513
|
-
children.sort((leftChild, rightChild) => {
|
|
514
|
-
if (leftChild.type !== rightChild.type) return leftChild.type === "dir" ? -1 : 1;
|
|
515
|
-
return leftChild.name.localeCompare(rightChild.name);
|
|
542
|
+
const child = await resolveVisibleChild(entry, absPath, relPath, localFilter);
|
|
543
|
+
if (!child) return null;
|
|
544
|
+
return buildTreeAsync(child.childAbs, child.childRel, localFilter);
|
|
516
545
|
});
|
|
517
|
-
return
|
|
518
|
-
name: relPath ? path.basename(relPath) : "",
|
|
519
|
-
path: relPath,
|
|
520
|
-
type: "dir",
|
|
521
|
-
modifiedMs: stat.mtimeMs,
|
|
522
|
-
children,
|
|
523
|
-
};
|
|
546
|
+
return assembleDirNode(childPromises, relPath, stat.mtimeMs);
|
|
524
547
|
}
|
|
525
548
|
|
|
526
549
|
// Map a single directory entry to a shallow TreeNode, applying the
|
|
527
550
|
// same hidden/sensitive/symlink/gitignore filters as the recursive
|
|
528
551
|
// walk. Returns null for entries that should not surface in the UI.
|
|
529
552
|
async function dirEntryToNode(entry: Dirent, absPath: string, relPath: string, localFilter: GitignoreFilter | undefined): Promise<TreeNode | null> {
|
|
530
|
-
|
|
531
|
-
if (!
|
|
532
|
-
|
|
533
|
-
const childRel = relPath ? path.join(relPath, entry.name) : entry.name;
|
|
534
|
-
if (localFilter) {
|
|
535
|
-
const testPath = entry.isDirectory() ? `${childRel}/` : childRel;
|
|
536
|
-
if (localFilter.ignores(testPath)) return null;
|
|
537
|
-
}
|
|
538
|
-
const childAbs = path.join(absPath, entry.name);
|
|
539
|
-
const childStat = await statSafeAsync(childAbs);
|
|
540
|
-
if (!childStat) return null;
|
|
553
|
+
const child = await resolveVisibleChild(entry, absPath, relPath, localFilter);
|
|
554
|
+
if (!child) return null;
|
|
555
|
+
const { childRel, childStat } = child;
|
|
541
556
|
if (childStat.isDirectory()) {
|
|
542
557
|
return {
|
|
543
558
|
name: entry.name,
|
|
@@ -580,19 +595,7 @@ export async function listDirShallow(absPath: string, relPath: string, gitFilter
|
|
|
580
595
|
// filter so children pick up THEIR .gitignore files.
|
|
581
596
|
const localFilter = gitFilter ? gitFilter.childForDir(absPath) : new GitignoreFilter();
|
|
582
597
|
const childPromises = entries.map((entry) => dirEntryToNode(entry, absPath, relPath, localFilter));
|
|
583
|
-
|
|
584
|
-
const children = resolved.filter((childNode): childNode is TreeNode => childNode !== null);
|
|
585
|
-
children.sort((leftChild, rightChild) => {
|
|
586
|
-
if (leftChild.type !== rightChild.type) return leftChild.type === "dir" ? -1 : 1;
|
|
587
|
-
return leftChild.name.localeCompare(rightChild.name);
|
|
588
|
-
});
|
|
589
|
-
return {
|
|
590
|
-
name: relPath ? path.basename(relPath) : "",
|
|
591
|
-
path: relPath,
|
|
592
|
-
type: "dir",
|
|
593
|
-
modifiedMs: stat.mtimeMs,
|
|
594
|
-
children,
|
|
595
|
-
};
|
|
598
|
+
return assembleDirNode(childPromises, relPath, stat.mtimeMs);
|
|
596
599
|
}
|
|
597
600
|
|
|
598
601
|
router.get(API_ROUTES.files.tree, async (_req: Request<object, unknown, unknown, object>, res: Response<TreeNode | ErrorResponse>) => {
|