@koi-language/koi 1.0.5 → 1.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.
- package/README.md +4 -125
- package/examples/.build/agent-dialogue.ts +138 -0
- package/examples/.build/agent-dialogue.ts.map +1 -0
- package/examples/.build/chess.ts +77 -0
- package/examples/.build/chess.ts.map +1 -0
- package/examples/.build/delegation-test.ts +140 -0
- package/examples/.build/delegation-test.ts.map +1 -0
- package/examples/.build/dialog-demo.ts +77 -0
- package/examples/.build/dialog-demo.ts.map +1 -0
- package/examples/.build/hello-world.ts +77 -0
- package/examples/.build/hello-world.ts.map +1 -0
- package/examples/.build/lover-dialog-demo.ts +77 -0
- package/examples/.build/lover-dialog-demo.ts.map +1 -0
- package/examples/.build/package.json +3 -0
- package/examples/.build/registry-interactive-demo.ts +202 -0
- package/examples/.build/registry-interactive-demo.ts.map +1 -0
- package/examples/.build/registry-playbook-demo.ts +201 -0
- package/examples/.build/registry-playbook-demo.ts.map +1 -0
- package/examples/.build/tic-tac-toe.ts +77 -0
- package/examples/.build/tic-tac-toe.ts.map +1 -0
- package/examples/actions-demo.koi +8 -9
- package/examples/activists-dialogue.koi +75 -0
- package/examples/agent-dialogue.koi +66 -0
- package/examples/chess.koi +19 -0
- package/examples/counter.koi +20 -69
- package/examples/delegation-test.koi +16 -18
- package/examples/dialog-demo.koi +20 -0
- package/examples/hello-world.koi +7 -43
- package/examples/mcp-stdio-demo.koi +29 -0
- package/examples/memory-test.koi +49 -0
- package/examples/mobile-mcp-demo.koi +32 -0
- package/examples/multi-event-handler-test.koi +16 -18
- package/examples/pipeline.koi +15 -17
- package/examples/prompt-demo.koi +20 -0
- package/examples/{registry-playbook-email-compositor.koi → registry-interactive-demo.koi} +27 -27
- package/examples/registry-playbook-demo.koi +28 -28
- package/examples/skill-import-test.koi +7 -9
- package/examples/skills/.build/math-operations.ts +1656 -0
- package/examples/skills/.build/math-operations.ts.map +1 -0
- package/examples/skills/.build/package.json +3 -0
- package/examples/skills/.build/string-operations.ts +1643 -0
- package/examples/skills/.build/string-operations.ts.map +1 -0
- package/examples/skills/advanced/.build/index.ts +3223 -0
- package/examples/skills/advanced/.build/index.ts.map +1 -0
- package/examples/skills/advanced/.build/package.json +3 -0
- package/examples/skills/advanced/index.koi +3 -5
- package/examples/skills/math-operations.koi +1 -3
- package/examples/skills/string-operations.koi +1 -3
- package/examples/tic-tac-toe.koi +19 -0
- package/examples/utils/echo-mcp-server.js +141 -0
- package/examples/web-delegation-demo.koi +15 -17
- package/package.json +2 -1
- package/src/cli/koi.js +30 -41
- package/src/compiler/build-optimizer.js +204 -289
- package/src/compiler/cache-manager.js +1 -1
- package/src/compiler/import-resolver.js +5 -9
- package/src/compiler/parser.js +6072 -3476
- package/src/compiler/transpiler.js +346 -38
- package/src/grammar/koi.pegjs +302 -62
- package/src/runtime/actions/{format.js → call-llm.js} +37 -44
- package/src/runtime/actions/call-mcp.js +97 -0
- package/src/runtime/actions/if.js +179 -0
- package/src/runtime/actions/print.js +3 -1
- package/src/runtime/actions/prompt-user.js +75 -0
- package/src/runtime/actions/repeat.js +147 -0
- package/src/runtime/actions/shell.js +185 -0
- package/src/runtime/actions/while.js +205 -0
- package/src/runtime/agent.js +592 -178
- package/src/runtime/cli-display.js +26 -0
- package/src/runtime/cli-input.js +421 -0
- package/src/runtime/cli-logger.js +2 -5
- package/src/runtime/cli-markdown.js +61 -0
- package/src/runtime/cli-select.js +106 -0
- package/src/runtime/incremental-json-parser.js +51 -17
- package/src/runtime/index.js +1 -0
- package/src/runtime/llm-provider.js +1083 -572
- package/src/runtime/mcp-registry.js +141 -0
- package/src/runtime/mcp-stdio-client.js +334 -0
- package/src/runtime/planner.js +1 -1
- package/src/runtime/playbook-session.js +259 -0
- package/src/runtime/registry-backends/keyv-sqlite.js +1 -1
- package/src/runtime/registry-backends/local.js +1 -1
- package/src/runtime/router.js +22 -26
- package/src/runtime/runtime.js +7 -1
- package/examples/cache-test.koi +0 -29
- package/examples/calculator.koi +0 -61
- package/examples/clear-registry.js +0 -33
- package/examples/clear-registry.koi +0 -30
- package/examples/code-introspection-test.koi +0 -149
- package/examples/directory-import-test.koi +0 -84
- package/examples/hello-world-claude.koi +0 -52
- package/examples/hello.koi +0 -24
- package/examples/mcp-example.koi +0 -70
- package/examples/new-import-test.koi +0 -89
- package/examples/registry-demo.koi +0 -184
- package/examples/registry-playbook-email-compositor-2.koi +0 -140
- package/examples/sentiment.koi +0 -90
- package/examples/simple.koi +0 -48
- package/examples/task-chaining-demo.koi +0 -244
- package/examples/test-await.koi +0 -22
- package/examples/test-crypto-sha256.koi +0 -196
- package/examples/test-delegation.koi +0 -41
- package/examples/test-multi-team-routing.koi +0 -258
- package/examples/test-no-handler.koi +0 -35
- package/examples/test-npm-import.koi +0 -67
- package/examples/test-parse.koi +0 -10
- package/examples/test-peers-with-team.koi +0 -59
- package/examples/test-permissions-fail.koi +0 -20
- package/examples/test-permissions.koi +0 -36
- package/examples/test-simple-registry.koi +0 -31
- package/examples/test-typescript-import.koi +0 -64
- package/examples/test-uses-team-syntax.koi +0 -25
- package/examples/test-uses-team.koi +0 -31
package/src/grammar/koi.pegjs
CHANGED
|
@@ -28,29 +28,20 @@ Program
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
Declaration
|
|
31
|
-
=
|
|
32
|
-
/ ImportDecl
|
|
31
|
+
= ImportDecl
|
|
33
32
|
/ RoleDecl
|
|
34
33
|
/ TeamDecl
|
|
35
34
|
/ AgentDecl
|
|
36
35
|
/ SkillDecl
|
|
36
|
+
/ MCPDecl
|
|
37
37
|
/ RunStatement
|
|
38
38
|
|
|
39
|
-
// ============================================================
|
|
40
|
-
// Package
|
|
41
|
-
// ============================================================
|
|
42
|
-
|
|
43
|
-
PackageDecl
|
|
44
|
-
= "package"i _ name:StringLiteral _ {
|
|
45
|
-
return { type: 'PackageDecl', name, location: location() };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
39
|
// ============================================================
|
|
49
40
|
// Import (TypeScript/JavaScript style)
|
|
50
41
|
// ============================================================
|
|
51
42
|
|
|
52
43
|
ImportDecl
|
|
53
|
-
= "import"
|
|
44
|
+
= "import" _ name:StringLiteral _ {
|
|
54
45
|
return { type: 'ImportDecl', what: 'module', name, location: location() };
|
|
55
46
|
}
|
|
56
47
|
|
|
@@ -59,7 +50,7 @@ ImportDecl
|
|
|
59
50
|
// ============================================================
|
|
60
51
|
|
|
61
52
|
RoleDecl
|
|
62
|
-
= "role"
|
|
53
|
+
= "role" _ name:Identifier _ "{" _ caps:RoleCapabilities _ "}" _ {
|
|
63
54
|
return { type: 'RoleDecl', name, capabilities: caps, location: location() };
|
|
64
55
|
}
|
|
65
56
|
|
|
@@ -69,7 +60,7 @@ RoleCapabilities
|
|
|
69
60
|
}
|
|
70
61
|
|
|
71
62
|
RoleCapability
|
|
72
|
-
= "can"
|
|
63
|
+
= "can" _ name:Identifier {
|
|
73
64
|
return { type: 'Capability', name, location: location() };
|
|
74
65
|
}
|
|
75
66
|
|
|
@@ -78,12 +69,12 @@ RoleCapability
|
|
|
78
69
|
// ============================================================
|
|
79
70
|
|
|
80
71
|
TeamDecl
|
|
81
|
-
= "
|
|
72
|
+
= "team" _ name:Identifier _ override:TeamOverride? _ "{" _ members:TeamMembers _ "}" _ {
|
|
82
73
|
return { type: 'TeamDecl', name, override, members, location: location() };
|
|
83
74
|
}
|
|
84
75
|
|
|
85
76
|
TeamOverride
|
|
86
|
-
= "override"
|
|
77
|
+
= "override" _ "{" _ overrides:TeamMembers _ "}" {
|
|
87
78
|
return overrides;
|
|
88
79
|
}
|
|
89
80
|
|
|
@@ -93,16 +84,25 @@ TeamMembers
|
|
|
93
84
|
}
|
|
94
85
|
|
|
95
86
|
TeamMember
|
|
96
|
-
= name:Identifier _ "=" _ value:(MCPAddress / StringLiteral / Identifier) _ {
|
|
87
|
+
= name:Identifier _ (":" / "=") _ value:(MCPAddress / StringLiteral / Identifier) _ {
|
|
97
88
|
return { name, value, location: location() };
|
|
98
89
|
}
|
|
99
90
|
|
|
91
|
+
// ============================================================
|
|
92
|
+
// MCP (Model Context Protocol) server declaration
|
|
93
|
+
// ============================================================
|
|
94
|
+
|
|
95
|
+
MCPDecl
|
|
96
|
+
= "mcp" _ name:Identifier _ "=" _ config:ObjectLiteral _ {
|
|
97
|
+
return { type: 'MCPDecl', name, config, location: location() };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
100
|
// ============================================================
|
|
101
101
|
// Agent
|
|
102
102
|
// ============================================================
|
|
103
103
|
|
|
104
104
|
AgentDecl
|
|
105
|
-
= "
|
|
105
|
+
= "agent" _ name:Identifier _ ":" _ role:Identifier _ "{" _ body:AgentBody _ "}" _ {
|
|
106
106
|
return { type: 'AgentDecl', name, role, body, location: location() };
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -115,23 +115,35 @@ AgentBody
|
|
|
115
115
|
AgentBodyItem
|
|
116
116
|
= UsesSkill
|
|
117
117
|
/ UsesTeam
|
|
118
|
+
/ UsesMCP
|
|
118
119
|
/ LLMConfig
|
|
120
|
+
/ AmnesiaDecl
|
|
119
121
|
/ EventHandler
|
|
120
122
|
/ StateDecl
|
|
121
123
|
/ PlaybookDecl
|
|
122
124
|
/ ResilienceDecl
|
|
123
125
|
/ ExportFunction
|
|
124
126
|
|
|
127
|
+
AmnesiaDecl
|
|
128
|
+
= "amnesia" _ "=" _ value:BooleanLiteral _ {
|
|
129
|
+
return { type: 'AmnesiaDecl', value, location: location() };
|
|
130
|
+
}
|
|
131
|
+
|
|
125
132
|
UsesSkill
|
|
126
|
-
= "uses"
|
|
133
|
+
= "uses" _ "skill" _ names:IdentifierList _ {
|
|
127
134
|
return names.map(name => ({ type: 'UsesSkill', skill: name, location: location() }));
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
UsesTeam
|
|
131
|
-
= "uses"
|
|
138
|
+
= "uses" _ "team" _ names:IdentifierList _ {
|
|
132
139
|
return names.map(name => ({ type: 'UsesTeam', team: name, location: location() }));
|
|
133
140
|
}
|
|
134
141
|
|
|
142
|
+
UsesMCP
|
|
143
|
+
= "uses" _ "mcp" _ names:IdentifierList _ {
|
|
144
|
+
return names.map(name => ({ type: 'UsesMCP', mcp: name, location: location() }));
|
|
145
|
+
}
|
|
146
|
+
|
|
135
147
|
// Comma-separated list of identifiers
|
|
136
148
|
IdentifierList
|
|
137
149
|
= first:Identifier rest:(_ "," _ Identifier)* {
|
|
@@ -139,19 +151,19 @@ IdentifierList
|
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
LLMConfig
|
|
142
|
-
= "llm"
|
|
154
|
+
= "llm" _ "default" _ "=" _ config:ObjectLiteral _ {
|
|
143
155
|
return { type: 'LLMConfig', config, location: location() };
|
|
144
156
|
}
|
|
145
157
|
|
|
146
158
|
EventHandler
|
|
147
|
-
= "on"
|
|
159
|
+
= "on" _ event:HandlerName _ "(" _ params:Parameters? _ ")" _ "{" _ body:Statement* _ "}" _ {
|
|
148
160
|
return { type: 'EventHandler', event, params: params || [], body, location: location() };
|
|
149
161
|
}
|
|
150
162
|
|
|
151
163
|
HandlerName
|
|
152
164
|
= name:$([a-zA-Z_][a-zA-Z0-9_]*) &{
|
|
153
|
-
const reserved = ['run', '
|
|
154
|
-
'uses', 'llm', 'default', 'on', 'state', 'playbook', 'resilience',
|
|
165
|
+
const reserved = ['run', 'import', 'skill', 'role', 'can', 'team', 'agent',
|
|
166
|
+
'uses', 'llm', 'default', 'on', 'state', 'playbook', 'resilience', 'amnesia', 'mcp',
|
|
155
167
|
'export', 'async', 'function', 'var', 'const', 'let', 'if', 'else', 'for', 'of', 'in', 'while',
|
|
156
168
|
'return', 'await', 'send', 'timeout', 'use', 'override', 'affordance',
|
|
157
169
|
'true', 'false', 'null'];
|
|
@@ -165,7 +177,7 @@ HandlerName
|
|
|
165
177
|
}
|
|
166
178
|
|
|
167
179
|
StateDecl
|
|
168
|
-
= "state"
|
|
180
|
+
= "state" _ "{" _ fields:StateFields _ "}" _ {
|
|
169
181
|
return { type: 'StateDecl', fields, location: location() };
|
|
170
182
|
}
|
|
171
183
|
|
|
@@ -193,12 +205,12 @@ StateField
|
|
|
193
205
|
}
|
|
194
206
|
|
|
195
207
|
PlaybookDecl
|
|
196
|
-
= "playbook"
|
|
208
|
+
= "playbook" _ name:StringLiteral _ content:StringLiteral _ {
|
|
197
209
|
return { type: 'PlaybookDecl', name, content, location: location() };
|
|
198
210
|
}
|
|
199
211
|
|
|
200
212
|
ResilienceDecl
|
|
201
|
-
= "resilience"
|
|
213
|
+
= "resilience" _ name:StringLiteral _ "{" _ props:ResilienceProps _ "}" _ {
|
|
202
214
|
return { type: 'ResilienceDecl', name, properties: props, location: location() };
|
|
203
215
|
}
|
|
204
216
|
|
|
@@ -217,12 +229,14 @@ ResilienceProp
|
|
|
217
229
|
// ============================================================
|
|
218
230
|
|
|
219
231
|
SkillDecl
|
|
220
|
-
= "
|
|
221
|
-
// Extract affordance, functions, agents, teams from body
|
|
232
|
+
= "skill" _ name:Identifier _ "{" _ body:SkillBody _ "}" _ {
|
|
233
|
+
// Extract affordance, functions, agents, teams, constants, variables from body
|
|
222
234
|
const affordance = body.find(item => item.type === 'AffordanceDecl');
|
|
223
235
|
const functions = body.filter(item => item.type === 'ExportFunction');
|
|
224
236
|
const agents = body.filter(item => item.type === 'AgentDecl');
|
|
225
237
|
const teams = body.filter(item => item.type === 'TeamDecl');
|
|
238
|
+
const constants = body.filter(item => item.type === 'SkillConstDeclaration');
|
|
239
|
+
const variables = body.filter(item => item.type === 'SkillVariableDeclaration');
|
|
226
240
|
|
|
227
241
|
return {
|
|
228
242
|
type: 'SkillDecl',
|
|
@@ -231,6 +245,8 @@ SkillDecl
|
|
|
231
245
|
functions,
|
|
232
246
|
agents,
|
|
233
247
|
teams,
|
|
248
|
+
constants,
|
|
249
|
+
variables,
|
|
234
250
|
location: location()
|
|
235
251
|
};
|
|
236
252
|
}
|
|
@@ -244,15 +260,116 @@ SkillBodyItem
|
|
|
244
260
|
= AffordanceDecl
|
|
245
261
|
/ AgentDecl
|
|
246
262
|
/ TeamDecl
|
|
263
|
+
/ SkillConstDeclaration
|
|
264
|
+
/ SkillVariableDeclaration
|
|
247
265
|
/ ExportFunction
|
|
266
|
+
/ NonExportFunction
|
|
248
267
|
|
|
249
268
|
AffordanceDecl
|
|
250
|
-
= "affordance"
|
|
269
|
+
= "affordance" _ content:StringLiteral _ {
|
|
251
270
|
return { type: 'AffordanceDecl', content, location: location() };
|
|
252
271
|
}
|
|
253
272
|
|
|
273
|
+
SkillConstDeclaration
|
|
274
|
+
= "const"i _ pattern:DestructuringPattern _ typeAnnotation:(":" _ TypeAnnotation)? _ "=" _ value:Expression _ {
|
|
275
|
+
return {
|
|
276
|
+
type: 'SkillConstDeclaration',
|
|
277
|
+
pattern,
|
|
278
|
+
typeAnnotation: typeAnnotation ? typeAnnotation[2] : null,
|
|
279
|
+
value,
|
|
280
|
+
location: location()
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/ "const"i _ name:Identifier _ typeAnnotation:(":" _ TypeAnnotation)? _ "=" _ value:Expression _ {
|
|
284
|
+
return {
|
|
285
|
+
type: 'SkillConstDeclaration',
|
|
286
|
+
pattern: { type: 'Identifier', name: name.name },
|
|
287
|
+
typeAnnotation: typeAnnotation ? typeAnnotation[2] : null,
|
|
288
|
+
value,
|
|
289
|
+
location: location()
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
SkillVariableDeclaration
|
|
294
|
+
= "let"i _ pattern:DestructuringPattern _ typeAnnotation:(":" _ TypeAnnotation)? _ init:("=" _ Expression)? _ {
|
|
295
|
+
return {
|
|
296
|
+
type: 'SkillVariableDeclaration',
|
|
297
|
+
pattern,
|
|
298
|
+
typeAnnotation: typeAnnotation ? typeAnnotation[2] : null,
|
|
299
|
+
init: init ? init[2] : null,
|
|
300
|
+
location: location()
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/ "let"i _ name:Identifier _ typeAnnotation:(":" _ TypeAnnotation)? _ init:("=" _ Expression)? _ {
|
|
304
|
+
return {
|
|
305
|
+
type: 'SkillVariableDeclaration',
|
|
306
|
+
pattern: { type: 'Identifier', name: name.name },
|
|
307
|
+
typeAnnotation: typeAnnotation ? typeAnnotation[2] : null,
|
|
308
|
+
init: init ? init[2] : null,
|
|
309
|
+
location: location()
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
DestructuringPattern
|
|
314
|
+
= ObjectDestructuringPattern
|
|
315
|
+
/ ArrayDestructuringPattern
|
|
316
|
+
|
|
317
|
+
ObjectDestructuringPattern
|
|
318
|
+
= "{" _ props:DestructuringPropertyList _ "}" {
|
|
319
|
+
return { type: 'ObjectPattern', properties: props };
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
DestructuringPropertyList
|
|
323
|
+
= head:DestructuringProperty tail:(_ "," _ DestructuringProperty)* {
|
|
324
|
+
return [head, ...tail.map(t => t[3])];
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
DestructuringProperty
|
|
328
|
+
= key:Identifier _ ":" _ value:Identifier {
|
|
329
|
+
return { key: key.name, value: value.name };
|
|
330
|
+
}
|
|
331
|
+
/ name:Identifier {
|
|
332
|
+
return { key: name.name, value: name.name };
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
ArrayDestructuringPattern
|
|
336
|
+
= "[" _ elements:DestructuringElementList _ "]" {
|
|
337
|
+
return { type: 'ArrayPattern', elements };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
DestructuringElementList
|
|
341
|
+
= head:Identifier tail:(_ "," _ Identifier)* {
|
|
342
|
+
return [head.name, ...tail.map(t => t[3].name)];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
NonExportFunction
|
|
346
|
+
= isAsync:("async"i _)? "function"i _ name:Identifier _ "(" _ params:Parameters? _ ")" _ ":" _ returnType:TypeAnnotation _ "{" body:FunctionBody "}" _ {
|
|
347
|
+
return {
|
|
348
|
+
type: 'ExportFunction',
|
|
349
|
+
name,
|
|
350
|
+
isExport: false,
|
|
351
|
+
isAsync: !!isAsync,
|
|
352
|
+
params: params || [],
|
|
353
|
+
returnType,
|
|
354
|
+
body: { code: body },
|
|
355
|
+
location: location()
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/ isAsync:("async"i _)? "function"i _ name:Identifier _ "(" _ params:Parameters? _ ")" _ "{" body:FunctionBody "}" _ {
|
|
359
|
+
return {
|
|
360
|
+
type: 'ExportFunction',
|
|
361
|
+
name,
|
|
362
|
+
isExport: false,
|
|
363
|
+
isAsync: !!isAsync,
|
|
364
|
+
params: params || [],
|
|
365
|
+
returnType: null,
|
|
366
|
+
body: { code: body },
|
|
367
|
+
location: location()
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
|
|
254
371
|
ExportFunction
|
|
255
|
-
= "export"
|
|
372
|
+
= "export" _ isAsync:("async"i _)? "function"i _ name:Identifier _ "(" _ params:Parameters? _ ")" _ ":" _ returnType:TypeAnnotation _ "{" body:FunctionBody "}" _ {
|
|
256
373
|
return {
|
|
257
374
|
type: 'ExportFunction',
|
|
258
375
|
name,
|
|
@@ -283,16 +400,18 @@ Statement
|
|
|
283
400
|
= PlaybookStatement
|
|
284
401
|
/ VariableDeclaration
|
|
285
402
|
/ ConstDeclaration
|
|
403
|
+
/ TryStatement
|
|
286
404
|
/ IfStatement
|
|
287
405
|
/ ForStatement
|
|
288
406
|
/ WhileStatement
|
|
289
407
|
/ ReturnStatement
|
|
408
|
+
/ ThrowStatement
|
|
290
409
|
/ SendStatement
|
|
291
410
|
/ UsePlaybookStatement
|
|
292
411
|
/ ExpressionStatement
|
|
293
412
|
|
|
294
413
|
PlaybookStatement
|
|
295
|
-
= "playbook"
|
|
414
|
+
= "playbook" _ content:StringLiteral _ {
|
|
296
415
|
return { type: 'PlaybookStatement', content, location: location() };
|
|
297
416
|
}
|
|
298
417
|
|
|
@@ -312,7 +431,7 @@ ConstDeclaration
|
|
|
312
431
|
return { type: 'ConstDeclaration', name, value, location: location() };
|
|
313
432
|
}
|
|
314
433
|
/ "let"i _ name:Identifier _ "=" _ value:Expression _ {
|
|
315
|
-
return { type: '
|
|
434
|
+
return { type: 'VariableDeclaration', name, init: value, varType: null, location: location() };
|
|
316
435
|
}
|
|
317
436
|
|
|
318
437
|
IfStatement
|
|
@@ -325,6 +444,23 @@ ElseClause
|
|
|
325
444
|
return body;
|
|
326
445
|
}
|
|
327
446
|
|
|
447
|
+
TryStatement
|
|
448
|
+
= "try"i _ "{" _ body:Statement* _ "}" _ handler:CatchClause? _ finalizer:FinallyClause? _ &{
|
|
449
|
+
return !!(handler || finalizer);
|
|
450
|
+
} {
|
|
451
|
+
return { type: 'TryStatement', body, handler, finalizer, location: location() };
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
CatchClause
|
|
455
|
+
= "catch"i _ "(" _ param:Identifier _ ")" _ "{" _ body:Statement* _ "}" {
|
|
456
|
+
return { type: 'CatchClause', param, body, location: location() };
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
FinallyClause
|
|
460
|
+
= "finally"i _ "{" _ body:Statement* _ "}" {
|
|
461
|
+
return body;
|
|
462
|
+
}
|
|
463
|
+
|
|
328
464
|
ForStatement
|
|
329
465
|
= "for"i _ "(" _ decl:("const"i / "let"i / "var"i) _ id:Identifier _ "of"i _ expr:Expression _ ")" _ "{" _ body:Statement* _ "}" _ {
|
|
330
466
|
return { type: 'ForOfStatement', declaration: decl, id, expression: expr, body, location: location() };
|
|
@@ -351,27 +487,32 @@ ReturnStatement
|
|
|
351
487
|
return { type: 'ReturnStatement', value, location: location() };
|
|
352
488
|
}
|
|
353
489
|
|
|
490
|
+
ThrowStatement
|
|
491
|
+
= "throw"i _ value:Expression _ {
|
|
492
|
+
return { type: 'ThrowStatement', argument: value, location: location() };
|
|
493
|
+
}
|
|
494
|
+
|
|
354
495
|
SendStatement
|
|
355
496
|
= "await"i _ "send"i _ target:SendTarget _ args:CallArguments _ timeout:TimeoutClause? _ {
|
|
356
497
|
return { type: 'SendStatement', target, arguments: args, timeout, location: location() };
|
|
357
498
|
}
|
|
358
499
|
|
|
359
500
|
SendTarget
|
|
360
|
-
= base:
|
|
501
|
+
= base:PrimaryExpression filters:SendFilter* {
|
|
361
502
|
return { base, filters, location: location() };
|
|
362
503
|
}
|
|
363
504
|
|
|
364
505
|
SendFilter
|
|
365
|
-
= "." "event"i "(" _ name:StringLiteral _ ")" {
|
|
506
|
+
= _ "." "event"i "(" _ name:StringLiteral _ ")" {
|
|
366
507
|
return { type: 'EventFilter', event: name, location: location() };
|
|
367
508
|
}
|
|
368
|
-
/ "." "role"i "(" _ role:Identifier _ ")" {
|
|
509
|
+
/ _ "." "role"i "(" _ role:Identifier _ ")" {
|
|
369
510
|
return { type: 'RoleFilter', role, location: location() };
|
|
370
511
|
}
|
|
371
|
-
/ "." "any"i "(" _ ")" {
|
|
512
|
+
/ _ "." "any"i "(" _ ")" {
|
|
372
513
|
return { type: 'SelectionFilter', mode: 'any', location: location() };
|
|
373
514
|
}
|
|
374
|
-
/ "." "all"i "(" _ ")" {
|
|
515
|
+
/ _ "." "all"i "(" _ ")" {
|
|
375
516
|
return { type: 'SelectionFilter', mode: 'all', location: location() };
|
|
376
517
|
}
|
|
377
518
|
|
|
@@ -384,7 +525,7 @@ TimeUnit
|
|
|
384
525
|
= "ms"i / "s"i / "m"i / "h"i
|
|
385
526
|
|
|
386
527
|
UsePlaybookStatement
|
|
387
|
-
= "use"
|
|
528
|
+
= "use" _ "playbook" _ name:(Identifier / StringLiteral) _ {
|
|
388
529
|
return { type: 'UsePlaybookStatement', name, location: location() };
|
|
389
530
|
}
|
|
390
531
|
|
|
@@ -399,13 +540,23 @@ ExpressionStatement
|
|
|
399
540
|
|
|
400
541
|
Expression
|
|
401
542
|
= AssignmentExpression
|
|
543
|
+
/ ConditionalExpression
|
|
544
|
+
|
|
545
|
+
ConditionalExpression
|
|
546
|
+
= test:LogicalOrExpression _ "?" _ consequent:Expression _ ":" _ alternate:Expression {
|
|
547
|
+
return { type: 'ConditionalExpression', test, consequent, alternate, location: location() };
|
|
548
|
+
}
|
|
402
549
|
/ LogicalOrExpression
|
|
403
550
|
|
|
404
551
|
AssignmentExpression
|
|
405
|
-
= left:
|
|
552
|
+
= left:AssignmentTarget _ op:("=" / "+=" / "-=" / "*=" / "/=" / "%=") _ right:Expression {
|
|
406
553
|
return { type: 'AssignmentExpression', operator: op, left, right, location: location() };
|
|
407
554
|
}
|
|
408
555
|
|
|
556
|
+
AssignmentTarget
|
|
557
|
+
= ChainedExpression
|
|
558
|
+
/ Identifier
|
|
559
|
+
|
|
409
560
|
LogicalOrExpression
|
|
410
561
|
= head:LogicalAndExpression tail:(_ ("||") _ LogicalAndExpression)* {
|
|
411
562
|
return buildBinaryExpression(head, tail);
|
|
@@ -422,7 +573,7 @@ EqualityExpression
|
|
|
422
573
|
}
|
|
423
574
|
|
|
424
575
|
RelationalExpression
|
|
425
|
-
= head:AdditiveExpression tail:(_ ("<=" / ">=" / "<" / ">") _ AdditiveExpression)* {
|
|
576
|
+
= head:AdditiveExpression tail:(_ ("<=" / ">=" / "<" / ">" / "instanceof"i) _ AdditiveExpression)* {
|
|
426
577
|
return buildBinaryExpression(head, tail);
|
|
427
578
|
}
|
|
428
579
|
|
|
@@ -480,23 +631,32 @@ ChainedExpression
|
|
|
480
631
|
= base:PrimaryExpression chain:ChainElement+ {
|
|
481
632
|
return chain.reduce((obj, element) => {
|
|
482
633
|
if (element.type === 'call') {
|
|
483
|
-
return { type: 'CallExpression', callee: obj, arguments: element.args, location: location() };
|
|
634
|
+
return { type: 'CallExpression', callee: obj, arguments: element.args, optional: element.optional, location: location() };
|
|
484
635
|
} else if (element.type === 'member') {
|
|
485
|
-
return { type: 'MemberExpression', object: obj, property: element.property, computed: element.computed, location: location() };
|
|
636
|
+
return { type: 'MemberExpression', object: obj, property: element.property, computed: element.computed, optional: element.optional, location: location() };
|
|
486
637
|
}
|
|
487
638
|
return obj;
|
|
488
639
|
}, base);
|
|
489
640
|
}
|
|
490
641
|
|
|
491
642
|
ChainElement
|
|
492
|
-
= "
|
|
493
|
-
return { type: 'member', property: prop, computed: false };
|
|
643
|
+
= "?." _ prop:PropertyIdentifier {
|
|
644
|
+
return { type: 'member', property: prop, computed: false, optional: true };
|
|
645
|
+
}
|
|
646
|
+
/ "." _ prop:PropertyIdentifier {
|
|
647
|
+
return { type: 'member', property: prop, computed: false, optional: false };
|
|
648
|
+
}
|
|
649
|
+
/ "?.[" _ prop:Expression _ "]" {
|
|
650
|
+
return { type: 'member', property: prop, computed: true, optional: true };
|
|
494
651
|
}
|
|
495
652
|
/ "[" _ prop:Expression _ "]" {
|
|
496
|
-
return { type: 'member', property: prop, computed:
|
|
653
|
+
return { type: 'member', property: prop, computed: false, optional: false };
|
|
654
|
+
}
|
|
655
|
+
/ "?." _ args:CallArguments {
|
|
656
|
+
return { type: 'call', args, optional: true };
|
|
497
657
|
}
|
|
498
658
|
/ args:CallArguments {
|
|
499
|
-
return { type: 'call', args };
|
|
659
|
+
return { type: 'call', args, optional: false };
|
|
500
660
|
}
|
|
501
661
|
|
|
502
662
|
CallArguments
|
|
@@ -546,11 +706,11 @@ AwaitExpression
|
|
|
546
706
|
}
|
|
547
707
|
|
|
548
708
|
ArrowFunction
|
|
549
|
-
= "(" _ params:ParameterList? _ ")" _ "=>" _ body:ArrowBody {
|
|
550
|
-
return { type: 'ArrowFunction', params: params || [], body, location: location() };
|
|
709
|
+
= isAsync:("async"i _)? "(" _ params:ParameterList? _ ")" _ "=>" _ body:ArrowBody {
|
|
710
|
+
return { type: 'ArrowFunction', params: params || [], body, isAsync: !!isAsync, location: location() };
|
|
551
711
|
}
|
|
552
|
-
/ param:Identifier _ "=>" _ body:ArrowBody {
|
|
553
|
-
return { type: 'ArrowFunction', params: [param], body, location: location() };
|
|
712
|
+
/ isAsync:("async"i _)? param:Identifier _ "=>" _ body:ArrowBody {
|
|
713
|
+
return { type: 'ArrowFunction', params: [param], body, isAsync: !!isAsync, location: location() };
|
|
554
714
|
}
|
|
555
715
|
|
|
556
716
|
ParameterList
|
|
@@ -574,6 +734,7 @@ Literal
|
|
|
574
734
|
= MCPAddress
|
|
575
735
|
/ TemplateLiteral
|
|
576
736
|
/ StringLiteral
|
|
737
|
+
/ RegexLiteral
|
|
577
738
|
/ NumberLiteral
|
|
578
739
|
/ BooleanLiteral
|
|
579
740
|
/ NullLiteral
|
|
@@ -625,6 +786,21 @@ SingleStringChar
|
|
|
625
786
|
= !("'" / "\\") char:. { return char; }
|
|
626
787
|
/ "\\" seq:EscapeSequence { return seq; }
|
|
627
788
|
|
|
789
|
+
RegexLiteral
|
|
790
|
+
= "/" pattern:RegexPattern "/" flags:RegexFlags? {
|
|
791
|
+
return { type: 'RegexLiteral', pattern, flags: flags || '', location: location() };
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
RegexPattern
|
|
795
|
+
= chars:RegexChar* { return chars.join(''); }
|
|
796
|
+
|
|
797
|
+
RegexChar
|
|
798
|
+
= "\\" char:. { return "\\" + char; } // Escaped character (including \/)
|
|
799
|
+
/ ![/\n\r] char:. { return char; } // Any character except / and newlines
|
|
800
|
+
|
|
801
|
+
RegexFlags
|
|
802
|
+
= flags:$[gimsuvy]+ { return flags; }
|
|
803
|
+
|
|
628
804
|
EscapeSequence
|
|
629
805
|
= "n" { return "\n"; }
|
|
630
806
|
/ "t" { return "\t"; }
|
|
@@ -693,13 +869,66 @@ ArrayLiteral
|
|
|
693
869
|
// ============================================================
|
|
694
870
|
|
|
695
871
|
TypeAnnotation
|
|
696
|
-
=
|
|
697
|
-
/
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
872
|
+
= UnionType
|
|
873
|
+
/ PostfixType
|
|
874
|
+
|
|
875
|
+
UnionType
|
|
876
|
+
= head:PostfixType tail:(_ "|" _ PostfixType)+ {
|
|
877
|
+
return { type: 'UnionType', types: [head, ...tail.map(t => t[3])], location: location() };
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
PostfixType
|
|
881
|
+
= base:PrimaryType suffixes:(_ "[" _ "]")+ {
|
|
882
|
+
// Apply array type for each []
|
|
883
|
+
return suffixes.reduce((type) => {
|
|
884
|
+
return { type: 'ArrayTypeAnnotation', elementType: type, location: location() };
|
|
885
|
+
}, base);
|
|
886
|
+
}
|
|
887
|
+
/ PrimaryType
|
|
888
|
+
|
|
889
|
+
PrimaryType
|
|
890
|
+
= PromiseType
|
|
891
|
+
/ ArrayTypeAnnotation
|
|
892
|
+
/ ObjectTypeAnnotation
|
|
893
|
+
/ PrimitiveType
|
|
894
|
+
|
|
895
|
+
ObjectTypeAnnotation
|
|
896
|
+
= "{" _ props:TypePropertyList _ "}" {
|
|
897
|
+
return { type: 'ObjectTypeAnnotation', properties: props, location: location() };
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
TypePropertyList
|
|
901
|
+
= head:TypeProperty tail:(_ "," _ TypeProperty)* _ ","? {
|
|
902
|
+
return [head, ...tail.map(t => t[3])];
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
TypeProperty
|
|
906
|
+
= name:PropertyIdentifier _ optional:"?"? _ ":" _ type:TypeAnnotation {
|
|
907
|
+
return { name: name.name, type, optional: !!optional };
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
ArrayTypeAnnotation
|
|
911
|
+
= "Array"i _ "<" _ elem:TypeAnnotation _ ">" {
|
|
912
|
+
return { type: 'ArrayTypeAnnotation', elementType: elem, location: location() };
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
PromiseType
|
|
916
|
+
= "Promise"i _ "<" _ inner:TypeAnnotation _ ">" {
|
|
701
917
|
return { type: 'TypeAnnotation', name: 'Promise', inner, location: location() };
|
|
702
918
|
}
|
|
919
|
+
|
|
920
|
+
PrimitiveType
|
|
921
|
+
= "boolean"i !IdentifierPart { return { type: 'BooleanType', location: location() }; }
|
|
922
|
+
/ "number"i !IdentifierPart { return { type: 'NumberType', location: location() }; }
|
|
923
|
+
/ "string"i !IdentifierPart { return { type: 'StringType', location: location() }; }
|
|
924
|
+
/ "void"i !IdentifierPart { return { type: 'VoidType', location: location() }; }
|
|
925
|
+
/ "any"i !IdentifierPart { return { type: 'AnyType', location: location() }; }
|
|
926
|
+
/ "null"i !IdentifierPart { return { type: 'NullType', location: location() }; }
|
|
927
|
+
/ "undefined"i !IdentifierPart { return { type: 'UndefinedType', location: location() }; }
|
|
928
|
+
/ "Int"i !IdentifierPart { return { type: 'TypeAnnotation', name: 'Int', location: location() }; }
|
|
929
|
+
/ "String"i !IdentifierPart { return { type: 'TypeAnnotation', name: 'String', location: location() }; }
|
|
930
|
+
/ "Bool"i !IdentifierPart { return { type: 'TypeAnnotation', name: 'Bool', location: location() }; }
|
|
931
|
+
/ "Json"i !IdentifierPart { return { type: 'TypeAnnotation', name: 'Json', location: location() }; }
|
|
703
932
|
/ name:Identifier {
|
|
704
933
|
return { type: 'TypeAnnotation', name: name.name, location: location() };
|
|
705
934
|
}
|
|
@@ -714,8 +943,11 @@ Parameters
|
|
|
714
943
|
}
|
|
715
944
|
|
|
716
945
|
Parameter
|
|
717
|
-
= name:Identifier _ ":" _ type:TypeAnnotation {
|
|
718
|
-
return { name, type, location: location() };
|
|
946
|
+
= name:Identifier _ ":" _ type:TypeAnnotation _ defaultValue:("=" _ Expression)? {
|
|
947
|
+
return { name, type, default: defaultValue ? defaultValue[2] : null, location: location() };
|
|
948
|
+
}
|
|
949
|
+
/ name:Identifier {
|
|
950
|
+
return { name, type: null, default: null, location: location() };
|
|
719
951
|
}
|
|
720
952
|
|
|
721
953
|
// ============================================================
|
|
@@ -723,7 +955,7 @@ Parameter
|
|
|
723
955
|
// ============================================================
|
|
724
956
|
|
|
725
957
|
RunStatement
|
|
726
|
-
= "run"
|
|
958
|
+
= "run" _ target:MemberExpression args:CallArguments _ {
|
|
727
959
|
return { type: 'RunStatement', target, arguments: args, location: location() };
|
|
728
960
|
}
|
|
729
961
|
|
|
@@ -736,12 +968,20 @@ Identifier
|
|
|
736
968
|
return { type: 'Identifier', name, location: location() };
|
|
737
969
|
}
|
|
738
970
|
|
|
971
|
+
// PropertyIdentifier: allows reserved words as property names (after .)
|
|
972
|
+
// Examples: obj.state, obj.default, this.state
|
|
973
|
+
PropertyIdentifier
|
|
974
|
+
= name:$([a-zA-Z_][a-zA-Z0-9_]*) {
|
|
975
|
+
return { type: 'Identifier', name, location: location() };
|
|
976
|
+
}
|
|
977
|
+
|
|
739
978
|
ReservedWord
|
|
740
|
-
= ("
|
|
741
|
-
"uses" / "llm" / "default" / "on" / "state" / "playbook" / "resilience" /
|
|
979
|
+
= ("import" / "skill" / "role" / "can" / "team" / "agent" / "skill" /
|
|
980
|
+
"uses" / "llm" / "default" / "on" / "state" / "playbook" / "resilience" / "mcp" /
|
|
742
981
|
"export" / "async" / "function" / "var" / "const" / "let" / "if" / "else" / "for" / "of" / "in" / "while" /
|
|
982
|
+
"try" / "catch" / "finally" / "throw" / "instanceof" /
|
|
743
983
|
"return" / "await" / "send" / "timeout" / "use" / "run" /
|
|
744
|
-
"override" / "affordance" / "true" / "false" / "null") !IdentifierPart
|
|
984
|
+
"override" / "affordance" / "amnesia" / "true" / "false" / "null") !IdentifierPart
|
|
745
985
|
|
|
746
986
|
IdentifierPart
|
|
747
987
|
= [a-zA-Z0-9_]
|