@mulmoclaude/core 3.12.0 → 3.14.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.
@@ -5,7 +5,7 @@ const require_root = require("../../../root-rPH6FGDT.cjs");
5
5
  const require_relPath = require("../../../relPath-CTAjGdCL.cjs");
6
6
  const require_utils_fetch = require("../../../utils/fetch.cjs");
7
7
  const require_discovery = require("../../../discovery-BsXiDZBR.cjs");
8
- const require_server = require("../../../server-BIKy55wo.cjs");
8
+ const require_server = require("../../../server-DknYbXBo.cjs");
9
9
  const require_templatePath = require("../../../templatePath-27vUZowm.cjs");
10
10
  const require_skill_bridge_index = require("../../../skill-bridge/index.cjs");
11
11
  const require_types = require("../../../types-CNqkLT4M.cjs");
@@ -3,7 +3,7 @@ import { n as writeFileAtomic } from "../../../root-BMroU_mB.js";
3
3
  import { n as toPosixRelPath } from "../../../relPath-DW8MC8VO.js";
4
4
  import { fetchWithTimeout } from "../../../utils/fetch.js";
5
5
  import { $ as collectionsRegistriesConfigPath, G as safeRecordId, ct as projectSkillsDir, mt as skillsStagingDir, nt as getWorkspaceRoot, ot as log, r as loadCollection, s as CollectionSchemaZ, t as acceptParsedSchema } from "../../../discovery-B9zdNkgW.js";
6
- import { g as ONE_SECOND_MS } from "../../../server-DkT40KgR.js";
6
+ import { g as ONE_SECOND_MS } from "../../../server-CQSF5fHe.js";
7
7
  import { t as isSafeActionTemplatePath } from "../../../templatePath-k_WNbL_Q.js";
8
8
  import { claudeSkillDir, dataSkillDir, mirrorSkillWrite } from "../../../skill-bridge/index.js";
9
9
  import { n as parseRegistryIndex, r as isRecord, t as OFFICIAL_REGISTRY_NAME } from "../../../types-BKVZrtyc.js";
@@ -0,0 +1,97 @@
1
+ import { AuthoredApp } from './publishManifest';
2
+ /** The audiences a view may be written for. A CLOSED set: each one names a
3
+ * tier with a rule behind it, so an unknown value has nowhere to be
4
+ * published to and is refused before it gets there. */
5
+ export declare const VIEW_AUDIENCES: readonly ["public", "member", "participant"];
6
+ export type ViewAudience = (typeof VIEW_AUDIENCES)[number];
7
+ /** Where each audience's documents live under `apps/{aid}`. `public` is not
8
+ * here: it keeps `config/public` + `config/view`, which are already published
9
+ * and already read by a deployed runtime. */
10
+ export declare const VIEW_TIER: Readonly<Record<Exclude<ViewAudience, "public">, "member" | "roster">>;
11
+ /** The id `public.view` normalizes to. Fixed rather than derived, so two
12
+ * implementations of the same normalization cannot pick different ones. */
13
+ export declare const PUBLIC_VIEW_ID = "public";
14
+ /** `config` is the projection's own document in every tier (`live:config`),
15
+ * so a view may not be called that — the two would be the same document. */
16
+ export declare const RESERVED_VIEW_IDS: readonly string[];
17
+ /** What an id may be.
18
+ *
19
+ * Narrow on purpose: this value is written by the author, and it becomes a
20
+ * Firestore document id under a `live:` / `staged:` prefix. Excluding `:`
21
+ * keeps the prefix and the id from running together; excluding `/`, `.` and
22
+ * `__…__` keeps it a legal document id that addresses the path it says. */
23
+ export declare const VIEW_ID_PATTERN: RegExp;
24
+ /** A view as the author wrote it, once normalized: one shape, whichever of
25
+ * the two declarations it came from. `where` is the path it was written at,
26
+ * carried only so a refusal names the key the author can go and edit. */
27
+ export interface NormalizedView {
28
+ id: string;
29
+ audience: ViewAudience;
30
+ path: string;
31
+ collections: string[];
32
+ where: string;
33
+ }
34
+ export type NormalizedViewsResult = {
35
+ ok: true;
36
+ views: NormalizedView[];
37
+ } | {
38
+ ok: false;
39
+ problems: string[];
40
+ };
41
+ /** The one shape everything downstream reads.
42
+ *
43
+ * Every caller — the publish gate, the projection, the host that writes the
44
+ * documents — goes through this, so "which declaration was used" is decided
45
+ * exactly once. */
46
+ export declare function normalizeViews(app: AuthoredApp): NormalizedViewsResult;
47
+ /** How one audience reaches one collection's records.
48
+ *
49
+ * The parent page builds the query from this; the view never touches
50
+ * Firestore. `own` is not a filter the rules apply for the reader — an
51
+ * unscoped `list` on an own-row collection is DENIED, not narrowed — so the
52
+ * scope has to travel with the declaration or the page fails. */
53
+ export interface ProjectedViewCollection {
54
+ cid: string;
55
+ scope: "all" | "own";
56
+ /** `scope: "own"` — the field carrying the reader's verified address. */
57
+ emailField?: string;
58
+ /** `scope: "own"` — the row is the document whose id is the reader's uid. */
59
+ ownDocId?: "auth.uid";
60
+ }
61
+ /** How a participant reaches `cid`, or null if they cannot.
62
+ *
63
+ * Mirrors the rules' read branches for someone holding no role:
64
+ * `partRead` (the whole collection) and `ownRow` (their own record, found
65
+ * by the submit declaration's `emailField` or by a uid-derived id).
66
+ *
67
+ * `participantRead` is a PARAMETER rather than read off the manifest, and
68
+ * that is the whole point of the signature. Publish does not promote the
69
+ * manifest's value: `projectPublish` overwrites `participantRead` with what
70
+ * the STAGED schemas carry, so a cid added since the last deploy is in the
71
+ * manifest and not in the rules. Deriving the scope from the manifest would
72
+ * publish `scope: "all"` for a collection the promoted rules then deny —
73
+ * and removing one gives the mirror-image false refusal. The caller passes
74
+ * the set that will actually be in force. */
75
+ export declare function participantScope(app: AuthoredApp, cid: string, participantRead: readonly string[]): ProjectedViewCollection | null;
76
+ /** The declaration as one non-public audience may see it — the document
77
+ * published at `apps/{aid}/{tier}/live:config`, and deployed at
78
+ * `staged:config`.
79
+ *
80
+ * The roster is NOT here, and neither is anything about another member: this
81
+ * is read by everyone the tier admits, which for `roster` includes every
82
+ * participant. */
83
+ export interface AppViewConfigDoc extends Record<string, unknown> {
84
+ name?: string;
85
+ views: {
86
+ id: string;
87
+ collections: ProjectedViewCollection[];
88
+ }[];
89
+ /** The submit declarations for the collections these views draw, so the page
90
+ * can show what may be sent rather than discovering it from a denial. */
91
+ submit: Record<string, Record<string, unknown>>;
92
+ publishedAt: number;
93
+ }
94
+ /** The document ids one tier uses. `live:` and `staged:` are the only two
95
+ * prefixes, so a single `match` covers the projection and every view. */
96
+ export declare const viewDocId: (stage: "live" | "staged", viewId: string) => string;
97
+ export declare const VIEW_CONFIG_ID = "config";
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_root = require("../../root-rPH6FGDT.cjs");
3
3
  const require_itemId = require("../../itemId-Dzrr3vs5.cjs");
