@dyx9/rosetta 0.0.0-stage → 0.0.1
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/.env.example +59 -0
- package/LICENSE +21 -0
- package/README.md +101 -2
- package/bin/rosetta.js +10 -0
- package/build/dist/assets/abnfDiagram-WEYOIA3C-CwZlxHkI.js +1 -0
- package/build/dist/assets/arc-B0x0q6O1.js +1 -0
- package/build/dist/assets/architecture-WOLXFQ4H-CkOpgBe5.js +1 -0
- package/build/dist/assets/architectureDiagram-ZHVYKT53-DT2OTBIB.js +36 -0
- package/build/dist/assets/array-BifhSqXX.js +1 -0
- package/build/dist/assets/bash-CLZ0U2zV.js +1 -0
- package/build/dist/assets/blockDiagram-RJAE7QA3-DXKyW4Qj.js +140 -0
- package/build/dist/assets/c4Diagram-XDPPPE54-CqHMZj3I.js +38 -0
- package/build/dist/assets/channel-BmjZSxDJ.js +1 -0
- package/build/dist/assets/chunk-2E7WHVMD-DTKlOCW9.js +88 -0
- package/build/dist/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/build/dist/assets/chunk-4EMNKR2T-BsnKxZVc.js +1 -0
- package/build/dist/assets/chunk-55XCU76K-Ddul4yK8.js +1 -0
- package/build/dist/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/build/dist/assets/chunk-7S6XSTFO-D73i4Kfs.js +2 -0
- package/build/dist/assets/chunk-AQDTSKZB-DJMpZsbr.js +72 -0
- package/build/dist/assets/chunk-DSNLSHJZ-KWPl82ns.js +129 -0
- package/build/dist/assets/chunk-DUW6YSOI-Dgx8z5s3.js +1 -0
- package/build/dist/assets/chunk-HAGFOTED-Co5xWe5K.js +62 -0
- package/build/dist/assets/chunk-HNE4Q36P-D9ufLjJL.js +1 -0
- package/build/dist/assets/chunk-J5ZVWO5B-oDCd-gWO.js +1 -0
- package/build/dist/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/build/dist/assets/chunk-NGNAAXSQ-C2Wy9Xmz.js +136 -0
- package/build/dist/assets/chunk-NQOKRVIF-DuVeWA2D.js +213 -0
- package/build/dist/assets/chunk-UHW7PFBP-DrzHcxiz.js +1 -0
- package/build/dist/assets/chunk-VQ5W62QI-tyK9wvZy.js +1 -0
- package/build/dist/assets/chunk-WQQL4CDK-BtfOu2ju.js +10 -0
- package/build/dist/assets/chunk-XXDRQBXY-BFig8xVb.js +1 -0
- package/build/dist/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/build/dist/assets/chunk-YZO67HFG-Cw5eVjq1.js +1 -0
- package/build/dist/assets/chunk-ZAUX2LTX-CIpKyMEe.js +1 -0
- package/build/dist/assets/chunk-ZCHMQSOR-Djve8pwS.js +2 -0
- package/build/dist/assets/classDiagram-v2-4MYWR3UA-D4XAcUCd.js +217 -0
- package/build/dist/assets/cose-bilkent-JH36ORCC-DHRGyJqU.js +1 -0
- package/build/dist/assets/cynefin-EF2NZ3EQ-Cv-uxuqE.js +1 -0
- package/build/dist/assets/cynefinDiagram-WF24UDRP-MFe-UzcY.js +62 -0
- package/build/dist/assets/cytoscape.esm-BegBNzOV.js +321 -0
- package/build/dist/assets/dagre-NK4GIZVX-BsY0-Q-N.js +4 -0
- package/build/dist/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/build/dist/assets/diagram-CBK3MWTC-9zfXZ0bX.js +24 -0
- package/build/dist/assets/diagram-I5XIIV2D-CfWjvEof.js +24 -0
- package/build/dist/assets/diagram-ODIL2UCW-BpJaYO2i.js +30 -0
- package/build/dist/assets/diagram-PFBEJUXE-CtpxT_FQ.js +3 -0
- package/build/dist/assets/diagram-RJA3I4VV-DuLQrOcT.js +41 -0
- package/build/dist/assets/diagram-TYUNFSNR-w6Mohdl5.js +200 -0
- package/build/dist/assets/dist-DI7WHQIh.js +1 -0
- package/build/dist/assets/ebnfDiagram-V4P3TTPT-DlwHfKyL.js +1 -0
- package/build/dist/assets/elk-QONTBCTQ-DEvtD9nx.js +27 -0
- package/build/dist/assets/erDiagram-KYQIGQAA-DQuhkec3.js +99 -0
- package/build/dist/assets/eventmodeling-K75KTNOO-BO57PAOs.js +1 -0
- package/build/dist/assets/flowDiagram-IUGLLWBU-B_Ib7Avh.js +1 -0
- package/build/dist/assets/ganttDiagram-R7GPNTJY-CDGbtnUY.js +292 -0
- package/build/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/build/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/build/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/build/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/build/dist/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/build/dist/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/build/dist/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/build/dist/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/build/dist/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/build/dist/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/build/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/build/dist/assets/gitGraph-VSP46ZUC-D9ZZKP8z.js +1 -0
- package/build/dist/assets/gitGraphDiagram-PDYL7XHY-Da8Oypep.js +106 -0
- package/build/dist/assets/github-dark-C-LZuMrd.js +1 -0
- package/build/dist/assets/github-light-EUqPIrTm.js +1 -0
- package/build/dist/assets/graphlib-DS17s2tU.js +1 -0
- package/build/dist/assets/index-Cf0aBmwz.css +2 -0
- package/build/dist/assets/index-Ct3brajV.js +471 -0
- package/build/dist/assets/info-OHQRW6UA-BF836x6L.js +1 -0
- package/build/dist/assets/infoDiagram-MVDRKAX5-DpOoH-IR.js +2 -0
- package/build/dist/assets/init-C-OQMol4.js +1 -0
- package/build/dist/assets/ishikawaDiagram-HPEHV2GE-DT-Ft7vW.js +70 -0
- package/build/dist/assets/javascript-BgS3c2Ky.js +1 -0
- package/build/dist/assets/journeyDiagram-BOSHW7O7-BAF7tJ1H.js +139 -0
- package/build/dist/assets/json-qhed-kSA.js +1 -0
- package/build/dist/assets/kanban-definition-FNSA4HC5-B_w2r2eo.js +89 -0
- package/build/dist/assets/katex-B_JcIwqj.js +257 -0
- package/build/dist/assets/line-DMjgRylK.js +1 -0
- package/build/dist/assets/linear-BEdVl1PM.js +1 -0
- package/build/dist/assets/mermaid-parser.core-BDmgiU7m.js +7 -0
- package/build/dist/assets/mermaid.core-8Kj_dqOs.js +44 -0
- package/build/dist/assets/mindmap-definition-6OY57UG3-DOcaArfN.js +98 -0
- package/build/dist/assets/ordinal-BDEzSJ7C.js +1 -0
- package/build/dist/assets/packet-JDAUHWVQ-zWLPVpvX.js +1 -0
- package/build/dist/assets/path-fybaL0A-.js +1 -0
- package/build/dist/assets/pegDiagram-ECIUJNBX-sYwsFyAl.js +1 -0
- package/build/dist/assets/pie-XZMESJXO-B-h0LV9S.js +1 -0
- package/build/dist/assets/pieDiagram-GNMPY74T-FToCIvky.js +39 -0
- package/build/dist/assets/python-gzcpVVnB.js +1 -0
- package/build/dist/assets/quadrantDiagram-D57K4MC3-tiXtbFLP.js +7 -0
- package/build/dist/assets/radar-ABXABTNO--ew_ZFJl.js +1 -0
- package/build/dist/assets/railroad-I3PHUGI6-cxsf_ZsE.js +1 -0
- package/build/dist/assets/railroad-abnf-LNEFI6M7-BIK-9C0Z.js +1 -0
- package/build/dist/assets/railroad-ebnf-DWYD2UWJ-BHw1M8VQ.js +1 -0
- package/build/dist/assets/railroad-peg-JR7BVNR7-MHCdZHAZ.js +1 -0
- package/build/dist/assets/railroadDiagram-Y72NRBL7-wjsZpnJA.js +1 -0
- package/build/dist/assets/requirementDiagram-EQYSW5RA-CHkzAP3w.js +84 -0
- package/build/dist/assets/rough.esm-Dy-Kn_BL.js +1 -0
- package/build/dist/assets/sankeyDiagram-SY24JHO5-BBLq6ndO.js +40 -0
- package/build/dist/assets/sequenceDiagram-BLEHNHQU-DW_h9VZQ.js +169 -0
- package/build/dist/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/build/dist/assets/src-MbiMZlpk.js +1 -0
- package/build/dist/assets/stateDiagram-v2-A6IESKWZ-BgpDkVUs.js +291 -0
- package/build/dist/assets/swimlanes-B3ENRKFQ-DJHWFYmN.js +1 -0
- package/build/dist/assets/swimlanesDiagram-AYQRV4AK-Cq_MGOxD.js +8 -0
- package/build/dist/assets/timeline-definition-JXYKGLGB-DQ-XYDnd.js +120 -0
- package/build/dist/assets/treeView-D4JQ5SDB-ydIf6KAy.js +1 -0
- package/build/dist/assets/treemap-SAJKECNS-CB6tZuFJ.js +1 -0
- package/build/dist/assets/typescript-bsJCZSQ-.js +1 -0
- package/build/dist/assets/usecaseDiagram-WPOLBNNX-D_A5G5wv.js +328 -0
- package/build/dist/assets/vennDiagram-Q3Y3IDCW-j2yUit_4.js +34 -0
- package/build/dist/assets/wardley-7MLQ67FV-BztBXEva.js +1 -0
- package/build/dist/assets/wardleyDiagram-IVAIDKWA-CyrXADWS.js +78 -0
- package/build/dist/assets/xychartDiagram-4URNHDU4-BM2yVuEH.js +7 -0
- package/build/dist/favicon.svg +1 -0
- package/build/dist/icons.svg +24 -0
- package/build/dist/index.html +14 -0
- package/build/server/agent/conversation.js +244 -0
- package/build/server/agent/harness.js +435 -0
- package/build/server/agent/sessions.js +222 -0
- package/build/server/agent/turn.js +56 -0
- package/build/server/config.js +92 -0
- package/build/server/http/auth.js +31 -0
- package/build/server/http/chat.js +67 -0
- package/build/server/http/feedback.js +30 -0
- package/build/server/http/routes.js +231 -0
- package/build/server/http/stream.js +39 -0
- package/build/server/http/util.js +40 -0
- package/build/server/index.js +112 -0
- package/build/server/records/operations.js +53 -0
- package/build/server/records/recording.js +186 -0
- package/build/server/records/turn-recording.js +151 -0
- package/build/server/stone/file-boundary.js +57 -0
- package/build/server/stone/prompt.js +83 -0
- package/build/server/stone/stone.js +245 -0
- package/build/server/stone/verify.js +141 -0
- package/build/src/shared/protocol.js +25 -0
- package/build/stones/example/AGENTS.md +25 -0
- package/build/stones/example/checks/hotspot.py +74 -0
- package/build/stones/example/checks/syntax.py +13 -0
- package/build/stones/example/constraints/rig-limits.md +15 -0
- package/build/stones/example/docs/reference.md +26 -0
- package/build/stones/example/examples/good/crossfade.py +15 -0
- package/build/stones/example/examples/violations/hotspot.py +17 -0
- package/build/stones/example/rosetta.json +23 -0
- package/build/stones/example/skills/writing-cues/SKILL.md +21 -0
- package/package.json +74 -4
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The wire format between server and browser.
|
|
3
|
+
*
|
|
4
|
+
* Imported by both sides so the two cannot drift. Every value is JSON-safe:
|
|
5
|
+
* each event is serialised as one line of NDJSON.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Highlighting grammars bundled with the client.
|
|
9
|
+
*
|
|
10
|
+
* Shared so the server can warn about a stone declaring a `language` that will
|
|
11
|
+
* silently render as plain text. Adding one here means adding the import in
|
|
12
|
+
* `src/lib/highlighter.ts` too.
|
|
13
|
+
*/
|
|
14
|
+
export const BUNDLED_LANGUAGES = [
|
|
15
|
+
"python",
|
|
16
|
+
"javascript",
|
|
17
|
+
"typescript",
|
|
18
|
+
"json",
|
|
19
|
+
"bash",
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Name of the tool that runs a stone's checkers. Shared so the UI can say
|
|
23
|
+
* "checking" rather than "reading documentation" while it runs.
|
|
24
|
+
*/
|
|
25
|
+
export const CHECK_TOOL = "check_script";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Stagelight
|
|
2
|
+
|
|
3
|
+
Stagelight is a small Python dialect for writing stage lighting cues. It runs on an embedded
|
|
4
|
+
interpreter inside the lighting desk, so only the host functions below are available. The
|
|
5
|
+
Python standard library is **not** importable.
|
|
6
|
+
|
|
7
|
+
## Host functions
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
fixture(id: str) -> Fixture # look up a fixture by its patch id, e.g. "spot-1"
|
|
11
|
+
aim(f: Fixture, x: float, y: float) # aim at a stage coordinate, in metres from centre
|
|
12
|
+
intensity(f: Fixture, pct: float) # 0.0 to 100.0
|
|
13
|
+
fade(f: Fixture, pct: float, secs: float) # ramp intensity over time
|
|
14
|
+
wait(secs: float) # hold before the next instruction
|
|
15
|
+
blackout() # all fixtures to 0
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Ordinary Python control flow works: `for`, `while`, `if`, functions, arithmetic. There are no
|
|
19
|
+
imports, no file access, and no networking.
|
|
20
|
+
|
|
21
|
+
## Constraints
|
|
22
|
+
|
|
23
|
+
The language will accept scripts that the rig cannot safely run. The rules that decide
|
|
24
|
+
which are in `constraints/rig-limits.md`, which is always in your context alongside this
|
|
25
|
+
file. Check every script against them before offering it.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Domain check for Stagelight: the hotspot rule.
|
|
3
|
+
|
|
4
|
+
No two fixtures may both exceed 70% intensity while aimed within 2.0 metres of
|
|
5
|
+
each other. This is valid Stagelight in every respect; only the rig says no.
|
|
6
|
+
Reads a script on stdin. Exit 0 passes.
|
|
7
|
+
"""
|
|
8
|
+
import ast
|
|
9
|
+
import math
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
MIN_SEPARATION_M = 2.0
|
|
13
|
+
HOT_THRESHOLD_PCT = 70.0
|
|
14
|
+
|
|
15
|
+
source = sys.stdin.read()
|
|
16
|
+
try:
|
|
17
|
+
tree = ast.parse(source)
|
|
18
|
+
except SyntaxError:
|
|
19
|
+
sys.exit(0) # The syntax check owns this; stay quiet.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def number(node):
|
|
23
|
+
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
|
|
24
|
+
return float(node.value)
|
|
25
|
+
if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
|
|
26
|
+
inner = number(node.operand)
|
|
27
|
+
return None if inner is None else -inner
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
fixtures, aims, levels, lines = {}, {}, {}, {}
|
|
32
|
+
|
|
33
|
+
for node in ast.walk(tree):
|
|
34
|
+
# name = fixture("spot-1")
|
|
35
|
+
if isinstance(node, ast.Assign) and isinstance(node.value, ast.Call):
|
|
36
|
+
call = node.value
|
|
37
|
+
if isinstance(call.func, ast.Name) and call.func.id == "fixture" and call.args:
|
|
38
|
+
arg = call.args[0]
|
|
39
|
+
if isinstance(node.targets[0], ast.Name) and isinstance(arg, ast.Constant):
|
|
40
|
+
fixtures[node.targets[0].id] = str(arg.value)
|
|
41
|
+
|
|
42
|
+
if not isinstance(node, ast.Call) or not isinstance(node.func, ast.Name):
|
|
43
|
+
continue
|
|
44
|
+
name, args = node.func.id, node.args
|
|
45
|
+
|
|
46
|
+
if name == "aim" and len(args) >= 3 and isinstance(args[0], ast.Name):
|
|
47
|
+
x, y = number(args[1]), number(args[2])
|
|
48
|
+
if x is not None and y is not None:
|
|
49
|
+
aims[args[0].id] = (x, y)
|
|
50
|
+
lines[args[0].id] = node.lineno
|
|
51
|
+
elif name in ("intensity", "fade") and len(args) >= 2 and isinstance(args[0], ast.Name):
|
|
52
|
+
pct = number(args[1])
|
|
53
|
+
if pct is not None:
|
|
54
|
+
levels[args[0].id] = max(levels.get(args[0].id, 0.0), pct)
|
|
55
|
+
lines[args[0].id] = node.lineno
|
|
56
|
+
|
|
57
|
+
hot = [v for v, pct in levels.items() if pct > HOT_THRESHOLD_PCT and v in aims]
|
|
58
|
+
violations = []
|
|
59
|
+
for i, a in enumerate(hot):
|
|
60
|
+
for b in hot[i + 1:]:
|
|
61
|
+
gap = math.dist(aims[a], aims[b])
|
|
62
|
+
if gap < MIN_SEPARATION_M:
|
|
63
|
+
violations.append(
|
|
64
|
+
f"line {max(lines.get(a, 0), lines.get(b, 0))}: "
|
|
65
|
+
f"{fixtures.get(a, a)} ({levels[a]:.0f}%) and {fixtures.get(b, b)} "
|
|
66
|
+
f"({levels[b]:.0f}%) are {gap:.2f}m apart, minimum is {MIN_SEPARATION_M}m "
|
|
67
|
+
f"when both exceed {HOT_THRESHOLD_PCT:.0f}%"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if violations:
|
|
71
|
+
print("hotspot rule violated:", file=sys.stderr)
|
|
72
|
+
for line in violations:
|
|
73
|
+
print(f" {line}", file=sys.stderr)
|
|
74
|
+
sys.exit(1)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Syntax check for Stagelight: the language is a Python dialect, so the
|
|
3
|
+
grammar is Python's. Reads a script on stdin. Exit 0 passes."""
|
|
4
|
+
import ast
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
source = sys.stdin.read()
|
|
8
|
+
try:
|
|
9
|
+
ast.parse(source)
|
|
10
|
+
except SyntaxError as error:
|
|
11
|
+
line = error.lineno or "?"
|
|
12
|
+
print(f"line {line}: {error.msg}", file=sys.stderr)
|
|
13
|
+
sys.exit(1)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Rig limits
|
|
2
|
+
|
|
3
|
+
These are physical limits of the lighting rig, not rules of the language. A script that
|
|
4
|
+
breaks one is still valid Stagelight and will still run — it will just damage equipment or
|
|
5
|
+
the set. Never produce a script that violates them.
|
|
6
|
+
|
|
7
|
+
1. **Hotspot rule.** No two fixtures may both exceed 70% intensity while aimed within 2.0
|
|
8
|
+
metres of each other. The combined heat scorches painted flats.
|
|
9
|
+
2. **Slew rule.** A fixture may not be re-aimed more than 4.0 metres in under 1.0 second. The
|
|
10
|
+
yoke motor stalls and loses calibration.
|
|
11
|
+
3. **Cold start.** A fixture below 10% must not jump above 80% in one step. Ramp it with
|
|
12
|
+
`fade` over at least 0.5 seconds or the lamp cracks.
|
|
13
|
+
|
|
14
|
+
When a request would violate one of these, say so plainly, name the rule, and offer the
|
|
15
|
+
nearest version that satisfies it.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Stagelight reference
|
|
2
|
+
|
|
3
|
+
## Coordinates
|
|
4
|
+
|
|
5
|
+
Stage coordinates are metres from centre stage. `x` runs stage-left negative to stage-right
|
|
6
|
+
positive. `y` runs downstage negative to upstage positive. The usable area is roughly
|
|
7
|
+
-6.0 to 6.0 on x and -4.0 to 4.0 on y.
|
|
8
|
+
|
|
9
|
+
## Timing
|
|
10
|
+
|
|
11
|
+
`wait(secs)` blocks the whole script. `fade(f, pct, secs)` returns immediately and the ramp
|
|
12
|
+
continues in the background, so two fades started together run in parallel.
|
|
13
|
+
|
|
14
|
+
To run fades in sequence, follow each with `wait` for at least the fade duration.
|
|
15
|
+
|
|
16
|
+
## Fixture ids
|
|
17
|
+
|
|
18
|
+
Fixtures are patched as `spot-N`, `wash-N` or `cyc-N`. `fixture()` raises if the id is not
|
|
19
|
+
patched. There is no way to enumerate fixtures from a script; the ids come from the patch
|
|
20
|
+
sheet.
|
|
21
|
+
|
|
22
|
+
## Errors
|
|
23
|
+
|
|
24
|
+
A script that raises stops immediately and the desk holds the last state. It does not black
|
|
25
|
+
out. Always end a cue sequence with an explicit state rather than relying on the script
|
|
26
|
+
ending.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Task: bring two fixtures to centre stage without creating a hotspot.
|
|
2
|
+
#
|
|
3
|
+
# Both fixtures end up near centre, so rule 1 applies. They are staggered
|
|
4
|
+
# 2.4 metres apart on the x axis, which clears the 2.0 metre minimum, and
|
|
5
|
+
# each ramps with fade() rather than jumping, which satisfies rule 3.
|
|
6
|
+
|
|
7
|
+
left = fixture("spot-1")
|
|
8
|
+
right = fixture("spot-2")
|
|
9
|
+
|
|
10
|
+
aim(left, -1.2, 0.0)
|
|
11
|
+
aim(right, 1.2, 0.0)
|
|
12
|
+
wait(1.0)
|
|
13
|
+
|
|
14
|
+
fade(left, 85.0, 2.0)
|
|
15
|
+
fade(right, 85.0, 2.0)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# VIOLATES RULE 1 — hotspot.
|
|
2
|
+
#
|
|
3
|
+
# This is valid Stagelight. The interpreter accepts it and the desk will run it.
|
|
4
|
+
# Both fixtures are aimed at exactly the same point at 90% intensity, which is
|
|
5
|
+
# well over the 70% threshold with 0.0 metres of separation.
|
|
6
|
+
#
|
|
7
|
+
# The fix is to separate the aim points by at least 2.0 metres, or to keep one
|
|
8
|
+
# fixture at or below 70%.
|
|
9
|
+
|
|
10
|
+
left = fixture("spot-1")
|
|
11
|
+
right = fixture("spot-2")
|
|
12
|
+
|
|
13
|
+
aim(left, 0.0, 0.0)
|
|
14
|
+
aim(right, 0.0, 0.0)
|
|
15
|
+
|
|
16
|
+
intensity(left, 90.0)
|
|
17
|
+
intensity(right, 90.0)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"agentName": "Stagelight Assistant",
|
|
3
|
+
"languageName": "Stagelight",
|
|
4
|
+
"welcomeMessage": "Ask how to write Stagelight cues, or describe what you want the lights to do.",
|
|
5
|
+
"suggestedQuestions": [
|
|
6
|
+
"How do I fade a fixture up over 3 seconds?",
|
|
7
|
+
"Move two fixtures to centre stage at full intensity",
|
|
8
|
+
"What happens if I aim two fixtures at the same spot?"
|
|
9
|
+
],
|
|
10
|
+
"answersAbout": "the Stagelight scripting language and stage lighting safety rules",
|
|
11
|
+
"syntaxHighlighting": "python",
|
|
12
|
+
"alwaysInContext": ["AGENTS.md", "constraints/**/*.md", "examples/**/*"],
|
|
13
|
+
"checks": [
|
|
14
|
+
{
|
|
15
|
+
"name": "syntax",
|
|
16
|
+
"command": ["python3", "./checks/syntax.py"]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "hotspot",
|
|
20
|
+
"command": ["python3", "./checks/hotspot.py"]
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: writing-cues
|
|
3
|
+
description: How to draft a Stagelight cue sequence from a plain-English request. Use whenever asked to write, draft, change or fix a cue or script.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Writing a cue
|
|
7
|
+
|
|
8
|
+
1. Name every fixture by its patch id (`spot-1`, `wash-2`). Never invent one; if the
|
|
9
|
+
request does not say which fixture, ask.
|
|
10
|
+
2. Before writing any `aim`, check the new position against the hotspot rule and the
|
|
11
|
+
slew rule in AGENTS.md. If either would be broken, say which and offer the nearest
|
|
12
|
+
safe version instead.
|
|
13
|
+
3. Use `fade` rather than `intensity` for any change larger than 30 points, and never
|
|
14
|
+
jump a fixture from under 10% to over 80% in one step.
|
|
15
|
+
4. Fades run in parallel unless separated by `wait`. To run them in sequence, follow each
|
|
16
|
+
`fade` with a `wait` of at least the same duration.
|
|
17
|
+
5. End with an explicit state — a final `intensity`, `fade` or `blackout()`. A script that
|
|
18
|
+
simply stops leaves the rig wherever it was.
|
|
19
|
+
|
|
20
|
+
Compare the request with `examples/good/` and `examples/violations/` before answering:
|
|
21
|
+
the violations show what a valid-looking but unsafe cue looks like.
|
package/package.json
CHANGED
|
@@ -1,6 +1,76 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dyx9/rosetta",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "An assistant that answers questions about a custom scripting language and drafts scripts in it, from documentation you supply as a stone.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/dyx9/rosetta-agent.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/dyx9/rosetta-agent#readme",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"bin": {
|
|
13
|
+
"rosetta": "bin/rosetta.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin",
|
|
17
|
+
"build",
|
|
18
|
+
".env.example"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=22.19"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"dev": "node --env-file-if-exists=.env node_modules/vite/bin/vite.js",
|
|
28
|
+
"serve": "node --env-file-if-exists=.env server/index.ts",
|
|
29
|
+
"build": "tsc -b && vite build",
|
|
30
|
+
"preview": "vite preview",
|
|
31
|
+
"lint": "oxlint",
|
|
32
|
+
"format": "prettier --write .",
|
|
33
|
+
"format:check": "prettier --check .",
|
|
34
|
+
"test": "node --experimental-test-module-mocks --test tests/*.test.ts",
|
|
35
|
+
"prepack": "node scripts/build-package.ts"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@earendil-works/pi-coding-agent": "1.3.0",
|
|
39
|
+
"fastest-levenshtein": "^1.0.16",
|
|
40
|
+
"sirv": "^3.0.2",
|
|
41
|
+
"typebox": "^1.4.2",
|
|
42
|
+
"zod": "^4.6.7"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@base-ui/react": "^1.9.0",
|
|
46
|
+
"@fontsource-variable/geist": "^5.3.0",
|
|
47
|
+
"@fontsource-variable/geist-mono": "^5.3.0",
|
|
48
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
49
|
+
"@types/node": "^25.9.9",
|
|
50
|
+
"@types/react": "^19.3.0",
|
|
51
|
+
"@types/react-dom": "^19.3.0",
|
|
52
|
+
"@vitejs/plugin-react": "^6.1.2",
|
|
53
|
+
"class-variance-authority": "^0.7.1",
|
|
54
|
+
"clsx": "^2.1.1",
|
|
55
|
+
"lucide-react": "^1.59.0",
|
|
56
|
+
"mermaid": "^12.2.0",
|
|
57
|
+
"nanoid": "^6.0.2",
|
|
58
|
+
"next-themes": "^0.4.6",
|
|
59
|
+
"oxlint": "^1.89.0",
|
|
60
|
+
"prettier": "3.9.10",
|
|
61
|
+
"react": "^19.3.1",
|
|
62
|
+
"react-dom": "^19.3.1",
|
|
63
|
+
"react-markdown": "^10.1.0",
|
|
64
|
+
"rehype-katex": "^7.0.1",
|
|
65
|
+
"remark-gfm": "^4.0.1",
|
|
66
|
+
"remark-math": "^6.0.0",
|
|
67
|
+
"shadcn": "^4.22.1",
|
|
68
|
+
"shiki": "^4.5.0",
|
|
69
|
+
"sonner": "^2.0.8",
|
|
70
|
+
"tailwind-merge": "^3.7.0",
|
|
71
|
+
"tailwindcss": "^4.3.3",
|
|
72
|
+
"tw-animate-css": "^1.4.0",
|
|
73
|
+
"typescript": "~7.0.2",
|
|
74
|
+
"vite": "^8.3.4"
|
|
75
|
+
}
|
|
76
|
+
}
|