@mulmoclaude/core 0.2.15 → 0.2.16

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 (45) hide show
  1. package/dist/collection/registry/guards.d.ts +2 -0
  2. package/dist/collection/registry/index.cjs +4 -0
  3. package/dist/collection/registry/index.d.ts +2 -0
  4. package/dist/collection/registry/index.js +2 -0
  5. package/dist/collection/registry/registryIndex.d.ts +48 -0
  6. package/dist/collection/registry/server/client.d.ts +60 -0
  7. package/dist/collection/registry/server/collectionFiles.d.ts +51 -0
  8. package/dist/collection/registry/server/exportCollection.d.ts +29 -0
  9. package/dist/collection/registry/server/fetch.d.ts +8 -0
  10. package/dist/collection/registry/server/importCollection.d.ts +35 -0
  11. package/dist/collection/registry/server/importWriter.d.ts +30 -0
  12. package/dist/collection/registry/server/index.cjs +1110 -0
  13. package/dist/collection/registry/server/index.cjs.map +1 -0
  14. package/dist/collection/registry/server/index.d.ts +28 -0
  15. package/dist/collection/registry/server/index.js +1076 -0
  16. package/dist/collection/registry/server/index.js.map +1 -0
  17. package/dist/collection/registry/server/performExport.d.ts +6 -0
  18. package/dist/collection/registry/server/registriesConfig.d.ts +11 -0
  19. package/dist/collection/registry/server/skillDescription.d.ts +4 -0
  20. package/dist/collection/registry/types.d.ts +37 -0
  21. package/dist/collection/server/host.d.ts +7 -0
  22. package/dist/collection/server/index.cjs +1 -1
  23. package/dist/collection/server/index.js +1 -1
  24. package/dist/collection/server/util.d.ts +1 -0
  25. package/dist/collection-watchers/index.cjs +1 -1
  26. package/dist/collection-watchers/index.js +1 -1
  27. package/dist/feeds/server/index.cjs +1 -1
  28. package/dist/feeds/server/index.cjs.map +1 -1
  29. package/dist/feeds/server/index.js +1 -1
  30. package/dist/feeds/server/index.js.map +1 -1
  31. package/dist/notifier-ChpY0XrY.js.map +1 -1
  32. package/dist/notifier-bS8IEeLA.cjs.map +1 -1
  33. package/dist/{server-CRlmOBVQ.js → server-DRoqc8dL.js} +8 -2
  34. package/dist/server-DRoqc8dL.js.map +1 -0
  35. package/dist/{server-BjXvqGrE.cjs → server-DoDXibCq.cjs} +31 -1
  36. package/dist/server-DoDXibCq.cjs.map +1 -0
  37. package/dist/types-BKVZrtyc.js +123 -0
  38. package/dist/types-BKVZrtyc.js.map +1 -0
  39. package/dist/types-CNqkLT4M.cjs +140 -0
  40. package/dist/types-CNqkLT4M.cjs.map +1 -0
  41. package/dist/whisper/client.cjs.map +1 -1
  42. package/dist/whisper/client.js.map +1 -1
  43. package/package.json +13 -1
  44. package/dist/server-BjXvqGrE.cjs.map +0 -1
  45. package/dist/server-CRlmOBVQ.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ /** Narrow `unknown` to a plain object (not null, not array). */