4
4
  const require_discovery = require("../../discovery-BsXiDZBR.cjs");
5
- const require_server = require("../../server-BIKy55wo.cjs");
5
+ const require_server = require("../../server-DknYbXBo.cjs");
6
6
  const require_templatePath = require("../../templatePath-27vUZowm.cjs");
7
7
  exports.APPS_COLLECTION = require_server.APPS_COLLECTION;
8
8
  exports.APP_MANIFEST_FILE = require_discovery.APP_MANIFEST_FILE;
@@ -21,8 +21,14 @@ exports.MAX_RECORD_ISSUES = require_server.MAX_RECORD_ISSUES;
21
21
  exports.MAX_SCHEMA_ISSUES = require_server.MAX_SCHEMA_ISSUES;
22
22
  exports.MAX_UNSELECTIVE_ITEMS = require_server.MAX_UNSELECTIVE_ITEMS;
23
23
  exports.PUBLIC_CONFIG_DOC = require_server.PUBLIC_CONFIG_DOC;
24
+ exports.PUBLIC_VIEW_ID = require_server.PUBLIC_VIEW_ID;
25
+ exports.RESERVED_VIEW_IDS = require_server.RESERVED_VIEW_IDS;
24
26
  exports.SCHEMA_FILE = require_discovery.SCHEMA_FILE;
25
27
  exports.STORE_UNREADABLE = require_server.STORE_UNREADABLE;
28
+ exports.VIEW_AUDIENCES = require_server.VIEW_AUDIENCES;
29
+ exports.VIEW_CONFIG_ID = require_server.VIEW_CONFIG_ID;
30
+ exports.VIEW_ID_PATTERN = require_server.VIEW_ID_PATTERN;
31
+ exports.VIEW_TIER = require_server.VIEW_TIER;
26
32
  exports.acceptParsedSchema = require_discovery.acceptParsedSchema;
27
33
  exports.advanceTriggerDate = require_server.advanceTriggerDate;
28
34
  exports.appConfigPath = require_server.appConfigPath;
@@ -30,6 +36,7 @@ exports.appManifestReason = require_discovery.appManifestReason;
30
36
  exports.appSchemasPath = require_server.appSchemasPath;
31
37
  exports.appSlugDoc = require_server.appSlugDoc;
32
38
  exports.appStagingPath = require_server.appStagingPath;
39
+ exports.appViewTierPath = require_server.appViewTierPath;
33
40
  exports.applyMutateAction = require_server.applyMutateAction;
