@mulmoclaude/core 1.5.0 → 1.7.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/assets/helps/bug-report-faq.md +130 -0
- package/assets/helps/error-recovery.md +134 -1
- package/assets/helps/google-calendar-collection.md +57 -3
- package/assets/helps/google.md +3 -2
- package/assets/helps/index.md +2 -1
- package/dist/calendarGrid-CaS9er8i.cjs +576 -0
- package/dist/calendarGrid-CaS9er8i.cjs.map +1 -0
- package/dist/calendarGrid-CrGxeCOG.js +397 -0
- package/dist/calendarGrid-CrGxeCOG.js.map +1 -0
- package/dist/collection/index.cjs +44 -44
- package/dist/collection/index.cjs.map +1 -1
- package/dist/collection/index.js +2 -2
- package/dist/collection/registry/server/index.cjs +2 -2
- package/dist/collection/registry/server/index.js +2 -2
- package/dist/collection/server/index.cjs +4 -4
- package/dist/collection/server/index.js +3 -3
- package/dist/collection-watchers/index.cjs +5 -5
- package/dist/collection-watchers/index.cjs.map +1 -1
- package/dist/collection-watchers/index.js +4 -4
- package/dist/{discovery--kRUWed0.cjs → discovery-DYcR83qx.cjs} +64 -53
- package/dist/discovery-DYcR83qx.cjs.map +1 -0
- package/dist/{discovery-CKR4TOX3.js → discovery-_fjsluLx.js} +43 -32
- package/dist/discovery-_fjsluLx.js.map +1 -0
- package/dist/feeds/index.cjs +4 -4
- package/dist/feeds/index.js +2 -2
- package/dist/feeds/server/index.cjs +6 -6
- package/dist/feeds/server/index.js +4 -4
- package/dist/google/apiClient.d.ts +6 -0
- package/dist/google/calendar.d.ts +79 -8
- package/dist/google/calendarPushState.d.ts +17 -0
- package/dist/google/collectionPush.d.ts +64 -0
- package/dist/google/collectionSync.d.ts +10 -0
- package/dist/google/index.cjs +712 -36
- package/dist/google/index.cjs.map +1 -1
- package/dist/google/index.d.ts +7 -3
- package/dist/google/index.js +683 -37
- package/dist/google/index.js.map +1 -1
- package/dist/google/pushDateTime.d.ts +10 -0
- package/dist/google/pushPlan.d.ts +73 -0
- package/dist/{ingestTypes-xX8VpQqh.cjs → ingestTypes-D1GQdG8e.cjs} +3 -3
- package/dist/{ingestTypes-xX8VpQqh.cjs.map → ingestTypes-D1GQdG8e.cjs.map} +1 -1
- package/dist/{ingestTypes-L59cIGgX.js → ingestTypes-XReG-li7.js} +2 -2
- package/dist/{ingestTypes-L59cIGgX.js.map → ingestTypes-XReG-li7.js.map} +1 -1
- package/dist/{promptSafety-CQ5Un4wi.js → promptSafety-C--op_6a.js} +3 -269
- package/dist/promptSafety-C--op_6a.js.map +1 -0
- package/dist/{promptSafety-DfZYNtjK.cjs → promptSafety-FD8cQn3e.cjs} +8 -358
- package/dist/promptSafety-FD8cQn3e.cjs.map +1 -0
- package/dist/remote-host/index.cjs +8 -0
- package/dist/remote-host/index.cjs.map +1 -1
- package/dist/remote-host/index.d.ts +21 -0
- package/dist/remote-host/index.js +8 -1
- package/dist/remote-host/index.js.map +1 -1
- package/dist/{server-D_6FLygK.js → server-BlIrtGKl.js} +4 -4
- package/dist/{server-D_6FLygK.js.map → server-BlIrtGKl.js.map} +1 -1
- package/dist/{server-gEOeV_Nv.cjs → server-l4TZ5Lbf.cjs} +21 -21
- package/dist/{server-gEOeV_Nv.cjs.map → server-l4TZ5Lbf.cjs.map} +1 -1
- package/dist/workspace-setup/faq-entries.d.ts +24 -0
- package/dist/workspace-setup/index.d.ts +1 -0
- package/dist/workspace-setup/index.js +50 -1
- package/dist/workspace-setup/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/discovery--kRUWed0.cjs.map +0 -1
- package/dist/discovery-CKR4TOX3.js.map +0 -1
- package/dist/ids-BnTh3Hl0.cjs +0 -226
- package/dist/ids-BnTh3Hl0.cjs.map +0 -1
- package/dist/ids-s4GfmE93.js +0 -131
- package/dist/ids-s4GfmE93.js.map +0 -1
- package/dist/promptSafety-CQ5Un4wi.js.map +0 -1
- package/dist/promptSafety-DfZYNtjK.cjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as writeFileAtomic } from "./atomic-DPpdrJzO.js";
|
|
2
|
-
import {
|
|
2
|
+
import { A as fieldTextOrNull, C as FEED_SCHEDULES, D as isReadOnlySchema, O as storageKindFor, S as COMPUTED_TYPES, g as SAFE_SLUG_PATTERN, h as SAFE_RECORD_ID_PATTERN, k as fieldText, v as isSafeRecordId, w as INGEST_KINDS, x as AGENT_INGEST_KIND, y as isSafeSlug } from "./calendarGrid-CrGxeCOG.js";
|
|
3
3
|
import { t as projectRecordFields } from "./project-bU98ycsy.js";
|
|
4
4
|
import { n as isSafeCustomViewI18nPath, r as isSafeCustomViewPath, t as isSafeActionTemplatePath } from "./templatePath-k_WNbL_Q.js";
|
|
5
5
|
import { realpathSync, watch } from "node:fs";
|
|
@@ -305,6 +305,35 @@ async function readItem(dataDir, itemId, opts = {}) {
|
|
|
305
305
|
throw err;
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
|
+
/** The symlink-containment refusal every record path shares: one check, one
|
|
309
|
+
* warn, one answer. Extracted because this is a security RULE applied at
|
|
310
|
+
* three sites (write pre-mkdir, write post-mkdir, delete) — a fix to the
|
|
311
|
+
* check must not be able to land at only one of them.
|
|
312
|
+
*
|
|
313
|
+
* `stage` names the call site so the warn stays as diagnosable as the three
|
|
314
|
+
* hand-written copies were.
|
|
315
|
+
*
|
|
316
|
+
* Scope, stated explicitly because a reviewer asks every time: this catches
|
|
317
|
+
* a symlink that EXISTS when we look — `isContainedInRoot` realpaths the
|
|
318
|
+
* closest existing ancestor, so a pre-planted escape is refused. It does not
|
|
319
|
+
* and cannot close the check-then-use race, where an ancestor is swapped for
|
|
320
|
+
* a symlink between this call and the `mkdir` / `open` / `unlink` that
|
|
321
|
+
* follows. Closing that needs directory-handle I/O anchored at the workspace
|
|
322
|
+
* (`openat` + `O_NOFOLLOW`), which `node:fs` does not expose — it would mean
|
|
323
|
+
* a different I/O layer, not a tighter check here.
|
|
324
|
+
*
|
|
325
|
+
* That race is deliberately outside this app's threat model: the process is
|
|
326
|
+
* loopback-bound and bearer-authed, so anyone able to swap directories inside
|
|
327
|
+
* the workspace is already the workspace owner — the same trust principal the
|
|
328
|
+
* writes belong to. Revisit if collections ever serve a lower-trust caller. */
|
|
329
|
+
function escapesWorkspace(dataDir, workspaceRoot, itemId, stage) {
|
|
330
|
+
if (isContainedInRoot(dataDir, workspaceRoot)) return false;
|
|
331
|
+
log.warn("collections", `${stage} refused: dataDir escapes workspace via symlink`, {
|
|
332
|
+
dataDir,
|
|
333
|
+
itemId
|
|
334
|
+
});
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
308
337
|
/** Write a record. Ensures the directory exists, validates the id,
|
|
309
338
|
* re-checks symlink containment after mkdir, and writes atomically.
|
|
310
339
|
*
|
|
@@ -326,27 +355,15 @@ async function writeItem(dataDir, itemId, item, opts = {}) {
|
|
|
326
355
|
itemId
|
|
327
356
|
};
|
|
328
357
|
const workspaceRoot = opts.workspaceRoot ?? getWorkspaceRoot();
|
|
329
|
-
if (
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
});
|
|
334
|
-
return {
|
|
335
|
-
kind: "path-escape",
|
|
336
|
-
itemId: safeId
|
|
337
|
-
};
|
|
338
|
-
}
|
|
358
|
+
if (escapesWorkspace(dataDir, workspaceRoot, safeId, "writeItem (pre-mkdir)")) return {
|
|
359
|
+
kind: "path-escape",
|
|
360
|
+
itemId: safeId
|
|
361
|
+
};
|
|
339
362
|
await mkdir(dataDir, { recursive: true });
|
|
340
|
-
if (
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
});
|
|
345
|
-
return {
|
|
346
|
-
kind: "path-escape",
|
|
347
|
-
itemId: safeId
|
|
348
|
-
};
|
|
349
|
-
}
|
|
363
|
+
if (escapesWorkspace(dataDir, workspaceRoot, safeId, "writeItem (post-mkdir)")) return {
|
|
364
|
+
kind: "path-escape",
|
|
365
|
+
itemId: safeId
|
|
366
|
+
};
|
|
350
367
|
const filePath = itemFilePath(dataDir, safeId);
|
|
351
368
|
const payload = `${JSON.stringify(item, null, 2)}\n`;
|
|
352
369
|
if (opts.refuseOverwrite) {
|
|
@@ -383,16 +400,10 @@ async function deleteItem(dataDir, itemId, opts = {}) {
|
|
|
383
400
|
kind: "invalid-id",
|
|
384
401
|
itemId
|
|
385
402
|
};
|
|
386
|
-
if (
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
});
|
|
391
|
-
return {
|
|
392
|
-
kind: "path-escape",
|
|
393
|
-
itemId: safeId
|
|
394
|
-
};
|
|
395
|
-
}
|
|
403
|
+
if (escapesWorkspace(dataDir, opts.workspaceRoot ?? getWorkspaceRoot(), safeId, "deleteItem")) return {
|
|
404
|
+
kind: "path-escape",
|
|
405
|
+
itemId: safeId
|
|
406
|
+
};
|
|
396
407
|
const filePath = itemFilePath(dataDir, safeId);
|
|
397
408
|
try {
|
|
398
409
|
await unlink(filePath);
|
|
@@ -2655,4 +2666,4 @@ function toDetail(collection) {
|
|
|
2655
2666
|
//#endregion
|
|
2656
2667
|
export { skillsStagingDir as $, deleteItem as A, itemFilePath as B, compileCsvQuery as C, MAX_QUERY_ROWS as D, DEFAULT_QUERY_ROWS as E, resolveCreateItemId as F, archiveDir as G, resolveTemplatePath as H, writeItem as I, getWorkspaceRoot as J, collectionsRegistriesConfigPath as K, SCHEMA_FILE as L, isRegularFile as M, listItems as N, BackendUnavailableError as O, readItem as P, setCollectionChangePublisher as Q, isContainedInRoot as R, queryCsv as S, CollectionQueryZ as T, safeRecordId as U, resolveDataDir as V, safeSlugName as W, log as X, isPresetSlug as Y, publishCollectionChange as Z, csvRowToItem as _, toDetail as a, encodeCsvRecordId as b, resolveMutateSet as c, storeFor as d, createForwardingLogger as et, checkpointSqliteDatabase as f, cacheDir as g, MAX_CSV_ROWS as h, resolvePrimaryField as i, generateItemId as j, isBackendUnavailable as k, collectionWritable as l, projectItemFields as m, discoverCollections as n, toSummary as o, pageFromFullRead as p, configureCollectionHost as q, loadCollection as r, CollectionSchemaZ as s, acceptParsedSchema as t, createHostSlot as tt, readOnlyRefusal as u, decodeCsvRecordId as v, compileJsonlQuery as w, normalizeCsvValue as x, dedupeByRecordId as y, isContainedInWorkspace as z };
|
|
2657
2668
|
|
|
2658
|
-
//# sourceMappingURL=discovery-
|
|
2669
|
+
//# sourceMappingURL=discovery-_fjsluLx.js.map
|