tjs-lang 0.5.5 → 0.6.5
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/CLAUDE.md +49 -13
- package/README.md +4 -4
- package/bin/dev.ts +5 -1
- package/demo/docs.json +11 -5
- package/demo/index.html +2 -2
- package/demo/src/capabilities.ts +109 -2
- package/demo/src/index.ts +179 -29
- package/demo/src/playground-shared.ts +4 -4
- package/demo/src/playground.ts +2 -2
- package/demo/src/tjs-playground.ts +294 -12
- package/demo/src/ts-playground.ts +238 -0
- package/dist/index.js +116 -106
- package/dist/index.js.map +7 -6
- package/dist/src/cli/commands/emit.d.ts +3 -0
- package/dist/src/lang/emitters/dts.d.ts +48 -0
- package/dist/src/lang/index.d.ts +1 -0
- package/dist/tjs-full.js +116 -106
- package/dist/tjs-full.js.map +7 -6
- package/dist/tjs-vm.js +27 -27
- package/dist/tjs-vm.js.map +3 -3
- package/docs/generic-dts-design.md +143 -0
- package/docs/native-engine-integration.md +167 -0
- package/package.json +1 -1
- package/src/cli/commands/emit.ts +26 -0
- package/src/cli/tjs.ts +4 -1
- package/src/lang/emitters/dts.test.ts +470 -0
- package/src/lang/emitters/dts.ts +633 -0
- package/src/lang/emitters/from-ts.ts +96 -14
- package/src/lang/index.ts +5 -0
- package/src/lang/parser-transforms.ts +19 -2
- package/src/lang/typescript-syntax.test.ts +86 -0
package/CLAUDE.md
CHANGED
|
@@ -4,14 +4,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
4
4
|
|
|
5
5
|
## Project Overview
|
|
6
6
|
|
|
7
|
-
**tjs-lang** (npm: `tjs-lang`) is a
|
|
7
|
+
**tjs-lang** (npm: `tjs-lang`) is a typed JavaScript platform — a language, runtime, and toolchain that transpiles TypeScript and TJS to JavaScript with runtime type validation, inline WASM, monadic errors, and safe eval. It also includes AJS, a gas-metered VM for executing untrusted agent code in any JavaScript environment.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Three pillars:**
|
|
10
10
|
|
|
11
|
-
**
|
|
12
|
-
|
|
13
|
-
- **
|
|
14
|
-
- **AJS** — Agent language that compiles to JSON AST for safe, sandboxed execution
|
|
11
|
+
- **TJS** — TypeScript-like syntax where types are examples that survive to runtime as contracts, documentation, and tests. Transpiles TS → TJS → JS in a single fast pass.
|
|
12
|
+
- **AJS** — Agent language that compiles to JSON AST for safe, sandboxed execution with fuel limits and injected capabilities. Code travels to data.
|
|
13
|
+
- **Toolchain** — Compresses transpilation, linting, testing, and documentation generation into one pass. Includes inline WASM with SIMD, polymorphic dispatch, local class extensions, and a browser-based playground.
|
|
15
14
|
|
|
16
15
|
## Common Commands
|
|
17
16
|
|
|
@@ -70,7 +69,7 @@ npm run functions:serve # Local functions emulator
|
|
|
70
69
|
### Key Source Files
|
|
71
70
|
|
|
72
71
|
- `src/index.ts` - Main entry, re-exports everything
|
|
73
|
-
- `src/vm/runtime.ts` - All atom implementations, expression evaluation, fuel charging (~
|
|
72
|
+
- `src/vm/runtime.ts` - All atom implementations, expression evaluation, fuel charging (~3000 lines, security-critical)
|
|
74
73
|
- `src/vm/vm.ts` - AgentVM class (~226 lines)
|
|
75
74
|
- `src/vm/atoms/batteries.ts` - Battery atoms (vector search, LLM, store operations)
|
|
76
75
|
- `src/builder.ts` - TypedBuilder fluent API (~19KB)
|
|
@@ -78,6 +77,7 @@ npm run functions:serve # Local functions emulator
|
|
|
78
77
|
- `src/lang/emitters/ast.ts` - Emits Agent99 AST from parsed source
|
|
79
78
|
- `src/lang/emitters/js.ts` - Emits JavaScript with `__tjs` metadata
|
|
80
79
|
- `src/lang/emitters/from-ts.ts` - TypeScript to TJS/JS transpiler with class metadata extraction
|
|
80
|
+
- `src/lang/emitters/dts.ts` - .d.ts declaration file generator from TJS transpilation results
|
|
81
81
|
- `src/lang/inference.ts` - Type inference from example values
|
|
82
82
|
- `src/lang/linter.ts` - Static analysis (unused vars, unreachable code, no-explicit-new)
|
|
83
83
|
- `src/lang/runtime.ts` - TJS runtime (monadic errors, type checking, wrapClass)
|
|
@@ -153,8 +153,8 @@ function greet(name: '') -> '' {
|
|
|
153
153
|
}
|
|
154
154
|
`
|
|
155
155
|
|
|
156
|
-
const
|
|
157
|
-
//
|
|
156
|
+
const jsResult = tjs(tjsSource)
|
|
157
|
+
// jsResult.code contains JavaScript with __tjs metadata for runtime validation
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
**Full Chain Example:**
|
|
@@ -188,6 +188,9 @@ fn('a', 'b') // Returns { error: 'type mismatch', ... }
|
|
|
188
188
|
- `fromTS` lives in a separate entry point (`tosijs/lang/from-ts`)
|
|
189
189
|
- Import only what you need to keep bundle size minimal
|
|
190
190
|
- Each step is independently testable (see `src/lang/codegen.test.ts`)
|
|
191
|
+
- Constrained generics (`<T extends { id: number }>`) use the constraint as the example value instead of `any`
|
|
192
|
+
- Generic defaults (`<T = string>`) use the default as the example value
|
|
193
|
+
- Unconstrained generics (`<T>`) degrade to `any` — there's no information to use
|
|
191
194
|
|
|
192
195
|
### Security Model
|
|
193
196
|
|
|
@@ -223,10 +226,12 @@ AJS expressions behave differently from JavaScript in several important ways:
|
|
|
223
226
|
- Unit tests alongside source files (`*.test.ts`)
|
|
224
227
|
- Integration tests in `src/use-cases/` (RAG, orchestration, malicious actors)
|
|
225
228
|
- Security tests in `src/use-cases/malicious-actor.test.ts`
|
|
226
|
-
- Language tests in `src/lang
|
|
229
|
+
- Language tests split across 14 files in `src/lang/` (lang.test.ts, features.test.ts, codegen.test.ts, parser.test.ts, from-ts.test.ts, wasm.test.ts, etc.)
|
|
227
230
|
|
|
228
231
|
Coverage targets: 98% lines on `src/vm/runtime.ts` (security-critical), 80%+ overall.
|
|
229
232
|
|
|
233
|
+
**Bug fix rule:** Always create a reproduction test case before fixing a bug.
|
|
234
|
+
|
|
230
235
|
## Key Patterns
|
|
231
236
|
|
|
232
237
|
### Adding a New Atom
|
|
@@ -376,6 +381,18 @@ Generic Container<T, U = ''> {
|
|
|
376
381
|
return T(obj.item) && U(obj.label)
|
|
377
382
|
}
|
|
378
383
|
}
|
|
384
|
+
|
|
385
|
+
// Generic with declaration block (for .d.ts emission)
|
|
386
|
+
// The declaration block contains TypeScript syntax emitted verbatim into .d.ts
|
|
387
|
+
// It is stripped from runtime JS output
|
|
388
|
+
Generic BoxedProxy<T> {
|
|
389
|
+
predicate(x, T) { return typeof x === 'object' && T(x.value) }
|
|
390
|
+
declaration {
|
|
391
|
+
value: T
|
|
392
|
+
path: string
|
|
393
|
+
observe(cb: (path: string) => void): void
|
|
394
|
+
}
|
|
395
|
+
}
|
|
379
396
|
```
|
|
380
397
|
|
|
381
398
|
#### Bare Assignments
|
|
@@ -692,9 +709,28 @@ The `docs/` directory contains real documentation (markdown), not build artifact
|
|
|
692
709
|
- `DOCS-TJS.md` — TJS language guide
|
|
693
710
|
- `DOCS-AJS.md` — AJS runtime guide
|
|
694
711
|
- `CONTEXT.md` — Architecture deep dive
|
|
695
|
-
- `AGENTS.md` — Agent workflow instructions (issue tracking with `bd`, mandatory push-before-done)
|
|
712
|
+
- `AGENTS.md` — Agent workflow instructions (issue tracking with `bd`, mandatory push-before-done). **Critical**: work is NOT complete until `git push` succeeds; use `bd ready` to find work, `bd close <id>` to complete
|
|
696
713
|
- `PLAN.md` — Roadmap
|
|
697
714
|
|
|
698
|
-
### Known Gotcha:
|
|
715
|
+
### Known Gotcha: `tjs()` Returns an Object, Not a String
|
|
716
|
+
|
|
717
|
+
`tjs(source)` returns `{ code, types, metadata, testResults, ... }`. Use `.code` to get the transpiled JavaScript string. This is a common mistake.
|
|
718
|
+
|
|
719
|
+
### Known Gotcha: Running Emitted TJS Code in Tests
|
|
720
|
+
|
|
721
|
+
Transpiled TJS code requires `globalThis.__tjs` to be set up with `createRuntime()` before execution:
|
|
722
|
+
|
|
723
|
+
```typescript
|
|
724
|
+
import { createRuntime } from '../lang/runtime'
|
|
725
|
+
|
|
726
|
+
const saved = globalThis.__tjs
|
|
727
|
+
globalThis.__tjs = createRuntime()
|
|
728
|
+
try {
|
|
729
|
+
const fn = new Function(result.code + '\nreturn fnName')()
|
|
730
|
+
// ... test fn
|
|
731
|
+
} finally {
|
|
732
|
+
globalThis.__tjs = saved
|
|
733
|
+
}
|
|
734
|
+
```
|
|
699
735
|
|
|
700
|
-
|
|
736
|
+
A `{ standalone: true }` option to inline the ~1KB runtime is planned but not yet implemented.
|
package/README.md
CHANGED
|
@@ -272,10 +272,10 @@ The cost of "safe eval"—compare to a 200MB Docker image:
|
|
|
272
272
|
|
|
273
273
|
| Bundle | Size | Gzipped |
|
|
274
274
|
| ------------------------- | ------ | --------- |
|
|
275
|
-
| VM only |
|
|
276
|
-
| + Batteries (LLM, vector) |
|
|
277
|
-
| + Transpiler |
|
|
278
|
-
| Full (with TS support) |
|
|
275
|
+
| VM only | 218 KB | **66 KB** |
|
|
276
|
+
| + Batteries (LLM, vector) | 14 KB | 5 KB |
|
|
277
|
+
| + Transpiler | 5 KB | 2 KB |
|
|
278
|
+
| Full (with TS support) | 230 KB | 71 KB |
|
|
279
279
|
|
|
280
280
|
**Dependencies:** `acorn` (JS parser), `tosijs-schema` (validation). Both have zero transitive dependencies.
|
|
281
281
|
|
package/bin/dev.ts
CHANGED
|
@@ -181,6 +181,7 @@ const server = Bun.serve({
|
|
|
181
181
|
headers: {
|
|
182
182
|
'Content-Type': contentTypes[ext || 'html'] || 'text/plain',
|
|
183
183
|
'Access-Control-Allow-Origin': '*',
|
|
184
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
184
185
|
},
|
|
185
186
|
})
|
|
186
187
|
}
|
|
@@ -189,7 +190,10 @@ const server = Bun.serve({
|
|
|
189
190
|
const indexFile = Bun.file(join(DOCS_DIR, 'index.html'))
|
|
190
191
|
if (await indexFile.exists()) {
|
|
191
192
|
return new Response(indexFile, {
|
|
192
|
-
headers: {
|
|
193
|
+
headers: {
|
|
194
|
+
'Content-Type': 'text/html',
|
|
195
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
196
|
+
},
|
|
193
197
|
})
|
|
194
198
|
}
|
|
195
199
|
|