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 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 type-safe virtual machine (~33KB) for safe execution of untrusted code in any JavaScript environment. It compiles logic chains and AI agents to JSON-serializable ASTs that run sandboxed with fuel (gas) limits.
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
- Key concept: Code travels to data (rather than shipping data to code). Agents are defined as data, not deployed code.
9
+ **Three pillars:**
10
10
 
11
- **Two languages in one platform:**
12
-
13
- - **TJS** — TypeScript-like syntax with runtime type validation for writing your platform
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 (~2900 lines, security-critical)
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 jsCode = tjs(tjsSource)
157
- // Generates JavaScript with __tjs metadata for runtime validation
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/lang.test.ts` (~46KB comprehensive)
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: Self-Contained Output
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
- Transpiled TJS code currently requires `globalThis.__tjs` to be set up with `createRuntime()` before execution. A `{ standalone: true }` option to inline the ~1KB runtime is planned but not yet implemented.
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 | 42 KB | **14 KB** |
276
- | + Batteries (LLM, vector) | 56 KB | 19 KB |
277
- | + Transpiler | 89 KB | 27 KB |
278
- | Full (with TS support) | 180 KB | 56 KB |
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: { 'Content-Type': 'text/html' },
193
+ headers: {
194
+ 'Content-Type': 'text/html',
195
+ 'Cache-Control': 'no-cache, no-store, must-revalidate',
196
+ },
193
197
  })
194
198
  }
195
199