34
41
  exports.bindsSubmitterIdentity = require_server.bindsSubmitterIdentity;
35
42
  exports.buildActionSeedPrompt = require_server.buildActionSeedPrompt;
@@ -79,12 +86,15 @@ exports.log = require_discovery.log;
79
86
  exports.makeManageCollectionTool = require_server.makeManageCollectionTool;
80
87
  exports.maybeSpawnSuccessor = require_server.maybeSpawnSuccessor;
81
88
  exports.normalizeCsvValue = require_discovery.normalizeCsvValue;
89
+ exports.normalizeViews = require_server.normalizeViews;
82
90
  exports.pageFromFullRead = require_discovery.pageFromFullRead;
83
91
  exports.parseAppManifest = require_discovery.parseAppManifest;
84
92
  exports.parseAuthoredApp = require_server.parseAuthoredApp;
85
93
  exports.parseCivil = require_server.parseCivil;
94
+ exports.participantScope = require_server.participantScope;
86
95
  exports.peekWorkspaceRoot = require_discovery.peekWorkspaceRoot;
87
96
  exports.projectApp = require_server.projectApp;
97
+ exports.projectAppViews = require_server.projectAppViews;
88
98
  exports.projectDeploy = require_server.projectDeploy;
89
99
  exports.projectItemFields = require_discovery.projectItemFields;
90
100
  exports.projectPublish = require_server.projectPublish;
@@ -121,4 +131,6 @@ exports.toDetail = require_discovery.toDetail;
121
131
  exports.toSummary = require_discovery.toSummary;
122
132
  exports.validateCollectionRecords = require_server.validateCollectionRecords;
123
133
  exports.validateRecordObject = require_server.validateRecordObject;
134
+ exports.viewConfigDocId = require_server.viewConfigDocId;
135
+ exports.viewDocId = require_server.viewDocId;
124
136
  exports.writeItem = require_discovery.writeItem;
@@ -3,8 +3,9 @@ export type { FirestoreDoc, FirestoreDocs } from './firestoreDocs';
3
3
  export { sharedItemsPath } from './firestoreStore';
4
4
  export { loadAppManifest, parseAppManifest, appManifestReason, APP_MANIFEST_FILE, type AppManifest, type AppManifestResult } from './appManifest';
5
5
  export { AuthoredAppZ, parseAuthoredApp, APP_ROLES, type AuthoredApp, type AuthoredCollectionConfig, type AuthoredMail, type AuthoredSubmit, } from './publishManifest';
6
- export { projectApp, projectDeploy, projectPublish, stagedRuleConfig, promoteSchema, appStagingPath, APP_SLUGS_COLLECTION, appSlugDoc, type AppSlugDoc, type DeployedApp, type PublishedFace, APPS_COLLECTION, PUBLIC_CONFIG_DOC, appConfigPath, appSchemasPath, type PublishStamp, type PublishedApp, type PublishedConfigDoc, type PublishedSchemaDoc, type StagedSchemaDoc, } from './publishProject';
6
+ export { projectApp, projectAppViews, appViewTierPath, viewConfigDocId, type AppViewTier, projectDeploy, projectPublish, stagedRuleConfig, promoteSchema, appStagingPath, APP_SLUGS_COLLECTION, appSlugDoc, type AppSlugDoc, type DeployedApp, type PublishedFace, APPS_COLLECTION, PUBLIC_CONFIG_DOC, appConfigPath, appSchemasPath, type PublishStamp, type PublishedApp, type PublishedConfigDoc, type PublishedSchemaDoc, type StagedSchemaDoc, } from './publishProject';
7
7
  export { publishProblems, promotedRoleProblems, bindsSubmitterIdentity, type PublishableCollection } from './publishChecks';
8
+ export { normalizeViews, participantScope, viewDocId, PUBLIC_VIEW_ID, RESERVED_VIEW_IDS, VIEW_AUDIENCES, VIEW_CONFIG_ID, VIEW_ID_PATTERN, VIEW_TIER, type AppViewConfigDoc, type NormalizedView, type NormalizedViewsResult, type ProjectedViewCollection, type ViewAudience, } from './appViews';
8
9
  export type { LoadedCollection } from './discoveredCollection';
9
10
  export * from './paths';
10
11
  export * from './templatePath';
@@ -1,6 +1,6 @@
1
1
  import { t as canonicalRoot } from "../../root-BMroU_mB.js";
2
2
  import { N as COMPUTED_TYPES } from "../../itemId-DfTm08jm.js";
