@cratis/screenplay-language 0.1.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.
Files changed (147) hide show
  1. package/README.md +52 -0
  2. package/completion-items.ts +128 -0
  3. package/completion-planner.ts +111 -0
  4. package/completions.ts +112 -0
  5. package/diagnostics.ts +52 -0
  6. package/dist/completion-items.d.ts +23 -0
  7. package/dist/completion-items.d.ts.map +1 -0
  8. package/dist/completion-items.js +105 -0
  9. package/dist/completion-items.js.map +1 -0
  10. package/dist/completion-planner.d.ts +25 -0
  11. package/dist/completion-planner.d.ts.map +1 -0
  12. package/dist/completion-planner.js +90 -0
  13. package/dist/completion-planner.js.map +1 -0
  14. package/dist/completions.d.ts +4 -0
  15. package/dist/completions.d.ts.map +1 -0
  16. package/dist/completions.js +78 -0
  17. package/dist/completions.js.map +1 -0
  18. package/dist/diagnostics.d.ts +5 -0
  19. package/dist/diagnostics.d.ts.map +1 -0
  20. package/dist/diagnostics.js +47 -0
  21. package/dist/diagnostics.js.map +1 -0
  22. package/dist/document-context.d.ts +5 -0
  23. package/dist/document-context.d.ts.map +1 -0
  24. package/dist/document-context.js +45 -0
  25. package/dist/document-context.js.map +1 -0
  26. package/dist/hover-content.d.ts +2 -0
  27. package/dist/hover-content.d.ts.map +1 -0
  28. package/dist/hover-content.js +64 -0
  29. package/dist/hover-content.js.map +1 -0
  30. package/dist/hover.d.ts +3 -0
  31. package/dist/hover.d.ts.map +1 -0
  32. package/dist/hover.js +15 -0
  33. package/dist/hover.js.map +1 -0
  34. package/dist/index.d.ts +23 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +54 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/keyword-docs.d.ts +4 -0
  39. package/dist/keyword-docs.d.ts.map +1 -0
  40. package/dist/keyword-docs.js +100 -0
  41. package/dist/keyword-docs.js.map +1 -0
  42. package/dist/language.d.ts +12 -0
  43. package/dist/language.d.ts.map +1 -0
  44. package/dist/language.js +117 -0
  45. package/dist/language.js.map +1 -0
  46. package/dist/sub-language-registry.d.ts +20 -0
  47. package/dist/sub-language-registry.d.ts.map +1 -0
  48. package/dist/sub-language-registry.js +18 -0
  49. package/dist/sub-language-registry.js.map +1 -0
  50. package/dist/sub-languages/capture/CompletionProvider.d.ts +32 -0
  51. package/dist/sub-languages/capture/CompletionProvider.d.ts.map +1 -0
  52. package/dist/sub-languages/capture/CompletionProvider.js +332 -0
  53. package/dist/sub-languages/capture/CompletionProvider.js.map +1 -0
  54. package/dist/sub-languages/capture/HoverProvider.d.ts +8 -0
  55. package/dist/sub-languages/capture/HoverProvider.d.ts.map +1 -0
  56. package/dist/sub-languages/capture/HoverProvider.js +87 -0
  57. package/dist/sub-languages/capture/HoverProvider.js.map +1 -0
  58. package/dist/sub-languages/capture/Validator.d.ts +6 -0
  59. package/dist/sub-languages/capture/Validator.d.ts.map +1 -0
  60. package/dist/sub-languages/capture/Validator.js +72 -0
  61. package/dist/sub-languages/capture/Validator.js.map +1 -0
  62. package/dist/sub-languages/capture/index.d.ts +6 -0
  63. package/dist/sub-languages/capture/index.d.ts.map +1 -0
  64. package/dist/sub-languages/capture/index.js +58 -0
  65. package/dist/sub-languages/capture/index.js.map +1 -0
  66. package/dist/sub-languages/capture/language.d.ts +6 -0
  67. package/dist/sub-languages/capture/language.d.ts.map +1 -0
  68. package/dist/sub-languages/capture/language.js +160 -0
  69. package/dist/sub-languages/capture/language.js.map +1 -0
  70. package/dist/sub-languages/cdl.d.ts +3 -0
  71. package/dist/sub-languages/cdl.d.ts.map +1 -0
  72. package/dist/sub-languages/cdl.js +74 -0
  73. package/dist/sub-languages/cdl.js.map +1 -0
  74. package/dist/sub-languages/pdl.d.ts +3 -0
  75. package/dist/sub-languages/pdl.d.ts.map +1 -0
  76. package/dist/sub-languages/pdl.js +67 -0
  77. package/dist/sub-languages/pdl.js.map +1 -0
  78. package/dist/sub-languages/projection/CodeActionProvider.d.ts +18 -0
  79. package/dist/sub-languages/projection/CodeActionProvider.d.ts.map +1 -0
  80. package/dist/sub-languages/projection/CodeActionProvider.js +93 -0
  81. package/dist/sub-languages/projection/CodeActionProvider.js.map +1 -0
  82. package/dist/sub-languages/projection/CompletionProvider.d.ts +41 -0
  83. package/dist/sub-languages/projection/CompletionProvider.d.ts.map +1 -0
  84. package/dist/sub-languages/projection/CompletionProvider.js +591 -0
  85. package/dist/sub-languages/projection/CompletionProvider.js.map +1 -0
  86. package/dist/sub-languages/projection/HoverProvider.d.ts +24 -0
  87. package/dist/sub-languages/projection/HoverProvider.d.ts.map +1 -0
  88. package/dist/sub-languages/projection/HoverProvider.js +298 -0
  89. package/dist/sub-languages/projection/HoverProvider.js.map +1 -0
  90. package/dist/sub-languages/projection/Validator.d.ts +22 -0
  91. package/dist/sub-languages/projection/Validator.d.ts.map +1 -0
  92. package/dist/sub-languages/projection/Validator.js +339 -0
  93. package/dist/sub-languages/projection/Validator.js.map +1 -0
  94. package/dist/sub-languages/projection/index.d.ts +49 -0
  95. package/dist/sub-languages/projection/index.d.ts.map +1 -0
  96. package/dist/sub-languages/projection/index.js +160 -0
  97. package/dist/sub-languages/projection/index.js.map +1 -0
  98. package/dist/sub-languages/projection/language.d.ts +5 -0
  99. package/dist/sub-languages/projection/language.d.ts.map +1 -0
  100. package/dist/sub-languages/projection/language.js +171 -0
  101. package/dist/sub-languages/projection/language.js.map +1 -0
  102. package/dist/symbols.d.ts +45 -0
  103. package/dist/symbols.d.ts.map +1 -0
  104. package/dist/symbols.js +100 -0
  105. package/dist/symbols.js.map +1 -0
  106. package/dist/themes/screenplay-dark.d.ts +4 -0
  107. package/dist/themes/screenplay-dark.d.ts.map +1 -0
  108. package/dist/themes/screenplay-dark.js +29 -0
  109. package/dist/themes/screenplay-dark.js.map +1 -0
  110. package/dist/themes/screenplay-light.d.ts +4 -0
  111. package/dist/themes/screenplay-light.d.ts.map +1 -0
  112. package/dist/themes/screenplay-light.js +29 -0
  113. package/dist/themes/screenplay-light.js.map +1 -0
  114. package/dist/tokens.d.ts +5 -0
  115. package/dist/tokens.d.ts.map +1 -0
  116. package/dist/tokens.js +121 -0
  117. package/dist/tokens.js.map +1 -0
  118. package/dist/validation.d.ts +10 -0
  119. package/dist/validation.d.ts.map +1 -0
  120. package/dist/validation.js +101 -0
  121. package/dist/validation.js.map +1 -0
  122. package/document-context.ts +51 -0
  123. package/hover-content.ts +76 -0
  124. package/hover.ts +23 -0
  125. package/index.ts +98 -0
  126. package/keyword-docs.ts +102 -0
  127. package/language.ts +130 -0
  128. package/package.json +44 -0
  129. package/sub-language-registry.ts +42 -0
  130. package/sub-languages/capture/CompletionProvider.ts +365 -0
  131. package/sub-languages/capture/HoverProvider.ts +99 -0
  132. package/sub-languages/capture/Validator.ts +97 -0
  133. package/sub-languages/capture/index.ts +72 -0
  134. package/sub-languages/capture/language.ts +176 -0
  135. package/sub-languages/cdl.ts +76 -0
  136. package/sub-languages/pdl.ts +69 -0
  137. package/sub-languages/projection/CodeActionProvider.ts +123 -0
  138. package/sub-languages/projection/CompletionProvider.ts +653 -0
  139. package/sub-languages/projection/HoverProvider.ts +338 -0
  140. package/sub-languages/projection/Validator.ts +387 -0
  141. package/sub-languages/projection/index.ts +223 -0
  142. package/sub-languages/projection/language.ts +193 -0
  143. package/symbols.ts +161 -0
  144. package/themes/screenplay-dark.ts +32 -0
  145. package/themes/screenplay-light.ts +32 -0
  146. package/tokens.ts +145 -0
  147. package/validation.ts +145 -0
