summitjs 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.
- package/AGENTS.md +105 -0
- package/LICENSE +21 -0
- package/README.md +160 -0
- package/dist/summit.cjs +3324 -0
- package/dist/summit.cjs.map +1 -0
- package/dist/summit.d.cts +269 -0
- package/dist/summit.d.ts +269 -0
- package/dist/summit.js +3304 -0
- package/dist/summit.js.map +1 -0
- package/dist/summit.min.js +7 -0
- package/dist/summit.min.js.map +1 -0
- package/package.json +79 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Summit.js for AI agents
|
|
2
|
+
|
|
3
|
+
Summit is an HTML-first reactive framework. You add behavior to markup with
|
|
4
|
+
`s-` attributes and `$` magics. There is no build step and no virtual DOM. A
|
|
5
|
+
small, CSP-safe interpreter evaluates the expressions, so only a fixed,
|
|
6
|
+
predictable vocabulary is allowed. This file tells you how to write Summit that
|
|
7
|
+
runs correctly the first time.
|
|
8
|
+
|
|
9
|
+
Full docs as one file: https://velofy.github.io/summit/llms-full.txt
|
|
10
|
+
Index: https://velofy.github.io/summit/llms.txt
|
|
11
|
+
Any page as markdown: append `index.md` to its URL.
|
|
12
|
+
|
|
13
|
+
## Load it
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<script src="https://velofy.github.io/summit/summit.min.js" defer></script>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## The model
|
|
20
|
+
|
|
21
|
+
- `s-data` declares reactive state on an element. Its descendants can read and
|
|
22
|
+
write that state in expressions.
|
|
23
|
+
- State is signal-backed: reads track, writes notify, and only the affected DOM
|
|
24
|
+
updates. You never call render.
|
|
25
|
+
- Expressions are a safe subset of JavaScript. You cannot reach arbitrary
|
|
26
|
+
globals. Allowed globals include `Math`, `JSON`, `Date`, `Object`, `Array`,
|
|
27
|
+
`Number`, `String`, `Boolean`, `console`, `window`, `document`, `location`,
|
|
28
|
+
`localStorage`, `setTimeout`, `fetch`, and other common read-only builtins.
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<div s-data="{ count: 0 }">
|
|
32
|
+
<button @click="count++">Add</button>
|
|
33
|
+
<span s-text="count"></span>
|
|
34
|
+
</div>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Directives
|
|
38
|
+
|
|
39
|
+
| Directive | Shorthand | Purpose |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| `s-data` | | declare reactive state |
|
|
42
|
+
| `s-text` | | set textContent |
|
|
43
|
+
| `s-html` | | set innerHTML (trusted content only) |
|
|
44
|
+
| `s-bind:attr` | `:attr` | bind an attribute; `:class` and `:style` accept objects |
|
|
45
|
+
| `s-on:event` | `@event` | run an expression on an event |
|
|
46
|
+
| `s-model` | | two-way bind a form control |
|
|
47
|
+
| `s-show` | | toggle visibility with `display` |
|
|
48
|
+
| `s-if` | | add or remove from the DOM; a `<template s-if>` may hold multiple roots |
|
|
49
|
+
| `s-for` | | render a list; use `:key` |
|
|
50
|
+
| `s-ref` | | name an element, read it via `$refs` |
|
|
51
|
+
| `s-init` | | run an expression once on init |
|
|
52
|
+
| `s-effect` | | re-run an expression when its dependencies change |
|
|
53
|
+
| `s-transition` | | animate enter and leave |
|
|
54
|
+
| `s-teleport` | | move an element elsewhere in the DOM (dialogs, toasts) |
|
|
55
|
+
| `s-intersect` | `s-intersect:leave` | run an expression when the element enters or leaves the viewport (`.once`, `.half`, `.full`) |
|
|
56
|
+
| `s-trap` | | keep keyboard focus inside an element while an expression is truthy |
|
|
57
|
+
| `s-anchor` | | position next to a reference element, flipping to stay in view (`.top`, `.end`, `.offset.N`) |
|
|
58
|
+
| `s-collapse` | | animate an element open and closed by height |
|
|
59
|
+
| `s-mask` | | format an input as you type (`9` digit, `a` letter, `*` either) |
|
|
60
|
+
| `s-cloak` | | hide until initialized; pair with `[s-cloak]{display:none}` |
|
|
61
|
+
| `s-ignore` | | skip a subtree |
|
|
62
|
+
|
|
63
|
+
## Magics
|
|
64
|
+
|
|
65
|
+
`$el`, `$refs`, `$root`, `$id`, `$store`, `$watch`, `$nextTick`, `$dispatch`,
|
|
66
|
+
`$data`, `$persist`, `$focus`. Example: `@click="$dispatch('saved', { id: 3 })"`
|
|
67
|
+
fires a custom event that a `@saved.window` handler can catch. Use
|
|
68
|
+
`$persist(0)` in `s-data` for localStorage-backed state, and `$focus` to move
|
|
69
|
+
keyboard focus.
|
|
70
|
+
|
|
71
|
+
## Modifiers
|
|
72
|
+
|
|
73
|
+
- Events: `.prevent`, `.stop`, `.self`, `.once`, `.window`, `.outside`,
|
|
74
|
+
`.capture`, `.passive`, `.debounce`, `.throttle`, and keys such as `.enter`,
|
|
75
|
+
`.escape`, `.cmd`, `.ctrl`, `.meta`, `.alt`, `.shift`.
|
|
76
|
+
- Model: `.number`, `.trim`, `.lazy`.
|
|
77
|
+
|
|
78
|
+
```html
|
|
79
|
+
<input @keydown.enter="submit()" s-model.trim="query">
|
|
80
|
+
<div @keydown.window.cmd.k.prevent="openPalette()"></div>
|
|
81
|
+
<button @click.outside="open = false"></button>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Rules that keep it correct
|
|
85
|
+
|
|
86
|
+
- Every reactive expression must resolve against `s-data` state in scope. Do not
|
|
87
|
+
reference variables that are not declared in state or the allowed globals.
|
|
88
|
+
- `s-for` needs a `:key` for stable, correct reconciliation.
|
|
89
|
+
- Reach across components with events (`$dispatch`) or a shared `$store`, not by
|
|
90
|
+
reading another component's private state.
|
|
91
|
+
- `s-html` is not sanitized. Use it only with content you trust.
|
|
92
|
+
- Prefer `s-show` for frequent toggles and `s-if` to add or remove real DOM.
|
|
93
|
+
|
|
94
|
+
## UI library
|
|
95
|
+
|
|
96
|
+
Summit ships a copy-in component library. Load one stylesheet and use `s-`
|
|
97
|
+
prefixed classes (`s-btn`, `s-input`, `s-card`, `s-alert`, `s-tabs`, `s-dialog`,
|
|
98
|
+
and more). Theme everything by overriding CSS variables like `--accent`.
|
|
99
|
+
|
|
100
|
+
```html
|
|
101
|
+
<link rel="stylesheet" href="https://velofy.github.io/summit/assets/components.css">
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
See https://velofy.github.io/summit/components/ for every component with live
|
|
105
|
+
demos and copy-paste markup.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Velofy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/velofy/summit/main/docs/assets/logo-dark.svg">
|
|
4
|
+
<img alt="Summit.js" src="https://raw.githubusercontent.com/velofy/summit/main/docs/assets/logo-light.svg" width="104">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<h1 align="center">Summit.js</h1>
|
|
9
|
+
|
|
10
|
+
<p align="center">The open source, AI Agent Native JavaScript framework for composing behavior directly in your HTML.<br>Drop in one script and go. No build step, no virtual DOM, no <code>eval</code>.</p>
|
|
11
|
+
|
|
12
|
+
<p align="center"><strong>Open Source. by Nature.</strong></p>
|
|
13
|
+
|
|
14
|
+
Started by [anishfyi](https://github.com/anishfyi), so that AI agents can make beautiful frontends.
|
|
15
|
+
|
|
16
|
+
Summit is built in the spirit of Alpine's HTML-first ergonomics, then pushed further where it counts: a fine-grained signal engine, a CSP-safe expression evaluator, keyed list rendering, cached computed getters, a copy-in UI library, and full TypeScript types, all in about 16KB gzipped.
|
|
17
|
+
|
|
18
|
+
## AI Agent Native
|
|
19
|
+
|
|
20
|
+
Summit is designed so that an AI agent can write a working, good-looking frontend on the first try:
|
|
21
|
+
|
|
22
|
+
- **HTML-first and local.** Behavior lives on the element it affects, so an agent edits one place and sees the result. No file graph to hold in context.
|
|
23
|
+
- **Predictable vocabulary.** A small, closed set of `s-` directives and `$` magics. There is one obvious way to do most things, which is exactly what a model does best.
|
|
24
|
+
- **Safe by construction.** Expressions are interpreted, never `eval`ed, so generated markup runs under a strict CSP and cannot reach outside its allowlist.
|
|
25
|
+
- **A UI library, included.** Accessible, token-themed components an agent (or a person) drops in and themes with CSS variables. See the [UI Library](https://velofy.github.io/summit/components/).
|
|
26
|
+
- **Built to be read by machines.** The whole framework is discoverable in one fetch: [`llms.txt`](https://velofy.github.io/summit/llms.txt) indexes every page, [`llms-full.txt`](https://velofy.github.io/summit/llms-full.txt) is the entire corpus as markdown, any page is available as markdown (append `index.md` to its URL) with a one-click "Copy for AI" button, and [`AGENTS.md`](./AGENTS.md) is a drop-in brief you can hand to your own agent.
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<script src="https://velofy.github.io/summit/summit.min.js" defer></script>
|
|
30
|
+
|
|
31
|
+
<div s-data="{ open: false }">
|
|
32
|
+
<button @click="open = !open">Toggle</button>
|
|
33
|
+
<p s-show="open">Hello from Summit</p>
|
|
34
|
+
</div>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Why Summit
|
|
38
|
+
|
|
39
|
+
| Capability | Summit | Classic HTML-sprinkle runtimes |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| Reactivity | Fine-grained signals, surgical DOM updates | Effect re-runs, coarser |
|
|
42
|
+
| Strict CSP (no `unsafe-eval`) | Default | Needs a separate, limited build |
|
|
43
|
+
| Keyed list reconciliation | Built in | Limited |
|
|
44
|
+
| Cached computed getters | Yes | Recomputed on every read |
|
|
45
|
+
| `s-if` on any element | Yes | `<template>` only |
|
|
46
|
+
| TypeScript types shipped | Yes | Partial |
|
|
47
|
+
| Focus trap, floating menus, persisted state, input masking | Built in | Separate plugins |
|
|
48
|
+
| Bundle size (gzip) | ~16KB, batteries included | ~16KB core, plugins extra |
|
|
49
|
+
| Build step required | Never | Never |
|
|
50
|
+
|
|
51
|
+
The headline difference is the engine. Summit owns a real signal core, so a change updates only the DOM that read the value that changed. And because expressions run through a hand-written interpreter rather than `new Function`, a strict Content-Security-Policy works out of the box.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
Zero-build, drop in a script (auto-starts, exposes `window.Summit`):
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<script src="https://velofy.github.io/summit/summit.min.js" defer></script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
With a bundler:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm install summitjs
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
import Summit from "summitjs";
|
|
69
|
+
// register custom data, directives, magics, stores, or plugins here
|
|
70
|
+
Summit.start();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Directives
|
|
74
|
+
|
|
75
|
+
Prefix `s-`, with `@` shorthand for `s-on:` and `:` for `s-bind:`.
|
|
76
|
+
|
|
77
|
+
| Directive | Purpose |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `s-data` | Declare a reactive component scope |
|
|
80
|
+
| `s-text` / `s-html` | Set text or HTML content |
|
|
81
|
+
| `s-bind` / `:` | Bind attributes, with class object and style object merging |
|
|
82
|
+
| `s-on` / `@` | Listen for events, with a full modifier set |
|
|
83
|
+
| `s-model` | Two-way form binding |
|
|
84
|
+
| `s-show` | Toggle visibility via `display` |
|
|
85
|
+
| `s-if` | Add or remove an element (works on any element, not just `<template>`) |
|
|
86
|
+
| `s-for` | Keyed list rendering on a `<template>` |
|
|
87
|
+
| `s-effect` | Run an expression reactively |
|
|
88
|
+
| `s-transition` | Enter and leave animations, paired with `s-show` |
|
|
89
|
+
| `s-teleport` | Render a `<template>` elsewhere while keeping its scope |
|
|
90
|
+
| `s-ref` | Register an element into `$refs` (dynamic names supported) |
|
|
91
|
+
| `s-init` | Run an expression once on init |
|
|
92
|
+
| `s-id` | Open an id group for accessible `$id()` pairing |
|
|
93
|
+
| `s-cloak` | Hide until initialized; pair with `[s-cloak]{display:none}` |
|
|
94
|
+
|
|
95
|
+
### Event modifiers
|
|
96
|
+
|
|
97
|
+
`.prevent .stop .self .outside .once .capture .passive .window .document .debounce .throttle`, key filters (`.enter .escape .arrow-up ...`), system keys (`.shift .ctrl .alt .cmd`), and name transforms (`.camel .dot`).
|
|
98
|
+
|
|
99
|
+
### `s-model` modifiers
|
|
100
|
+
|
|
101
|
+
`.lazy .change .blur .number .boolean .debounce .fill`.
|
|
102
|
+
|
|
103
|
+
## Magics
|
|
104
|
+
|
|
105
|
+
`$el`, `$refs`, `$root`, `$store`, `$data`, `$watch`, `$dispatch`, `$nextTick`, `$id`. They are available in expressions and as `this.$watch`, `this.$refs`, and so on inside component methods.
|
|
106
|
+
|
|
107
|
+
`$watch` improves on the usual behavior: it returns an unwatch function and only fires on an actual change, so mutating the watched value inside its own callback cannot spin into an infinite loop.
|
|
108
|
+
|
|
109
|
+
## Registration API
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
Summit.data("dropdown", (open = false) => ({
|
|
113
|
+
open,
|
|
114
|
+
toggle() { this.open = !this.open },
|
|
115
|
+
init() { /* runs before the component renders */ },
|
|
116
|
+
}));
|
|
117
|
+
|
|
118
|
+
Summit.store("theme", { dark: false, toggle() { this.dark = !this.dark } });
|
|
119
|
+
|
|
120
|
+
Summit.directive("uppercase", (el, meta, utils) => {
|
|
121
|
+
utils.effect(() => { el.textContent = String(utils.evaluate(meta.expression)).toUpperCase(); });
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
Summit.magic("now", () => () => new Date().toLocaleTimeString());
|
|
125
|
+
|
|
126
|
+
Summit.plugin((s) => { /* register a bundle of the above */ });
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Registration is timing-safe. Built-ins register at import, your registrations override them, and `Summit.start()` can be called whenever the DOM is ready. There is no load-order event to miss.
|
|
130
|
+
|
|
131
|
+
## Reactivity primitives
|
|
132
|
+
|
|
133
|
+
Summit's signal core is also usable standalone:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
import { signal, computed, effect, batch } from "summitjs";
|
|
137
|
+
|
|
138
|
+
const count = signal(0);
|
|
139
|
+
const doubled = computed(() => count() * 2);
|
|
140
|
+
effect(() => console.log(doubled()));
|
|
141
|
+
count.set(5); // logs 10
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm install
|
|
148
|
+
npm run check # typecheck + unit tests + build + size budget + bundle smoke + page verification
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- `npm test` runs the Vitest suites (reactivity, evaluator, directives).
|
|
152
|
+
- `npm run build` produces ESM, CJS, IIFE, and `.d.ts` in `dist/`, and syncs `docs/`.
|
|
153
|
+
- `npm run smoke` drives the shipped bundle end to end.
|
|
154
|
+
- `npm run verify` boots the real docs page under Summit and checks every demo.
|
|
155
|
+
|
|
156
|
+
The documentation site in `docs/` dogfoods Summit and deploys to GitHub Pages.
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT
|