@stage5/lumine 0.2.46 → 0.2.48
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/lib/admin.js +9 -1
- package/lib/commands.js +1 -1
- package/lib/sdk.js +3 -0
- package/package.json +1 -1
- package/sdk/BUILD_SDK_INDEX.md +23 -3
- package/sdk/LUMINE_ADMIN.md +80 -30
package/lib/admin.js
CHANGED
|
@@ -1151,6 +1151,11 @@ export function parseAdminOperation(options) {
|
|
|
1151
1151
|
}
|
|
1152
1152
|
|
|
1153
1153
|
if (namespace === "bot-output" && !action) {
|
|
1154
|
+
if (options.adminDays && options.adminCursor) {
|
|
1155
|
+
throw cliValidationError(
|
|
1156
|
+
"Continue a bot-output --cursor without changing its --days window.",
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1154
1159
|
if (options.adminDays) {
|
|
1155
1160
|
const days = Number(options.adminDays);
|
|
1156
1161
|
if (!Number.isInteger(days) || days < 1 || days > 30) {
|
|
@@ -1159,7 +1164,10 @@ export function parseAdminOperation(options) {
|
|
|
1159
1164
|
}
|
|
1160
1165
|
return readOperation(
|
|
1161
1166
|
"bot.output",
|
|
1162
|
-
withQuery("/cli/admin/bot-output", {
|
|
1167
|
+
withQuery("/cli/admin/bot-output", {
|
|
1168
|
+
days: options.adminDays,
|
|
1169
|
+
cursor: options.adminCursor,
|
|
1170
|
+
}),
|
|
1163
1171
|
);
|
|
1164
1172
|
}
|
|
1165
1173
|
|
package/lib/commands.js
CHANGED
|
@@ -2767,7 +2767,7 @@ export function printHelp() {
|
|
|
2767
2767
|
lumine admin comment post --draft-id <id> [--json]
|
|
2768
2768
|
lumine admin comment edit <comment-id> --file <comment.md> [--json]
|
|
2769
2769
|
lumine admin brief [--days <1..30>] [--json]
|
|
2770
|
-
lumine admin bot-output [--days <1..30>] [--json]
|
|
2770
|
+
lumine admin bot-output [--days <1..30>|--cursor <cursor>] [--json]
|
|
2771
2771
|
lumine admin announcement post --file <announcement.md> [--json]
|
|
2772
2772
|
lumine admin chat send <user-id|username> --file <message.md> [--json]
|
|
2773
2773
|
lumine admin news claim [--date YYYY-MM-DD] [--output <claim.json>] [--scaffold <editorial.json>] [--json]
|
package/lib/sdk.js
CHANGED
|
@@ -38,9 +38,12 @@ export const SDK_CLI_METHODS = {
|
|
|
38
38
|
"sharedDb.getTopics": { path: "api/shared-db/topics", scopes: ["sharedDb:read"] },
|
|
39
39
|
"sharedDb.createTopic": { path: "api/shared-db/topic", scopes: ["sharedDb:write"], write: true },
|
|
40
40
|
"sharedDb.getEntries": { path: "api/shared-db/entries", scopes: ["sharedDb:read"] },
|
|
41
|
+
"sharedDb.getEntriesByIds": { path: "api/shared-db/entries/by-ids", scopes: ["sharedDb:read"] },
|
|
41
42
|
"sharedDb.addEntry": { path: "api/shared-db/entry", scopes: ["sharedDb:write"], write: true },
|
|
43
|
+
"sharedDb.addEntries": { path: "api/shared-db/entries/batch", scopes: ["sharedDb:write"], write: true },
|
|
42
44
|
"sharedDb.updateEntry": { path: "api/shared-db/entry/update", scopes: ["sharedDb:write"], write: true },
|
|
43
45
|
"sharedDb.deleteEntry": { path: "api/shared-db/entry/delete", scopes: ["sharedDb:write"], write: true },
|
|
46
|
+
"sharedDb.deleteEntries": { path: "api/shared-db/entries/delete", scopes: ["sharedDb:write"], write: true },
|
|
44
47
|
"sharedDb.kv.get": { path: "api/shared-db/kv/get", scopes: ["sharedDb:read"] },
|
|
45
48
|
"sharedDb.kv.list": { path: "api/shared-db/kv/list", scopes: ["sharedDb:read"] },
|
|
46
49
|
// The kv/set endpoint is batch-shaped ({ namespace, items }); kv.set keeps
|
package/package.json
CHANGED
package/sdk/BUILD_SDK_INDEX.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Build SDK Index
|
|
2
2
|
|
|
3
|
-
Version: 1.
|
|
4
|
-
Updated: 2026-08-
|
|
5
|
-
Generated: 2026-08-
|
|
3
|
+
Version: 1.36.0
|
|
4
|
+
Updated: 2026-08-19
|
|
5
|
+
Generated: 2026-08-19T05:45:14.858Z
|
|
6
6
|
|
|
7
7
|
## Notes
|
|
8
8
|
- This SDK is injected into Build iframes via the Build preview/runtime.
|
|
@@ -645,6 +645,12 @@ const result = await Twinkle.characters.chat({ character: 'zero', thinkingMode:
|
|
|
645
645
|
- Fetch the next sharedDb page.
|
|
646
646
|
- Convenience alias for getEntries used by Load more buttons.
|
|
647
647
|
- Pass the previous response cursor to fetch the next page using the same order and page size.
|
|
648
|
+
- async getEntriesByIds(entryIds) | scopes: sharedDb:read
|
|
649
|
+
- Returns: { entries: [{ id, topicId, userId, username, profilePicUrl, data, createdAt, updatedAt }] }
|
|
650
|
+
- Read up to 100 shared rows by their app-scoped entry ids.
|
|
651
|
+
- Accepts 1-100 unique positive entry ids and returns the rows that still exist in the same order as requested.
|
|
652
|
+
- Ids from another Build app are never returned.
|
|
653
|
+
- Use this for bounded manifest references; use getEntries for browseable topic feeds.
|
|
648
654
|
- async addEntry(topicName, data, { notify } = {}) | scopes: sharedDb:write
|
|
649
655
|
- Returns: { entry: { id, topicId, userId, username, profilePicUrl, data, createdAt, updatedAt } }
|
|
650
656
|
- Append a shared JSON row, optionally creating a Twinkle notification from the canonical write.
|
|
@@ -653,6 +659,14 @@ const result = await Twinkle.characters.chat({ character: 'zero', thinkingMode:
|
|
|
653
659
|
- notify may include eventKey, label, summary, recipients, and target. Supported recipients start with { kind: 'buildOwner' }.
|
|
654
660
|
- Use target.focus, such as { kind: 'sharedDbEntry', entryId: '$createdEntryId' }, so Twinkle.notifications can focus the item when opened.
|
|
655
661
|
- Use Twinkle.leaderboards for standard top-score rankings and personal-best scoreboards.
|
|
662
|
+
- async addEntries(topicName, items) | scopes: sharedDb:write
|
|
663
|
+
- Returns: { entries: [{ id, topicId, userId, username, profilePicUrl, data, createdAt, updatedAt }] }
|
|
664
|
+
- Atomically append up to 100 owner-controlled JSON rows for one low-frequency user action.
|
|
665
|
+
- items must contain 1-100 JSON objects; each object remains capped at 10 KB.
|
|
666
|
+
- All rows are created atomically in one topic and returned as canonical server entries.
|
|
667
|
+
- Batch rows remain controlled by their creator or the Build owner, just like addEntry rows.
|
|
668
|
+
- This method intentionally does not support subjectRef or notifications; use addEntry when either is needed.
|
|
669
|
+
- Use for one bounded durable action, not per-frame or per-tick logging.
|
|
656
670
|
- async updateEntry(entryId, data, { notify } = {}) | scopes: sharedDb:write
|
|
657
671
|
- Returns: { entry: { id, topicId, userId, username, profilePicUrl, data, createdAt, updatedAt } }
|
|
658
672
|
- Update a viewer-owned shared row, optionally notifying safe recipients from the canonical write.
|
|
@@ -662,6 +676,12 @@ const result = await Twinkle.characters.chat({ character: 'zero', thinkingMode:
|
|
|
662
676
|
- async deleteEntry(entryId) | scopes: sharedDb:write
|
|
663
677
|
- Returns: { success: true }
|
|
664
678
|
- Deletes an entry. Only the entry creator or the build owner can delete.
|
|
679
|
+
- async deleteEntries(entryIds) | scopes: sharedDb:write
|
|
680
|
+
- Returns: { success: true, deletedEntryIds: number[], missingEntryIds: number[] }
|
|
681
|
+
- Atomically delete up to 100 owned shared rows.
|
|
682
|
+
- Accepts 1-100 unique positive entry ids.
|
|
683
|
+
- Every existing target must be writable by the viewer or Build owner; otherwise the whole request rejects without deleting anything.
|
|
684
|
+
- Missing rows are reported and ignored, making cleanup idempotent.
|
|
665
685
|
- async kv.get(namespace, key) | scopes: sharedDb:read
|
|
666
686
|
- Returns: { item: { id, key, value, version, changeSeq, deleted, updatedBy, createdAt, updatedAt } | null }
|
|
667
687
|
- Read one key from the keyed shared store (shared mutable state). Deleted keys read as null.
|
package/sdk/LUMINE_ADMIN.md
CHANGED
|
@@ -802,11 +802,13 @@ type BuildCandidates = Success<{
|
|
|
802
802
|
}>;
|
|
803
803
|
```
|
|
804
804
|
|
|
805
|
-
Subject cursors freeze a primary-key high-water mark
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
805
|
+
Subject cursors freeze a primary-key high-water mark plus the server snapshot
|
|
806
|
+
timestamp and traverse descending IDs; bounded scans keep creation timestamps
|
|
807
|
+
inside that confirmed interval. Bounded recommendation cursors freeze both the
|
|
808
|
+
feed-ID high-water mark and the server timestamp, then traverse the indexed
|
|
809
|
+
`(timeStamp, id)` order; this also catches a Daily Reflection whose old feed
|
|
810
|
+
row moved forward when it was reshared. Explicit legacy scans retain the
|
|
811
|
+
descending primary-key walk. A page
|
|
810
812
|
can be empty while `hasMore` remains true; continue until `exhausted`. `--all`
|
|
811
813
|
does that automatically and writes a private checkpoint after every
|
|
812
814
|
server-confirmed page; `--resume` continues only when the checkpoint belongs to
|
|
@@ -1449,6 +1451,7 @@ type NewsSubmit = NewsStatus; // "success"; newspaper includes revisionNumber
|
|
|
1449
1451
|
```bash
|
|
1450
1452
|
lumine admin bot-output --json
|
|
1451
1453
|
lumine admin bot-output --days 3 --json
|
|
1454
|
+
lumine admin bot-output --cursor '<pagination.nextCursor>' --json
|
|
1452
1455
|
```
|
|
1453
1456
|
|
|
1454
1457
|
**Every run reviews what Zero and Ciel themselves said since the last run.**
|
|
@@ -1463,26 +1466,72 @@ Reflections — and it surfaced only because the kid showed Mikey).
|
|
|
1463
1466
|
(`--days 1..30` overrides): `chatMessages` (every stored Zero/Ciel chat and
|
|
1464
1467
|
reflection reply, with full text and recipient metadata when its best-effort
|
|
1465
1468
|
prompt audit exists) and `comments`
|
|
1466
|
-
(every public bot comment/reply).
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1469
|
+
(every public bot comment/reply). Individual utterances are returned in full;
|
|
1470
|
+
the API never clips their tails. The first response freezes a canonical
|
|
1471
|
+
high-water mark for both sources. Truncation flags mark another page beyond
|
|
1472
|
+
the 400-row or bounded-response-size budget; continue with the exact
|
|
1473
|
+
`pagination.nextCursor` until
|
|
1474
|
+
`pagination.exhausted` is true and both flags are false. A cursor retains the
|
|
1475
|
+
original time window and cannot be combined with `--days`. Do not complete the
|
|
1476
|
+
run while either flag remains true. The default window deliberately overlaps
|
|
1477
|
+
from the previous completed run's start, so output created after its review
|
|
1478
|
+
snapshot but before completion is reviewed again instead of being lost. Run it
|
|
1479
|
+
right after the brief, and **read every row** — the tool deliberately does no
|
|
1480
|
+
filtering, scoring, or keyword matching, because the judgment is the reviewing
|
|
1481
|
+
agent's.
|
|
1482
|
+
|
|
1483
|
+
**Purpose and privacy boundary:** this audits how Twinkle's bots treated
|
|
1484
|
+
members; it is not thought-policing or a moderation queue for members' private
|
|
1485
|
+
use of the tool. The question is whether Zero or Ciel inflicted, encouraged,
|
|
1486
|
+
or operationally facilitated potential harm — not whether a member's private
|
|
1487
|
+
idea is taboo, upsetting, sexual, violent, or angry. Treat private human
|
|
1488
|
+
messages and creative work as confidential context. Read every bot-authored
|
|
1489
|
+
row, but inspect adjacent human messages only when the minimum necessary
|
|
1490
|
+
context is needed to judge what the bot did; never browse the rest of a private
|
|
1491
|
+
conversation out of curiosity. Never reuse private material for public
|
|
1492
|
+
editorial judgment, Notable User selection, or unrelated identity
|
|
1493
|
+
investigation.
|
|
1494
|
+
|
|
1495
|
+
**Private creative-expression rule (Mikey's direction, 2026-08-19):** Zero and
|
|
1496
|
+
Ciel are tools members may use to express lawful private fiction already in
|
|
1497
|
+
their imagination. A high-school member writing romantic or sexual fiction
|
|
1498
|
+
about fictional peers around their own age is not an escalation merely because
|
|
1499
|
+
the prose is explicit or set at a school. Sexual fantasy is not inherently a
|
|
1500
|
+
dangerous thought, just as violent or angry fantasy alone is not evidence of
|
|
1501
|
+
real-world intent. If the member requested the fictional content and the bot
|
|
1502
|
+
helped put it into words, that assistance is not by itself the bot encouraging
|
|
1503
|
+
the member to think or act that way. Do not characterize, flag, notify anyone
|
|
1504
|
+
about, or intervene in that private creative endeavor absent a separate
|
|
1505
|
+
concrete harm signal.
|
|
1506
|
+
|
|
1507
|
+
**Real-world-harm boundary:** actionable assistance for poisoning someone,
|
|
1508
|
+
covertly hurting or tormenting a real target, evading detection, grooming,
|
|
1509
|
+
abuse, or another actual crime is categorically different from fantasy. A bot
|
|
1510
|
+
that supplies such operational instructions commits an urgent conduct
|
|
1511
|
+
violation. A bot that refuses and redirects safely has behaved correctly; the
|
|
1512
|
+
member's request becomes a separate private safety escalation only when the
|
|
1513
|
+
available context shows a concrete, credible bridge to real-world harm — such
|
|
1514
|
+
as an identifiable target, expressed intent, means, planning, or concealment —
|
|
1515
|
+
not merely because a disturbing thought or fictional premise exists.
|
|
1516
|
+
|
|
1517
|
+
**Position-of-trust safeguarding rule (Mikey's direction, 2026-08-19):** an
|
|
1518
|
+
adult teacher, or another adult in a comparable position of authority and
|
|
1519
|
+
direct access to children, creating or requesting sexual content about an
|
|
1520
|
+
underage child is always a private safeguarding escalation, even when framed
|
|
1521
|
+
as fiction. The mandatory flag follows from the adult's power, duty of care,
|
|
1522
|
+
and access to students — not from treating sex as uniquely taboo. Preserve only
|
|
1523
|
+
the minimum necessary evidence and report it privately to Mikey so he can tell
|
|
1524
|
+
Andrew and decide the response. A flag is not a public accusation or automatic
|
|
1525
|
+
finding of guilt; do not contact the teacher, students, or families without
|
|
1526
|
+
Mikey's direction. An identifiable real student, grooming, planning,
|
|
1527
|
+
concealment, or actionable abuse makes the escalation urgent.
|
|
1528
|
+
|
|
1529
|
+
Every escalation must state which rule was triggered and identify either what
|
|
1530
|
+
**Zero or Ciel** did (for example, an invented premise, pressure,
|
|
1531
|
+
sexualization of the member, actionable facilitation, abuse, or a failed
|
|
1532
|
+
boundary) or the concrete safeguarding signal. Include only the narrow context
|
|
1533
|
+
needed for Mikey to decide a remedy. A separate concrete risk may justify this
|
|
1534
|
+
minimal review, but it never authorizes browsing unrelated private activity.
|
|
1486
1535
|
|
|
1487
1536
|
Judge against the same values the editorial priorities encode:
|
|
1488
1537
|
|
|
@@ -1510,11 +1559,12 @@ Judge against the same values the editorial priorities encode:
|
|
|
1510
1559
|
enforce. Even a genuinely excessive routine warrants a question ("is this
|
|
1511
1560
|
still helping you, or would a break feel better?"), never a decree.
|
|
1512
1561
|
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
apologize as the bot, edit,
|
|
1516
|
-
|
|
1517
|
-
|
|
1562
|
+
A bot-conduct violation or mandatory safeguarding signal goes on the
|
|
1563
|
+
escalation list with the smallest excerpt and identity needed to evaluate it —
|
|
1564
|
+
top of the list when urgent. Do not apologize as the bot, edit, contact the
|
|
1565
|
+
member, or otherwise clean up without Mikey's direction; he decides the
|
|
1566
|
+
remedy. When he explicitly directs a private correction, use the composed-only
|
|
1567
|
+
existing-DM path (no model and no AI Energy):
|
|
1518
1568
|
|
|
1519
1569
|
```bash
|
|
1520
1570
|
lumine admin chat send <userId|username> --file message.md --json
|