@vibes.diy/prompts 14.0.14 → 14.0.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 (2) hide show
  1. package/llms/backend.md +31 -1
  2. package/package.json +4 -4
package/llms/backend.md CHANGED
@@ -815,6 +815,22 @@ export async function scheduled(event, ctx) {
815
815
  }
816
816
  ```
817
817
 
818
+ The run's own bookkeeping is the server's, not a user's. `scheduled` acts as the
819
+ app owner, so `user.isOwner` is the one condition that separates a run's write
820
+ from a client pretending to be one — and `access.js` is where that is said:
821
+
822
+ ```js
823
+ // access.js
824
+ export default function ({ doc, user }) {
825
+ if (doc.type === "runState" || doc.type === "runStatus") {
826
+ if (!user?.isOwner) throw { forbidden: "the run writes its own state" };
827
+ return { channels: ["show"] };
828
+ }
829
+ // …the app's own document types…
830
+ throw { forbidden: "unknown document type" };
831
+ }
832
+ ```
833
+
818
834
  App.jsx reads the same database, and renders that status beside the drafts, so a
819
835
  failed run and a good one never look alike:
820
836
 
@@ -853,6 +869,20 @@ export async function onChange(event, ctx) {
853
869
  export async function scheduled(event, ctx) {
854
870
  // Acts as the app owner — access.js allows `digest` docs for the owner only,
855
871
  // making this document genuinely server-controlled.
856
- await ctx.db.put({ _id: "digest", kind: "digest", updatedAt: event.scheduledTime }, { db: "digest" });
872
+ //
873
+ // What this tick already did is read BY ID, never re-derived from a scan, and
874
+ // the sweep is bounded by what is NEW rather than by how big the app has grown.
875
+ const state = await ctx.db.get("digest:state", { db: "digest" });
876
+ const since = state?.throughSeq ?? 0;
877
+ const fresh = await ctx.db.query({ db: "activity", field: "at", range: [since + 1, Number.MAX_SAFE_INTEGER], limit: 200 });
878
+ if (fresh.length === 0) return; // nothing happened — write nothing at all
879
+
880
+ const throughSeq = fresh.reduce((max, doc) => (doc.at > max ? doc.at : max), since);
881
+ const next = { _id: "digest", kind: "digest", headline: `${fresh.length} new notes`, throughSeq };
882
+ const existing = await ctx.db.get("digest", { db: "digest" });
883
+ if (existing?.headline === next.headline && existing?.throughSeq === next.throughSeq) return; // unchanged
884
+
885
+ await ctx.db.put(next, { db: "digest" });
886
+ await ctx.db.put({ _id: "digest:state", type: "digestState", throughSeq }, { db: "digest" });
857
887
  }
858
888
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibes.diy/prompts",
3
- "version": "14.0.14",
3
+ "version": "14.0.16",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "exports": {
@@ -34,9 +34,9 @@
34
34
  "license": "Apache-2.0",
35
35
  "dependencies": {
36
36
  "@adviser/cement": "~0.5.34",
37
- "@vibes.diy/call-ai-v2": "14.0.14",
38
- "@vibes.diy/identity": "14.0.14",
39
- "@vibes.diy/use-vibes-types": "14.0.14",
37
+ "@vibes.diy/call-ai-v2": "14.0.16",
38
+ "@vibes.diy/identity": "14.0.16",
39
+ "@vibes.diy/use-vibes-types": "14.0.16",
40
40
  "arktype": "~2.2.3",
41
41
  "json-schema-faker": "~0.6.3"
42
42
  },