3
3
  import { A as readItem, B as SCHEMA_FILE, C as CollectionQueryZ, D as generateItemId, E as deleteItem, F as loadAppManifest, G as safeRecordId, H as itemFilePath, I as parseAppManifest, J as isBackendUnavailable, K as safeSlugName, L as sharedItemsPath, M as writeItem, N as APP_MANIFEST_FILE, O as isRegularFile, P as appManifestReason, Q as collectionChangePayload, R as pageFromFullRead, S as compileJsonlQuery, T as MAX_QUERY_ROWS, U as resolveDataDir, V as isContainedInRoot, W as resolveTemplatePath, Y as COLLECTION_ROOT_REQUIRED, Z as collectionChangeKey, _ as dedupeByRecordId, a as toDetail, at as localCollectionKey, d as storeFor, dt as setFirestoreAccessor, et as configureCollectionHost, ft as setSharedCollectionsSupport, g as decodeCsvRecordId, h as csvRowToItem, i as resolvePrimaryField, j as resolveCreateItemId, k as listItems, l as collectionWritable, lt as publishCollectionChange, n as discoverCollections, nt as getWorkspaceRoot, o as toSummary, ot as log, p as MAX_CSV_ROWS, pt as sharedCollectionChangePayload, q as BackendUnavailableError, r as loadCollection, rt as hostSupportsSharedCollections, s as CollectionSchemaZ, st as peekWorkspaceRoot, t as acceptParsedSchema, tt as firestoreHandle, u as readOnlyRefusal, ut as setCollectionChangePublisher, v as encodeCsvRecordId, w as DEFAULT_QUERY_ROWS, x as compileCsvQuery, y as normalizeCsvValue, z as projectItemFields } from "../../discovery-B9zdNkgW.js";
4
- import { $ as AuthoredAppZ, A as runQueryOverRows, B as APPS_COLLECTION, C as STORE_UNREADABLE, D as recordFieldProblem, E as compileRecordZ, F as readCustomViewI18n, G as appSlugDoc, H as PUBLIC_CONFIG_DOC, I as readSkillTemplate, J as projectDeploy, K as appStagingPath, L as bindsSubmitterIdentity, M as buildCollectionActionSeedPrompt, N as promptPathsFor, O as runCollectionQuery, P as readCustomViewHtml, Q as APP_ROLES, R as promotedRoleProblems, S as MAX_RECORD_ISSUES, T as validateRecordObject, U as appConfigPath, V as APP_SLUGS_COLLECTION, W as appSchemasPath, X as promoteSchema, Y as projectPublish, Z as stagedRuleConfig, _ as computeCollectionIcon, a as deleteCollection, b as applyMutateAction, c as computeSuccessor, d as isTriggerDue, et as parseAuthoredApp, f as maybeSpawnSuccessor, h as successorId, i as deleteCustomView, j as buildActionSeedPrompt, k as enrichItems, l as daysInMonth, m as resolveEvery, n as MAX_UNSELECTIVE_ITEMS, o as deleteCollectionRefusalMessage, p as parseCivil, q as projectApp, r as makeManageCollectionTool, s as advanceTriggerDate, t as MAX_SCHEMA_ISSUES, u as formatCivil, v as buildWorkspaceOntology, w as validateCollectionRecords, x as firstMutateParamProblem, y as schemaRelations, z as publishProblems } from "../../server-DkT40KgR.js";
4
+ import { $ as stagedRuleConfig, A as runQueryOverRows, B as APPS_COLLECTION, C as STORE_UNREADABLE, D as recordFieldProblem, E as compileRecordZ, F as readCustomViewI18n, G as appSlugDoc, H as PUBLIC_CONFIG_DOC, I as readSkillTemplate, J as projectApp, K as appStagingPath, L as bindsSubmitterIdentity, M as buildCollectionActionSeedPrompt, N as promptPathsFor, O as runCollectionQuery, P as readCustomViewHtml, Q as promoteSchema, R as promotedRoleProblems, S as MAX_RECORD_ISSUES, T as validateRecordObject, U as appConfigPath, V as APP_SLUGS_COLLECTION, W as appSchemasPath, X as projectDeploy, Y as projectAppViews, Z as projectPublish, _ as computeCollectionIcon, a as deleteCollection, at as RESERVED_VIEW_IDS, b as applyMutateAction, c as computeSuccessor, ct as VIEW_ID_PATTERN, d as isTriggerDue, dt as participantScope, et as viewConfigDocId, f as maybeSpawnSuccessor, ft as viewDocId, h as successorId, i as deleteCustomView, it as PUBLIC_VIEW_ID, j as buildActionSeedPrompt, k as enrichItems, l as daysInMonth, lt as VIEW_TIER, m as resolveEvery, n as MAX_UNSELECTIVE_ITEMS, nt as AuthoredAppZ, o as deleteCollectionRefusalMessage, ot as VIEW_AUDIENCES, p as parseCivil, q as appViewTierPath, r as makeManageCollectionTool, rt as parseAuthoredApp, s as advanceTriggerDate, st as VIEW_CONFIG_ID, t as MAX_SCHEMA_ISSUES, tt as APP_ROLES, u as formatCivil, ut as normalizeViews, v as buildWorkspaceOntology, w as validateCollectionRecords, x as firstMutateParamProblem, y as schemaRelations, z as publishProblems } from "../../server-CQSF5fHe.js";
5
5
  import { i as isSafeTemplatePath, n as isSafeCustomViewI18nPath, r as isSafeCustomViewPath, t as isSafeActionTemplatePath } from "../../templatePath-k_WNbL_Q.js";