2
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
@@ -0,0 +1,4 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_types = require("../../types-CNqkLT4M.cjs");
3
+ exports.OFFICIAL_REGISTRY_NAME = require_types.OFFICIAL_REGISTRY_NAME;
4
+ exports.parseRegistryIndex = require_types.parseRegistryIndex;
@@ -0,0 +1,2 @@
1
+ export { parseRegistryIndex, type RegistryEntry, type RegistryIndex, type ParseResult } from './registryIndex.js';
2
+ export { OFFICIAL_REGISTRY_NAME, type RegistryConfigEntry, type RegistrySummary, type RegistryListResponse, type RegistryImportResponse } from './types.js';
@@ -0,0 +1,2 @@
1
+ import { n as parseRegistryIndex, t as OFFICIAL_REGISTRY_NAME } from "../../types-BKVZrtyc.js";
2
+ export { OFFICIAL_REGISTRY_NAME, parseRegistryIndex };
@@ -0,0 +1,48 @@
1
+ export interface RegistryEntry {
2
+ /** `<author>/<slug>` — identity inside its source registry. NOT globally
3
+ * unique when multiple registries are configured — pair with `registryName`
4
+ * for a global key. */
5
+ id: string;
6
+ author: string;
7
+ slug: string;
8
+ title: string;
9
+ icon: string;
10
+ description: string;
11
+ version: string;
12
+ tags: string[];
13
+ license: string;
14
+ fieldCount: number;
15
+ /** Custom view labels. */
16
+ views: string[];
17
+ hasSeed: boolean;
18
+ seedCount: number;
19
+ /** repo-relative path, omitted when absent. */
20
+ screenshot?: string;
21
+ /** repo-relative collection dir. */
22
+ path: string;
23
+ /** Stable bundle hash for update detection. */
24
+ contentSha: string;
25
+ /** Label of the source registry. Set by the client (not by the parser) when
26
+ * the index is fetched, so the import / preview path can resolve the right
27
+ * rawBase. `"official"` for receptron/mulmoclaude-collections; otherwise
28
+ * the user's config entry name. */
29
+ registryName: string;
30
+ }
31
+ export interface RegistryIndex {
32
+ schemaVersion: number;
33
+ generatedAt: string;
34
+ registry: string;
35
+ collections: RegistryEntry[];
36
+ }
37
+ export type ParseResult = {
38
+ ok: true;
39
+ index: RegistryIndex;
40
+ } | {
41
+ ok: false;
42
+ error: string;
43
+ };
44
+ /** Parse an index payload. `registryName` labels every entry produced — the
45
+ * caller passes "official" for the canonical registry or the user's config
46
+ * entry name. The label is needed downstream so import / preview can pick the
47
+ * right rawBase for per-collection files. */
48
+ export declare function parseRegistryIndex(value: unknown, registryName: string): ParseResult;
@@ -0,0 +1,60 @@
1
+ import { RegistryEntry, RegistryIndex } from '../registryIndex.js';
2
+ import { RegistryConfigEntry } from './registriesConfig.js';
3
+ export declare const CACHE_TTL_MS: number;
4
+ export declare const STALE_RETRY_BACKOFF_MS: number;
5
+ /** Per-registry fetch outcome. `ok: false` is reported per-registry — the
6
+ * merged Discover response still succeeds when at least one registry is
7
+ * reachable; failed registries just contribute zero entries. */
8
+ export type FetchIndexResult = {
9
+ ok: true;
10
+ index: RegistryIndex;
11
+ stale: boolean;
12
+ } | {
13
+ ok: false;
14
+ status: number;
15
+ error: string;
16
+ };
17
+ /** Resolved descriptor for one registry the host should fetch — name + URLs.
18
+ * `official` is always synthesized; further entries come from
19
+ * `config/collections-registries.json`. Currently structurally identical to
20
+ * `RegistryConfigEntry`; aliased so we can add server-only fields (e.g.
21
+ * auth headers) without touching the on-disk config schema. */
22
+ export type RegistryDescriptor = RegistryConfigEntry;
23
+ /** The full ordered registry list: official first, then user-configured ones.
24
+ * Re-reads the config file on every call so a Discover refresh picks up edits
25
+ * without a server restart (the config is small + read-rarely). */
26
+ export declare function listRegistries(): RegistryDescriptor[];
27
+ /** Look up one registry descriptor by name. Used by the preview / import path,
28
+ * which has the registry label from the entry and needs the rawBase. */
29
+ export declare function findRegistry(name: string): RegistryDescriptor | null;
30
+ export type IndexLoader = (descriptor: RegistryDescriptor) => Promise<FetchIndexResult>;
31
+ /** Fetch one registry's index. Same cache + stale-on-failure semantics as the
32
+ * original single-registry implementation — just keyed by descriptor identity
33
+ * (name + both URLs) so multiple registries don't fight over one slot AND a
34
+ * reconfigured registry doesn't serve a stale index from the prior URL. */
35
+ export declare function fetchRegistryIndex(descriptor: RegistryDescriptor, opts?: {
36
+ force?: boolean;
37
+ nowMs?: number;
38
+ loader?: IndexLoader;
39
+ }): Promise<FetchIndexResult>;
40
+ /** One registry's contribution to the merged Discover view. `failed` registries
41
+ * surface in the response so the UI can show a per-registry error badge while
42
+ * still rendering the entries from the registries that did work. */
43
+ export interface MergedRegistryResult {
44
+ name: string;
45
+ status: "ok" | "stale" | "failed";
46
+ generatedAt: string | null;
47
+ error: string | null;
48
+ entries: RegistryEntry[];
49
+ }
50
+ /** Fetch every configured registry in parallel and return per-registry
51
+ * outcomes. Callers (the Discover route) concatenate `entries` from each.
52
+ * Failure of any single registry doesn't abort the others — that's the point
53
+ * of supporting multiple registries. */
54
+ export declare function fetchAllRegistries(opts?: {
55
+ force?: boolean;
56
+ nowMs?: number;
57
+ loader?: IndexLoader;
58
+ }): Promise<MergedRegistryResult[]>;
59
+ /** Test seam: reset the module cache + failure backoff state (all registries). */
60
+ export declare function resetRegistryCache(): void;
@@ -0,0 +1,51 @@
1
+ import { RegistryEntry } from '../registryIndex.js';
2
+ /** Compose the raw URL for `<dirPath>/<relFile>` under a given registry's
3
+ * rawBase. Empty and traversal (`.`/`..`) segments are dropped so the URL can
4
+ * never escape the base, even if an upstream check is bypassed (the index
5
+ * parser already rejects such identifiers — this is defense-in-depth). The
6
+ * rawBase is trailing-slash-normalized: `parseRegistriesConfig` already trims
7
+ * user-config trailing slashes, but the official descriptor and any test
8
+ * bypass parse — repeating the trim here keeps the join `${base}/${path}`
9
+ * from producing `//` even when the caller bypassed config validation
10
+ * (CodeRabbit review on #1837). */
11
+ export declare function collectionFileUrl(rawBase: string, dirPath: string, relFile: string): string;
12
+ export type FileResult = {
13
+ ok: true;
14
+ text: string;
15
+ } | {
16
+ ok: false;
17
+ status: number;
18
+ error: string;
19
+ };
20
+ /** Fetch one file out of a registry collection. `rawBase` comes from the
21
+ * entry's source registry (`findRegistry(entry.registryName).rawBaseUrl`),
22
+ * not a module-level setting — that's what makes additional user-configured
23
+ * registries reachable. */
24
+ export declare function fetchCollectionFile(rawBase: string, dirPath: string, relFile: string): Promise<FileResult>;
25
+ export type JsonObjectResult = {
26
+ ok: true;
27
+ value: Record<string, unknown>;
28
+ } | {
29
+ ok: false;
30
+ error: string;
31
+ };
32
+ export declare function parseJsonObject(text: string, label: string): JsonObjectResult;
33
+ /** Resolve an entry's rawBase from its `registryName`. A missing match (the
34
+ * user removed the registry from config while a cached index still references
35
+ * it) returns null — the caller surfaces it as a 404 rather than crashing. */
36
+ export declare function rawBaseForEntry(entry: Pick<RegistryEntry, "registryName">): string | null;
37
+ export type PreviewResult = {
38
+ ok: true;
39
+ entry: RegistryEntry;
40
+ schema: Record<string, unknown>;
41
+ meta: Record<string, unknown>;
42
+ } | {
43
+ ok: false;
44
+ status: number;
45
+ error: string;
46
+ };
47
+ /** Preview a registry collection: confirm it's in some registry's published
48
+ * index, then fetch + parse its schema.json + meta.json so the Discover tab
49
+ * can show fields/views before import. With multi-registry support the
50
+ * `registry` arg disambiguates same-name collections from different sources. */
51
+ export declare function previewCollection(author: string, slug: string, registry?: string | null): Promise<PreviewResult>;
@@ -0,0 +1,29 @@
1
+ export declare const EXPORT_BASE = "data/registry-export";
2
+ export interface ExportMeta {
3
+ author: string;
4
+ slug: string;
5
+ version: string;
6
+ title: string;
7
+ description: string;
8
+ tags: string[];
9
+ license: string;
10
+ }
11
+ export type ExportResult = {
12
+ ok: true;
13
+ outputPath: string;
14
+ fileCount: number;
15
+ seedCount: number;
16
+ seedSkipped: number;
17
+ warnings: string[];
18
+ } | {
19
+ ok: false;
20
+ status: number;
21
+ error: string;
22
+ };
23
+ export declare function writeCollectionExport(params: {
24
+ workspaceRoot: string;
25
+ skillDir: string;
26
+ dataDir: string;
27
+ meta: ExportMeta;
28
+ includeSeed: boolean;
29
+ }): Promise<ExportResult>;
@@ -0,0 +1,8 @@
1
+ export declare const DEFAULT_FETCH_TIMEOUT_MS: number;
2
+ export type FetchWithTimeoutInit = Parameters<typeof fetch>[1] & {
3
+ timeoutMs?: number;
4
+ };
5
+ /** `fetch` with a finite timeout. Rejects with a `TimeoutError` once `timeoutMs`
6
+ * elapses. Composes with a caller-supplied `signal` so external cancellation
7
+ * still works. */
8
+ export declare function fetchWithTimeout(url: string | URL, init?: FetchWithTimeoutInit): Promise<Response>;
@@ -0,0 +1,35 @@
1
+ import { RegistryEntry } from '../registryIndex.js';
2
+ /** A manifest entry must be a relative path that stays inside the collection dir:
3
+ * no absolute paths, no backslashes, no empty / `.` / `..` segments. */
4
+ export declare function isSafeBundlePath(rel: unknown): rel is string;
5
+ export type ManifestResult = {
6
+ ok: true;
7
+ files: string[];
8
+ } | {
9
+ ok: false;
10
+ error: string;
11
+ };
12
+ export declare function parseManifest(value: unknown): ManifestResult;
13
+ /** `data/collections/<localSlug>/items` — the host owns dataPath, never the
14
+ * registry's authored value, so imported collections can't collide on disk. */
15
+ export declare function normalizedDataPath(localSlug: string): string;
16
+ export declare function withNormalizedDataPath(schema: Record<string, unknown>, localSlug: string): Record<string, unknown>;
17
+ export type ManifestFetch = {
18
+ ok: true;
19
+ files: string[];
20
+ } | {
21
+ ok: false;
22
+ status: number;
23
+ error: string;
24
+ };
25
+ export declare function fetchManifest(entry: RegistryEntry): Promise<ManifestFetch>;
26
+ export type BundleFetch = {
27
+ ok: true;
28
+ files: Map<string, string>;
29
+ } | {
30
+ ok: false;
31
+ status: number;
32
+ error: string;
33
+ };
34
+ /** Fetch every manifest file. Paths are already safety-checked by parseManifest. */
35
+ export declare function fetchBundle(entry: RegistryEntry, fileList: readonly string[]): Promise<BundleFetch>;
@@ -0,0 +1,30 @@
1
+ import { claudeSkillDir, dataSkillDir } from '../../../skill-bridge/index.js';
2
+ import { RegistryEntry } from '../registryIndex.js';
3
+ export interface ImportOrigin {
4
+ registry: string;
5
+ author: string;
6
+ slug: string;
7
+ version: string;
8
+ contentSha: string;
9
+ importedAt: string;
10
+ }
11
+ export type ImportResult = {
12
+ ok: true;
13
+ localSlug: string;
14
+ updated: boolean;
15
+ seedWritten: number;
16
+ seedSkipped: boolean;
17
+ } | {
18
+ ok: false;
19
+ status: number;
20
+ error: string;
21
+ };
22
+ export declare function writeImportedCollection(params: {
23
+ registry: string;
24
+ entry: RegistryEntry;
25
+ bundle: Map<string, string>;
26
+ workspaceRoot: string;
27
+ nowIso: string;
28
+ }): Promise<ImportResult>;
29
+ export declare function performImport(author: string, slug: string, workspaceRoot: string, registry?: string | null): Promise<ImportResult>;
30
+ export { claudeSkillDir, dataSkillDir };