@@ -0,0 +1,101 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ import { primitiveTypes, sliceTypes } from './language';
4
+ import { fenceMap, indentOf } from './document-context';
5
+ import { knownEventNames, scanDocument } from './symbols';
6
+ function issue(severity, line, startColumn, length, message) {
7
+ return { severity, message, line, startColumn, endColumn: startColumn + length };
8
+ }
9
+ function tokenIssue(severity, line, text, token, message) {
10
+ const column = text.indexOf(token) + 1;
11
+ return issue(severity, line, column, token.length, message);
12
+ }
13
+ // Validates a Screenplay document without any editor dependency — both the Monaco
14
+ // service and the VSCode extension adapt these issues to their marker/diagnostic APIs.
15
+ export function validateLines(lines) {
16
+ const fences = fenceMap(lines);
17
+ const symbols = scanDocument(lines);
18
+ const events = new Set(knownEventNames(symbols));
19
+ const policies = new Set(symbols.policies.map((policy) => policy.name));
20
+ const issues = [];
21
+ const checkEvent = (line, text, name) => {
22
+ if (!events.has(name)) {
23
+ issues.push(tokenIssue('warning', line, text, name, `Unknown event type '${name}' — declare it in a slice or import it.`));
24
+ }
25
+ };
26
+ let authorizeIndent = -1;
27
+ for (let index = 0; index < lines.length; index++) {
28
+ const line = lines[index];
29
+ const trimmed = line.trim();
30
+ if (fences[index] || trimmed.length === 0)
31
+ continue;
32
+ const leading = line.match(/^[ ]*(\t+)/);
33
+ if (leading) {
34
+ issues.push(issue('warning', index, leading[0].length - leading[1].length + 1, leading[1].length, 'Screenplay is indentation-based — use spaces, not tabs.'));
35
+ }
36
+ // Policy references continue on indented lines below an authorize clause.
37
+ if (authorizeIndent >= 0) {
38
+ if (indentOf(line) > authorizeIndent &&
39
+ /^(?:or\s+)?[A-Z]\w*(?:\s+or\s+[A-Z]\w*)*$/.test(trimmed)) {
40
+ for (const name of trimmed.split(/\s+/).filter((token) => token !== 'or')) {
41
+ if (!policies.has(name)) {
42
+ issues.push(tokenIssue('warning', index, line, name, `Unknown policy '${name}' — declare it with 'policy ${name}'.`));
43
+ }
44
+ }
45
+ continue;
46
+ }
47
+ authorizeIndent = -1;
48
+ }
49
+ const slice = trimmed.match(/^slice\s+(\w+)/);
50
+ if (slice && !sliceTypes.includes(slice[1])) {
51
+ issues.push(tokenIssue('error', index, line, slice[1], `Unknown slice type '${slice[1]}' — expected ${sliceTypes.join(', ')}.`));
52
+ }
53
+ const concept = trimmed.match(/^concept\s+\w+\s*:\s*(\w+)/);
54
+ if (concept && concept[1] !== 'Enum' && !primitiveTypes.includes(concept[1])) {
55
+ issues.push(tokenIssue('error', index, line, concept[1], `Unknown primitive type '${concept[1]}' — expected ${primitiveTypes.join(', ')} or Enum.`));
56
+ }
57
+ const authorize = trimmed.match(/^authorize\s+(.*)$/);
58
+ if (authorize) {
59
+ authorizeIndent = indentOf(line);
60
+ for (const name of authorize[1].split(/\s+/).filter((token) => token !== 'or' && token.length > 0)) {
61
+ if (!policies.has(name)) {
62
+ issues.push(tokenIssue('warning', index, line, name, `Unknown policy '${name}' — declare it with 'policy ${name}'.`));
63
+ }
64
+ }
65
+ }
66
+ const reactsOn = trimmed.match(/^on\s+([A-Z]\w*)\s*$/);
67
+ if (reactsOn)
68
+ checkEvent(index, line, reactsOn[1]);
69
+ const produces = trimmed.match(/^produces\s+([A-Z]\w*)\s*$/);
70
+ if (produces)
71
+ checkEvent(index, line, produces[1]);
72
+ if (/^produces\s+when\b/.test(trimmed)) {
73
+ for (let next = index + 1; next < lines.length; next++) {
74
+ const candidate = lines[next];
75
+ if (fences[next] || candidate.trim().length === 0)
76
+ continue;
77
+ if (indentOf(candidate) > indentOf(line)) {
78
+ const name = candidate.trim().match(/^([A-Z]\w*)\s*$/);
79
+ if (name)
80
+ checkEvent(next, candidate, name[1]);
81
+ }
82
+ break;
83
+ }
84
+ }
85
+ const uniqueEvent = trimmed.match(/^unique\s+event\s+([A-Z]\w*)/);
86
+ if (uniqueEvent)
87
+ checkEvent(index, line, uniqueEvent[1]);
88
+ const uniqueProperty = trimmed.match(/^unique\s+[a-z_]\w*\s+on\s+([A-Z]\w*)/);
89
+ if (uniqueProperty)
90
+ checkEvent(index, line, uniqueProperty[1]);
91
+ }
92
+ const fenceLines = lines
93
+ .map((line, index) => ({ line, index }))
94
+ .filter(({ line }) => /^\s*```\s*$/.test(line));
95
+ if (fenceLines.length % 2 === 1) {
96
+ const last = fenceLines[fenceLines.length - 1];
97
+ issues.push(issue('error', last.index, 1, last.line.length + 1, 'Unclosed inline code block — expected a closing ``` line.'));
98
+ }
99
+ return issues;
100
+ }
101
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export function indentOf(line: string): number {
5
+ return line.length - line.trimStart().length;
6
+ }
7
+
8
+ export function firstWord(line: string): string {
9
+ return line.trim().split(/\s+/)[0] ?? '';
10
+ }
11
+
12
+ // Marks every line that is a code fence or lives inside one, so structural
13
+ // scanning never mistakes inline C#/TypeScript/HTML for Screenplay.
14
+ export function fenceMap(lines: string[]): boolean[] {
15
+ const map: boolean[] = new Array(lines.length).fill(false);
16
+ let open = false;
17
+ for (let index = 0; index < lines.length; index++) {
18
+ if (/^\s*```\s*$/.test(lines[index])) {
19
+ map[index] = true;
20
+ open = !open;
21
+ continue;
22
+ }
23
+ map[index] = open;
24
+ }
25
+ return map;
26
+ }
27
+
28
+ // Walks upward from a position and returns the chain of enclosing block openers,
29
+ // innermost first — e.g. ['command', 'slice', 'feature', 'module']. A block opener
30
+ // is any less-indented line above; its first word names the construct (for layout
31
+ // slots this is the slot name, which callers treat as an unknown construct).
32
+ export function enclosingChain(
33
+ lines: string[],
34
+ fences: boolean[],
35
+ lineIndex: number,
36
+ indent: number,
37
+ ): string[] {
38
+ const chain: string[] = [];
39
+ let currentIndent = indent;
40
+ for (let index = lineIndex - 1; index >= 0 && currentIndent > 0; index--) {
41
+ if (fences[index]) continue;
42
+ const line = lines[index];
43
+ if (line.trim().length === 0) continue;
44
+ const lineIndent = indentOf(line);
45
+ if (lineIndent < currentIndent) {
46
+ chain.push(firstWord(line));
47
+ currentIndent = lineIndent;
48
+ }
49
+ }
50
+ return chain;
51
+ }
@@ -0,0 +1,76 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { enclosingChain, fenceMap, indentOf } from './document-context';
5
+ import { scanDocument } from './symbols';
6
+ import { getSubLanguage } from './sub-language-registry';
7
+ import { attributeDocs, contextVariableDocs, keywordDocs } from './keyword-docs';
8
+
9
+ // Produces the hover markdown for a word at a position, without any editor
10
+ // dependency — the Monaco service and the VSCode extension share this content.
11
+ // Columns are 1-based, matching both editors' word-at-position APIs.
12
+ export function hoverContent(
13
+ lines: string[],
14
+ lineIndex: number,
15
+ word: string,
16
+ startColumn: number,
17
+ endColumn: number,
18
+ ): string | null {
19
+ const fences = fenceMap(lines);
20
+ if (fences[lineIndex]) return null;
21
+
22
+ const line = lines[lineIndex] ?? '';
23
+ const before = line.charAt(startColumn - 2);
24
+
25
+ if (before === '@') {
26
+ const doc = attributeDocs[word];
27
+ if (doc) return doc;
28
+ }
29
+ if (before === '$' || before === '.') {
30
+ const variable = line.substring(0, endColumn - 1).match(/\$[\w.]*$/)?.[0];
31
+ if (variable) {
32
+ const doc =
33
+ contextVariableDocs[variable] ??
34
+ (variable.startsWith('$env') ? contextVariableDocs['$env'] : undefined);
35
+ if (doc) return doc;
36
+ }
37
+ }
38
+
39
+ const symbols = scanDocument(lines);
40
+
41
+ const concept = symbols.concepts.find((candidate) => candidate.name === word);
42
+ if (concept) {
43
+ const attributes = concept.attributes.length ? ` ${concept.attributes.join(' ')}` : '';
44
+ const values = concept.enumValues.length
45
+ ? `\n\nValues: ${concept.enumValues.join(', ')}`
46
+ : '';
47
+ return `\`\`\`screenplay\nconcept ${concept.name} : ${concept.primitive}${attributes}\n\`\`\`${values}`;
48
+ }
49
+
50
+ const policy = symbols.policies.find((candidate) => candidate.name === word);
51
+ if (policy) {
52
+ const body = policy.requires.length ? policy.requires.join('\n') : '(custom C#)';
53
+ return `\`\`\`screenplay\npolicy ${policy.name}\n${body}\n\`\`\``;
54
+ }
55
+
56
+ const event = symbols.events.find((candidate) => candidate.name === word);
57
+ if (event) {
58
+ const properties = event.properties
59
+ .map((property) => `${property.name} ${property.type}`)
60
+ .join('\n');
61
+ return `\`\`\`screenplay\nevent ${event.name}\n${properties}\n\`\`\``;
62
+ }
63
+
64
+ // Sub-language keywords take precedence inside their construct.
65
+ const chain = enclosingChain(lines, fences, lineIndex, indentOf(line));
66
+ for (const construct of [line.trim().split(/\s+/)[0], ...chain]) {
67
+ const subLanguage = getSubLanguage(construct ?? '');
68
+ const doc = subLanguage?.hovers?.[word];
69
+ if (doc) return doc;
70
+ }
71
+
72
+ const keywordDoc = keywordDocs[word];
73
+ if (keywordDoc) return `**${word}** — ${keywordDoc}`;
74
+
75
+ return null;
76
+ }
package/hover.ts ADDED
@@ -0,0 +1,23 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import type { languages } from 'monaco-editor';
5
+ import { hoverContent } from './hover-content';
6
+
7
+ export function createHoverProvider(): languages.HoverProvider {
8
+ return {
9
+ provideHover(model, position) {
10
+ const word = model.getWordAtPosition(position);
11
+ if (!word) return null;
12
+
13
+ const content = hoverContent(
14
+ model.getLinesContent(),
15
+ position.lineNumber - 1,
16
+ word.word,
17
+ word.startColumn,
18
+ word.endColumn,
19
+ );
20
+ return content ? { contents: [{ value: content }] } : null;
21
+ },
22
+ };
23
+ }
package/index.ts ADDED
@@ -0,0 +1,98 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import {
5
+ Monaco,
6
+ languageConfiguration,
7
+ languageExtensionPoint,
8
+ languageId,
9
+ } from './language';
10
+ import { createTokensProvider } from './tokens';
11
+ import { createCompletionProvider } from './completions';
12
+ import { createHoverProvider } from './hover';
13
+ import { attachDiagnostics } from './diagnostics';
14
+ import {
15
+ getSubLanguage,
16
+ getSubLanguages,
17
+ onSubLanguagesChanged,
18
+ registerSubLanguage,
19
+ } from './sub-language-registry';
20
+ import { pdl } from './sub-languages/pdl';
21
+ import { cdl } from './sub-languages/cdl';
22
+ import { screenplayDark, screenplayDarkThemeName } from './themes/screenplay-dark';
23
+ import { screenplayLight, screenplayLightThemeName } from './themes/screenplay-light';
24
+
25
+ const registeredInstances = new Set<Monaco>();
26
+
27
+ function applyTokensProvider(monaco: Monaco): void {
28
+ monaco.languages.setMonarchTokensProvider(languageId, createTokensProvider(getSubLanguages()));
29
+ }
30
+
31
+ // Sub-languages registered after register() recompose the tokenizer on the fly.
32
+ onSubLanguagesChanged(() => registeredInstances.forEach(applyTokensProvider));
33
+
34
+ // Registers the built-in PDL and CDL sub-languages. Hosts that do not go through
35
+ // register() — such as the VSCode extension — call this before using the registry.
36
+ export function ensureBuiltInSubLanguages(): void {
37
+ if (!getSubLanguage('projection')) registerSubLanguage('projection', pdl);
38
+ if (!getSubLanguage('capture')) registerSubLanguage('capture', cdl);
39
+ }
40
+
41
+ export function register(monaco: Monaco): void {
42
+ if (registeredInstances.has(monaco)) return;
43
+
44
+ ensureBuiltInSubLanguages();
45
+
46
+ registeredInstances.add(monaco);
47
+
48
+ monaco.languages.register(languageExtensionPoint);
49
+ monaco.languages.setLanguageConfiguration(languageId, languageConfiguration);
50
+ applyTokensProvider(monaco);
51
+ monaco.languages.registerCompletionItemProvider(languageId, createCompletionProvider(monaco));
52
+ monaco.languages.registerHoverProvider(languageId, createHoverProvider());
53
+ monaco.editor.defineTheme(screenplayDarkThemeName, screenplayDark);
54
+ monaco.editor.defineTheme(screenplayLightThemeName, screenplayLight);
55
+ attachDiagnostics(monaco);
56
+ }
57
+
58
+ export {
59
+ clauseKeywords,
60
+ codeBlockTags,
61
+ conceptAttributes,
62
+ constructKeywords,
63
+ languageId,
64
+ primitiveTypes,
65
+ sliceTypes,
66
+ } from './language';
67
+ export type { Monaco } from './language';
68
+ export { getSubLanguage, getSubLanguages, registerSubLanguage } from './sub-language-registry';
69
+ export type {
70
+ MonarchTokenRules,
71
+ SubLanguage,
72
+ SubLanguageCompletion,
73
+ SubLanguageDefinition,
74
+ } from './sub-language-registry';
75
+ export { pdl } from './sub-languages/pdl';
76
+ export { cdl } from './sub-languages/cdl';
77
+ export { screenplayDarkThemeName } from './themes/screenplay-dark';
78
+ export { screenplayLightThemeName } from './themes/screenplay-light';
79
+ export { enclosingChain, fenceMap, firstWord, indentOf } from './document-context';
80
+ export { knownEventNames, scanDocument } from './symbols';
81
+ export type {
82
+ ConceptSymbol,
83
+ DocumentSymbols,
84
+ EventSymbol,
85
+ ImportSymbol,
86
+ NamedSymbol,
87
+ PolicySymbol,
88
+ PropertySymbol,
89
+ QuerySymbol,
90
+ } from './symbols';
91
+ export { attributeDocs, contextVariableDocs, keywordDocs } from './keyword-docs';
92
+ export { contextVariableItems, producesItems } from './completion-items';
93
+ export type { CompletionEntry } from './completion-items';
94
+ export { completionEntriesFor, planCompletions } from './completion-planner';
95
+ export type { CompletionPlan } from './completion-planner';
96
+ export { hoverContent } from './hover-content';
97
+ export { validateLines } from './validation';
98
+ export type { ValidationIssue, ValidationSeverity } from './validation';
@@ -0,0 +1,102 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export const keywordDocs: Record<string, string> = {
5
+ domain: 'The domain the file belongs to — optional, at most one per file, before everything else.',
6
+ import: 'Imports a type from another module; it becomes available by its short name.',
7
+ concept: 'A formalized value type wrapping a primitive. Attributes such as `@pii` travel with every usage.',
8
+ policy: 'A named authorization rule referenced by commands and queries. Multiple policies AND together.',
9
+ persona: 'A named role interacting with the application, with an optional description and its associated policies.',
10
+ authentication: 'Declares the identity providers of the application — at most one block per file.',
11
+ provider: 'A named identity provider within `authentication`, with free-form `name value` settings.',
12
+ description: 'A human-readable description of a module, feature, slice, persona, or command — the first body line, as a quoted single line or a fenced ``` block for multiple lines.',
13
+ module: 'The top-level namespace — maps to a bounded context.',
14
+ layout: 'A reusable screen template with named slots.',
15
+ template: 'Declares the named slots of a layout.',
16
+ feature: 'A vertical slice grouping. Features nest arbitrarily deep.',
17
+ slice: 'The atomic unit of behavior, aligned with Event Modeling. Has a type and a name.',
18
+ event: 'An event type — an immutable, past-tense fact. Properties use concepts or primitives.',
19
+ command: 'An imperative intent. Declares authorization, validation, and what events it produces — declaratively, or via a full handler.',
20
+ query: 'A read-side entry point mapping to a return type.',
21
+ projection: 'Declares how events project into a read model, using the embedded Projection Declaration Language (PDL).',
22
+ capture: 'Converts external data into events, using the embedded Change Data Capture Language (CDL).',
23
+ reactor: 'Reacts to events and produces side effects. Lives inside Automation slices.',
24
+ screen: 'A UI declaration. Supports intent, structure, and layout-with-code levels, or a full file reference.',
25
+ constraint: 'A server-side rule enforced in the Chronicle kernel before events are committed.',
26
+ authorize: 'References the policies that must all pass for the construct to execute.',
27
+ validate: 'Declarative validation rules, or `validate csharp` for imperative rules — on commands and concepts.',
28
+ produces: 'Declares the events a command emits — single, multiple, or conditional.',
29
+ handler: 'A fully imperative command implementation — a `file <Path>` reference or an inline `csharp` block, instead of `produces`.',
30
+ when: 'Guards a produced event or a capture append with a condition.',
31
+ require: 'A policy condition: `authenticated`, `role "..."`, or `claim "..." matches ...`.',
32
+ authenticated: 'Requires an authenticated caller.',
33
+ role: 'Requires the caller to have the given role.',
34
+ claim: 'Requires a claim on the caller to match a subject or value.',
35
+ subject: 'The subject (identity) of the caller.',
36
+ data: 'Binds a read model to a screen through a query.',
37
+ action: 'Makes a command available as an action on a screen.',
38
+ navigate: 'Navigates to a screen, optionally passing a parameter with `by`.',
39
+ section: 'A named structural section of a screen.',
40
+ table: 'A table widget over a read model or child collection.',
41
+ summary: 'A summary widget showing labeled fields.',
42
+ column: 'A table column bound to a property.',
43
+ field: 'A summary field bound to a property.',
44
+ title: 'The display title of a screen or section.',
45
+ label: 'The display label of an action, column, or field.',
46
+ unique: 'A uniqueness constraint — `unique <property> on <EventType>` or `unique event <EventType>`.',
47
+ concurrency: 'The concurrency scope enforced when the command appends events — dimensions: `eventSource`, `sourceType`, `streamType`, `streamId`, `events`.',
48
+ eventSource: 'Concurrency dimension — scope the check to the event source id of the command.',
49
+ sourceType: 'Concurrency dimension — scope the check to an event source type.',
50
+ streamType: 'Concurrency dimension — scope the check to an event stream type.',
51
+ streamId: 'Concurrency dimension — scope the check to an event stream id.',
52
+ tag: 'Attaches a tag to appended events — a static identifier or string, or a `$context.` expression resolved at append time.',
53
+ seed: 'Declares events to seed into the event store per event source id — multiple blocks accumulate.',
54
+ for: 'Introduces a seed group — the events to seed for one event source id.',
55
+ readmodel: 'Read model state in a specification — `given readmodel` establishes it, `then readmodel` asserts it.',
56
+ file: 'Delegates the implementation to an external file; the Screenplay contract stays visible.',
57
+ by: 'Introduces the identifying parameter.',
58
+ via: 'Connects screen data to the query that supplies it.',
59
+ filter: 'An optional query filter parameter.',
60
+ on: 'The event a reactor or constraint applies to, or a widget interaction such as `on row-click`.',
61
+ message: 'The validation message reported when the rule fails.',
62
+ matches: 'Matches a value against a regular expression or a named pattern such as `email`.',
63
+ all: 'Applies a comparison to every element of a collection.',
64
+ max: 'Maximum length or value.',
65
+ min: 'Minimum length or value.',
66
+ length: 'Constrains the exact length of a value.',
67
+ today: 'The current date.',
68
+ empty: 'Used with `not empty` — the value must be present.',
69
+ not: 'Negates a validation condition, as in `not empty`.',
70
+ and: 'Both conditions must hold.',
71
+ or: 'Either condition may hold.',
72
+ csharp: 'An inline C# block between triple backticks.',
73
+ typescript: 'An inline TypeScript block between triple backticks.',
74
+ react: 'An inline React/TSX block; receives the surrounding data contract as `Props`.',
75
+ html: 'An inline static HTML block.',
76
+ StateChange: 'Slice type — a command → events flow; something that changes the system.',
77
+ StateView: 'Slice type — a query + projection + screen; something that reads the system.',
78
+ Automation: 'Slice type — a reactor or reducer; something that reacts to events.',
79
+ Translate: 'Slice type — a capture; converts external data into events.',
80
+ Uuid: 'Primitive type — a universally unique identifier.',
81
+ String: 'Primitive type — a string of characters.',
82
+ Int: 'Primitive type — an integer number.',
83
+ Decimal: 'Primitive type — a decimal number.',
84
+ Bool: 'Primitive type — true or false.',
85
+ Date: 'Primitive type — a date without time.',
86
+ DateTime: 'Primitive type — a date and time.',
87
+ Enum: 'An enumeration concept with a fixed set of values.',
88
+ };
89
+
90
+ export const attributeDocs: Record<string, string> = {
91
+ pii: '`@pii` — the value is personally identifiable information; Chronicle manages and erases it automatically wherever the concept is used.',
92
+ sensitive: '`@sensitive` — the value is sensitive; Chronicle applies its sensitivity rules automatically wherever the concept is used.',
93
+ };
94
+
95
+ export const contextVariableDocs: Record<string, string> = {
96
+ '$context.occurred': 'The timestamp of the event.',
97
+ '$context.identity.id': 'The subject of the caller from the auth token.',
98
+ '$env': 'An environment variable, e.g. `$env.SERVICE_NAME`.',
99
+ '$secrets': 'An encrypted secret resolved at runtime, e.g. `$secrets.azureAdClientId` — stays symbolic in the compiled tree.',
100
+ '$strings': 'A localized string resolved from the `.strings` file of the active locale, e.g. `$strings.invoices.title`.',
101
+ '$eventContext.occurred': 'The timestamp of the event being projected.',
102
+ };
package/language.ts ADDED
@@ -0,0 +1,130 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import type { languages } from 'monaco-editor';
5
+
6
+ export type Monaco = typeof import('monaco-editor');
7
+
8
+ export const languageId = 'screenplay';
9
+
10
+ export const languageExtensionPoint: languages.ILanguageExtensionPoint = {
11
+ id: languageId,
12
+ extensions: ['.play'],
13
+ aliases: ['Screenplay', 'screenplay', 'play'],
14
+ mimetypes: ['text/x-screenplay'],
15
+ };
16
+
17
+ export const constructKeywords = [
18
+ 'domain',
19
+ 'import',
20
+ 'concept',
21
+ 'policy',
22
+ 'persona',
23
+ 'authentication',
24
+ 'module',
25
+ 'layout',
26
+ 'feature',
27
+ 'slice',
28
+ 'event',
29
+ 'command',
30
+ 'query',
31
+ 'reactor',
32
+ 'screen',
33
+ 'constraint',
34
+ 'specification',
35
+ 'seed',
36
+ ];
37
+
38
+ export const clauseKeywords = [
39
+ 'description',
40
+ 'template',
41
+ 'require',
42
+ 'authenticated',
43
+ 'role',
44
+ 'claim',
45
+ 'subject',
46
+ 'authorize',
47
+ 'validate',
48
+ 'produces',
49
+ 'handler',
50
+ 'when',
51
+ 'given',
52
+ 'then',
53
+ 'error',
54
+ 'message',
55
+ 'not',
56
+ 'empty',
57
+ 'matches',
58
+ 'all',
59
+ 'max',
60
+ 'min',
61
+ 'length',
62
+ 'today',
63
+ 'true',
64
+ 'false',
65
+ 'and',
66
+ 'or',
67
+ 'by',
68
+ 'filter',
69
+ 'data',
70
+ 'via',
71
+ 'action',
72
+ 'navigate',
73
+ 'to',
74
+ 'label',
75
+ 'section',
76
+ 'table',
77
+ 'summary',
78
+ 'title',
79
+ 'column',
80
+ 'field',
81
+ 'on',
82
+ 'unique',
83
+ 'file',
84
+ 'concurrency',
85
+ 'eventSource',
86
+ 'sourceType',
87
+ 'streamType',
88
+ 'streamId',
89
+ 'tag',
90
+ 'for',
91
+ 'readmodel',
92
+ 'provider',
93
+ ];
94
+
95
+ export const codeBlockTags = ['csharp', 'typescript', 'react', 'html'];
96
+
97
+ export const sliceTypes = ['StateChange', 'StateView', 'Automation', 'Translate'];
98
+
99
+ export const primitiveTypes = ['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime'];
100
+
101
+ export const conceptAttributes = ['@pii', '@sensitive'];
102
+
103
+ export const languageConfiguration: languages.LanguageConfiguration = {
104
+ comments: {
105
+ lineComment: '//',
106
+ },
107
+ brackets: [
108
+ ['(', ')'],
109
+ ['[', ']'],
110
+ ],
111
+ autoClosingPairs: [
112
+ { open: '(', close: ')' },
113
+ { open: '[', close: ']' },
114
+ { open: '"', close: '"' },
115
+ ],
116
+ surroundingPairs: [
117
+ { open: '(', close: ')' },
118
+ { open: '[', close: ']' },
119
+ { open: '"', close: '"' },
120
+ ],
121
+ folding: {
122
+ offSide: true,
123
+ },
124
+ indentationRules: {
125
+ increaseIndentPattern:
126
+ /^\s*(module|feature|slice|policy|persona|authentication|provider|event|command|screen|projection|capture|reactor|constraint|layout|template|validate|produces|handler|section|concurrency|seed|for)\b.*$/,
127
+ // Dedents are always explicit in an offside language — never auto-dedent.
128
+ decreaseIndentPattern: /(?!)/,
129
+ },
130
+ };
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@cratis/screenplay-language",
3
+ "version": "0.1.0",
4
+ "description": "Monaco language service for the Cratis Screenplay DSL — syntax highlighting, IntelliSense, hover and diagnostics for .play files",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ },
18
+ "./capture": {
19
+ "types": "./dist/sub-languages/capture/index.d.ts",
20
+ "import": "./dist/sub-languages/capture/index.js"
21
+ },
22
+ "./projection": {
23
+ "types": "./dist/sub-languages/projection/index.d.ts",
24
+ "import": "./dist/sub-languages/projection/index.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "**/*.ts"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsc -p tsconfig.json",
33
+ "compile": "tsc --noEmit -p tsconfig.json",
34
+ "lint": "yarn g:lint",
35
+ "lint:ci": "yarn g:lint:ci"
36
+ },
37
+ "peerDependencies": {
38
+ "monaco-editor": ">=0.44.0"
39
+ },
40
+ "devDependencies": {
41
+ "monaco-editor": "^0.55.1",
42
+ "typescript": "6.0.3"
43
+ }
44
+ }