6
- export { APPS_COLLECTION, APP_MANIFEST_FILE, APP_ROLES, APP_SLUGS_COLLECTION, AuthoredAppZ, BackendUnavailableError, COLLECTION_ROOT_REQUIRED, COMPUTED_TYPES, CollectionQueryZ, CollectionSchemaZ, DEFAULT_QUERY_ROWS, MAX_CSV_ROWS, MAX_QUERY_ROWS, MAX_RECORD_ISSUES, MAX_SCHEMA_ISSUES, MAX_UNSELECTIVE_ITEMS, PUBLIC_CONFIG_DOC, SCHEMA_FILE, STORE_UNREADABLE, acceptParsedSchema, advanceTriggerDate, appConfigPath, appManifestReason, appSchemasPath, appSlugDoc, appStagingPath, applyMutateAction, bindsSubmitterIdentity, buildActionSeedPrompt, buildCollectionActionSeedPrompt, buildWorkspaceOntology, canonicalRoot, collectionChangeKey, collectionChangePayload, collectionWritable, compileCsvQuery, compileJsonlQuery, compileRecordZ, computeCollectionIcon, computeSuccessor, configureCollectionHost, csvRowToItem, daysInMonth, decodeCsvRecordId, dedupeByRecordId, deleteCollection, deleteCollectionRefusalMessage, deleteCustomView, deleteItem, discoverCollections, encodeCsvRecordId, enrichItems, firestoreHandle, firstMutateParamProblem, formatCivil, generateItemId, getWorkspaceRoot, hostSupportsSharedCollections, isBackendUnavailable, isContainedInRoot, isRegularFile, isSafeActionTemplatePath, isSafeCustomViewI18nPath, isSafeCustomViewPath, isSafeTemplatePath, isTriggerDue, itemFilePath, listItems, loadAppManifest, loadCollection, localCollectionKey, log, makeManageCollectionTool, maybeSpawnSuccessor, normalizeCsvValue, pageFromFullRead, parseAppManifest, parseAuthoredApp, parseCivil, peekWorkspaceRoot, projectApp, projectDeploy, projectItemFields, projectPublish, promoteSchema, promotedRoleProblems, promptPathsFor, publishCollectionChange, publishProblems, readCustomViewHtml, readCustomViewI18n, readItem, readOnlyRefusal, readSkillTemplate, recordFieldProblem, resolveCreateItemId, resolveDataDir, resolveEvery, resolvePrimaryField, resolveTemplatePath, runCollectionQuery, runQueryOverRows, safeRecordId, safeSlugName, schemaRelations, setCollectionChangePublisher, setFirestoreAccessor, setSharedCollectionsSupport, sharedCollectionChangePayload, sharedItemsPath, stagedRuleConfig, storeFor, successorId, toDetail, toSummary, validateCollectionRecords, validateRecordObject, writeItem };
6
+ export { APPS_COLLECTION, APP_MANIFEST_FILE, APP_ROLES, APP_SLUGS_COLLECTION, AuthoredAppZ, BackendUnavailableError, COLLECTION_ROOT_REQUIRED, COMPUTED_TYPES, CollectionQueryZ, CollectionSchemaZ, DEFAULT_QUERY_ROWS, MAX_CSV_ROWS, MAX_QUERY_ROWS, MAX_RECORD_ISSUES, MAX_SCHEMA_ISSUES, MAX_UNSELECTIVE_ITEMS, PUBLIC_CONFIG_DOC, PUBLIC_VIEW_ID, RESERVED_VIEW_IDS, SCHEMA_FILE, STORE_UNREADABLE, VIEW_AUDIENCES, VIEW_CONFIG_ID, VIEW_ID_PATTERN, VIEW_TIER, acceptParsedSchema, advanceTriggerDate, appConfigPath, appManifestReason, appSchemasPath, appSlugDoc, appStagingPath, appViewTierPath, applyMutateAction, bindsSubmitterIdentity, buildActionSeedPrompt, buildCollectionActionSeedPrompt, buildWorkspaceOntology, canonicalRoot, collectionChangeKey, collectionChangePayload, collectionWritable, compileCsvQuery, compileJsonlQuery, compileRecordZ, computeCollectionIcon, computeSuccessor, configureCollectionHost, csvRowToItem, daysInMonth, decodeCsvRecordId, dedupeByRecordId, deleteCollection, deleteCollectionRefusalMessage, deleteCustomView, deleteItem, discoverCollections, encodeCsvRecordId, enrichItems, firestoreHandle, firstMutateParamProblem, formatCivil, generateItemId, getWorkspaceRoot, hostSupportsSharedCollections, isBackendUnavailable, isContainedInRoot, isRegularFile, isSafeActionTemplatePath, isSafeCustomViewI18nPath, isSafeCustomViewPath, isSafeTemplatePath, isTriggerDue, itemFilePath, listItems, loadAppManifest, loadCollection, localCollectionKey, log, makeManageCollectionTool, maybeSpawnSuccessor, normalizeCsvValue, normalizeViews, pageFromFullRead, parseAppManifest, parseAuthoredApp, parseCivil, participantScope, peekWorkspaceRoot, projectApp, projectAppViews, projectDeploy, projectItemFields, projectPublish, promoteSchema, promotedRoleProblems, promptPathsFor, publishCollectionChange, publishProblems, readCustomViewHtml, readCustomViewI18n, readItem, readOnlyRefusal, readSkillTemplate, recordFieldProblem, resolveCreateItemId, resolveDataDir, resolveEvery, resolvePrimaryField, resolveTemplatePath, runCollectionQuery, runQueryOverRows, safeRecordId, safeSlugName, schemaRelations, setCollectionChangePublisher, setFirestoreAccessor, setSharedCollectionsSupport, sharedCollectionChangePayload, sharedItemsPath, stagedRuleConfig, storeFor, successorId, toDetail, toSummary, validateCollectionRecords, validateRecordObject, viewConfigDocId, viewDocId, writeItem };
@@ -36,6 +36,7 @@ declare const CollectionConfigZ: z.ZodObject<{
36
36
  immutable: z.ZodOptional<z.ZodBoolean>;
37
37
  submitOnly: z.ZodOptional<z.ZodBoolean>;
38
38
  assigneeField: z.ZodOptional<z.ZodString>;
39
+ mirrorOf: z.ZodOptional<z.ZodString>;
39
40
  peerVisibility: z.ZodOptional<z.ZodEnum<{
40
41
  public: "public";
41
42
  hidden: "hidden";
@@ -65,11 +66,20 @@ declare const SubmitZ: z.ZodObject<{
65
66
  createFields: z.ZodArray<z.ZodString>;
66
67
  initialStatus: z.ZodOptional<z.ZodString>;
67
68
  idFrom: z.ZodOptional<z.ZodEnum<{
69
+ field: "field";
68
70
  auto: "auto";
69
71
  "auth.uid": "auth.uid";
70
72
  "auth.uid+field": "auth.uid+field";
71
73
  }>>;
72
74
  idField: z.ZodOptional<z.ZodString>;
75
+ idIn: z.ZodOptional<z.ZodObject<{
76
+ collection: z.ZodString;
77
+ where: z.ZodOptional<z.ZodObject<{
78
+ field: z.ZodString;
79
+ equals: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
80
+ }, z.core.$strict>>;
81
+ }, z.core.$strict>>;
82
+ mirror: z.ZodOptional<z.ZodString>;
73
83
  validate: z.ZodOptional<z.ZodObject<{
74
84
  required: z.ZodOptional<z.ZodArray<z.ZodString>>;
75
85
  keyFields: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -85,6 +95,11 @@ declare const SubmitZ: z.ZodObject<{
85
95
  collection: z.ZodString;
86
96
  field: z.ZodString;
87
97
  }, z.core.$strict>>;
98
+ untilField: z.ZodOptional<z.ZodObject<{
99
+ ref: z.ZodString;
100
+ collection: z.ZodString;
101
+ field: z.ZodString;
102
+ }, z.core.$strict>>;
88
103
  }, z.core.$strict>>;
89
104
  stampField: z.ZodOptional<z.ZodString>;
90
105
  selfUpdate: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
@@ -111,10 +126,10 @@ export declare const AuthoredAppZ: z.ZodObject<{
111
126
  aidEnv: z.ZodOptional<z.ZodString>;
112
127
  owner: z.ZodOptional<z.ZodString>;
113
128
  members: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodUnion<readonly [z.ZodLiteral<"*">, z.ZodString]>, z.ZodEnum<{
129
+ participant: "participant";
114
130
  owner: "owner";
115
131
  editor: "editor";
116
132
  viewer: "viewer";
117
- participant: "participant";
118
133
  assignee: "assignee";
119
134
  }>>>;
120
135
  collections: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -123,6 +138,7 @@ export declare const AuthoredAppZ: z.ZodObject<{
123
138
  immutable: z.ZodOptional<z.ZodBoolean>;
124
139
  submitOnly: z.ZodOptional<z.ZodBoolean>;
125
140
  assigneeField: z.ZodOptional<z.ZodString>;
141
+ mirrorOf: z.ZodOptional<z.ZodString>;
126
142
  peerVisibility: z.ZodOptional<z.ZodEnum<{
127
143
  public: "public";
128
144
  hidden: "hidden";
@@ -146,6 +162,10 @@ export declare const AuthoredAppZ: z.ZodObject<{
146
162
  public: z.ZodOptional<z.ZodObject<{
147
163
  enabled: z.ZodOptional<z.ZodBoolean>;
148
164
  read: z.ZodOptional<z.ZodArray<z.ZodString>>;
165
+ view: z.ZodOptional<z.ZodObject<{
166
+ path: z.ZodString;
167
+ collections: z.ZodArray<z.ZodString>;
168
+ }, z.core.$strict>>;
149
169
  submit: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
150
170
  auth: z.ZodEnum<{
151
171
  none: "none";
@@ -156,11 +176,20 @@ export declare const AuthoredAppZ: z.ZodObject<{
156
176
  createFields: z.ZodArray<z.ZodString>;
157
177
  initialStatus: z.ZodOptional<z.ZodString>;
158
178
  idFrom: z.ZodOptional<z.ZodEnum<{
179
+ field: "field";
159
180
  auto: "auto";
160
181
  "auth.uid": "auth.uid";
161
182
  "auth.uid+field": "auth.uid+field";
162
183
  }>>;
163
184
  idField: z.ZodOptional<z.ZodString>;
185
+ idIn: z.ZodOptional<z.ZodObject<{
186
+ collection: z.ZodString;
187
+ where: z.ZodOptional<z.ZodObject<{
188
+ field: z.ZodString;
189
+ equals: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
190
+ }, z.core.$strict>>;
191
+ }, z.core.$strict>>;
192
+ mirror: z.ZodOptional<z.ZodString>;
164
193
  validate: z.ZodOptional<z.ZodObject<{
165
194
  required: z.ZodOptional<z.ZodArray<z.ZodString>>;
166
195
  keyFields: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -176,6 +205,11 @@ export declare const AuthoredAppZ: z.ZodObject<{
176
205
  collection: z.ZodString;
177
206
  field: z.ZodString;
178
207
  }, z.core.$strict>>;
208
+ untilField: z.ZodOptional<z.ZodObject<{
209
+ ref: z.ZodString;
210
+ collection: z.ZodString;
211
+ field: z.ZodString;
212
+ }, z.core.$strict>>;
179
213
  }, z.core.$strict>>;
180
214
  stampField: z.ZodOptional<z.ZodString>;
181
215
  selfUpdate: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
@@ -188,6 +222,16 @@ export declare const AuthoredAppZ: z.ZodObject<{
188
222
  }, z.core.$strict>>;
189
223
  }, z.core.$strict>>>;
190
224
  }, z.core.$strict>>;
225
+ views: z.ZodOptional<z.ZodArray<z.ZodObject<{
226
+ id: z.ZodString;
227
+ audience: z.ZodEnum<{
228
+ public: "public";
229
+ member: "member";
230
+ participant: "participant";
231
+ }>;
232
+ path: z.ZodString;
233
+ collections: z.ZodArray<z.ZodString>;
234
+ }, z.core.$strict>>>;
191
235
  }, z.core.$strict>;
192
236
  export type AuthoredApp = z.infer<typeof AuthoredAppZ>;
193
237
  export type AuthoredCollectionConfig = z.infer<typeof CollectionConfigZ>;
@@ -1,4 +1,5 @@
1
1
  import { CollectionSchema } from '../core/schema';
2
+ import { AppViewConfigDoc, NormalizedView, ViewAudience } from './appViews';
2
3
  import { AuthoredApp, AuthoredCollectionConfig } from './publishManifest';
3
4
  /** Who and when. Threaded in rather than read from a clock inside the
4
5
  * projection so the projection stays pure and the tests can assert on an
@@ -80,6 +81,22 @@ export interface PublishedConfigDoc extends Record<string, unknown> {
80
81
  enabled: boolean;
81
82
  read: string[];
82
83
  submit: Record<string, Record<string, unknown>>;
84
+ /** That the app HAS a published view, and which datasets it asked for.
85
+ *
86
+ * This is the only place the public page can learn it: the rules' app
87
+ * document is reader-only and deliberately carries no view, and the HTML
88
+ * itself lands in a SEPARATE document (`config/view`) because a 1 MiB limit
89
+ * applies per document. Omitted here, the page has the HTML and no idea
90
+ * what to send it — the feature does not work at all.
91
+ *
92
+ * The authored PATH is deliberately not published. It names a file in the
93
+ * author's repository, which the browser cannot use and which nobody should
94
+ * be handed on a world-readable document; what the page needs is the
95
+ * dataset list, and `publishedAt` beside it is what pins this declaration
96
+ * to the HTML published in the same run. */
97
+ view?: {
98
+ collections: string[];
99
+ };
83
100
  publishedAt: number;
84
101
  }
85
102
  /** Everything one publish writes. Separate documents because they live at
@@ -253,3 +270,35 @@ export declare const appSlugDoc: (aid: string, published: boolean) => AppSlugDoc
253
270
  export declare const appStagingPath: (aid: string) => string;
254
271
  /** The public-config documents' parent path. */
255
272
  export declare const appConfigPath: (aid: string) => string;
273
+ /** Where one audience's pages live. `member` is read by anyone holding a role;
274
+ * `roster` by anyone on the roster, participants included. */
275
+ export declare const appViewTierPath: (aid: string, tier: "member" | "roster") => string;
276
+ /** One audience's tier, as publish (or deploy) must write it.
277
+ *
278
+ * Both tiers are returned even when empty, deliberately. An app that WITHDREW
279
+ * its member pages produces an empty tier, and a host that only ever saw the
280
+ * tiers with something in them would leave the previous pages live — the
281
+ * failure `config/view` already had, where a declaration was withdrawn and
282
+ * the world went on reading the page. */
283
+ export interface AppViewTier {
284
+ tier: "member" | "roster";
285
+ audience: Exclude<ViewAudience, "public">;
286
+ /** The projection document, for `{tier}/live:config` or `{tier}/staged:config`.
287
+ * Meaningless when `views` is empty — the host deletes the tier instead. */
288
+ config: AppViewConfigDoc;
289
+ /** The views to publish, in declaration order. The host reads each `path`
290
+ * and writes it to `{tier}/live:{id}`. */
291
+ views: NormalizedView[];
292
+ }
293
+ /** Project the declaration into the per-audience documents.
294
+ *
295
+ * Pure, like `projectApp`: the HTML is not here (the host reads the files),
296
+ * and neither is the clock. What is here is the answer to "what may this
297
+ * audience read, and how" — computed once, so the page never has to guess and
298
+ * never has to discover it from a denial. */
299
+ export declare function projectAppViews(authored: AuthoredApp, stamp: PublishStamp, promoted?: {
300
+ participantRead?: readonly string[];
301
+ }): AppViewTier[];
302
+ /** The document a tier's projection is published at. Beside the views
303
+ * themselves, under one `match` — see `firestore.rules`. */
304
+ export declare const viewConfigDocId: (stage: "live" | "staged") => string;
@@ -4,7 +4,7 @@ const require_itemId = require("../itemId-Dzrr3vs5.cjs");
4
4
  const require_promptSafety = require("../promptSafety-CWqYq-NS.cjs");
5
5
  require("../collection/index.cjs");
6
6
  const require_discovery = require("../discovery-BsXiDZBR.cjs");
7
- const require_server = require("../server-BIKy55wo.cjs");
7
+ const require_server = require("../server-DknYbXBo.cjs");
8
8
  const require_notifier = require("../notifier-DZJj0sOh.cjs");
9
9
  let node_fs_promises = require("node:fs/promises");
10
10
  //#region src/collection-watchers/config.ts
@@ -3,7 +3,7 @@ import { B as fieldText, x as isValidCollectionName } from "../itemId-DfTm08jm.j
3
3
  import { E as whenMatches, f as itemIsDone } from "../promptSafety-CSdyp7RF.js";
4
4
  import "../collection/index.js";
5
5
  import { H as itemFilePath, Q as collectionChangePayload, d as storeFor, lt as publishCollectionChange, n as discoverCollections, pt as sharedCollectionChangePayload, r as loadCollection, st as peekWorkspaceRoot, tt as firestoreHandle } from "../discovery-B9zdNkgW.js";
6
- import { d as isTriggerDue, f as maybeSpawnSuccessor } from "../server-DkT40KgR.js";
6
+ import { d as isTriggerDue, f as maybeSpawnSuccessor } from "../server-CQSF5fHe.js";
7
7
  import { d as publish, m as updateForPlugin, n as clear, s as listAll } from "../notifier-DhnwR82U.js";
8
8
  import { access } from "node:fs/promises";
9
9
  //#region src/collection-watchers/config.ts
@@ -5,7 +5,7 @@ const require_root = require("../../root-rPH6FGDT.cjs");
5
5
  const require_itemId = require("../../itemId-Dzrr3vs5.cjs");
6
6
  const require_project = require("../../project-C1ep9pvo.cjs");
7
7
  const require_discovery = require("../../discovery-BsXiDZBR.cjs");
8
- const require_server = require("../../server-BIKy55wo.cjs");
8
+ const require_server = require("../../server-DknYbXBo.cjs");
9
9
  const require_feeds_paths = require("../paths.cjs");
10
10
  const require_ingestTypes = require("../../ingestTypes-B4XfrUoq.cjs");
11
11
  const require_notifier = require("../../notifier-DZJj0sOh.cjs");
@@ -3,7 +3,7 @@ import { t as canonicalRoot } from "../../root-BMroU_mB.js";
3
3
  import { F as INGEST_KINDS, P as FEED_SCHEDULES } from "../../itemId-DfTm08jm.js";
4
4
  import { t as mergeIntoExisting } from "../../project-B0j_Vf_Q.js";
5
5
  import { K as safeSlugName, U as resolveDataDir, _t as createHostSlot, d as storeFor, gt as createForwardingLogger, k as listItems, n as discoverCollections } from "../../discovery-B9zdNkgW.js";
6
- import { I as readSkillTemplate, M as buildCollectionActionSeedPrompt, N as promptPathsFor } from "../../server-DkT40KgR.js";
6
+ import { I as readSkillTemplate, M as buildCollectionActionSeedPrompt, N as promptPathsFor } from "../../server-CQSF5fHe.js";
7
7
  import { FEEDS_DIR, feedDir, feedStatePath, feedsRoot, ingestStateDir, ingestStatePath } from "../paths.js";
8
8
  import { n as DEFAULT_FEED_MAX_ITEMS, r as isFeedSchedule, t as AGENT_INGEST_KIND } from "../../ingestTypes-B312BwXg.js";
9
9
  import { d as publish, n as clear } from "../../notifier-DhnwR82U.js";