@vraxis/osx-components 0.11.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OSX Components contributors
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,214 @@
1
+ # OSX Components
2
+
3
+ OSX Components is an open-source collection of OS X-inspired web components authored with Vue 3. Components render through the Custom Elements API, so they work in Vue, React, Svelte, Astro, or plain HTML.
4
+
5
+ The project recreates the interaction language—not Apple assets or source code—with accessible controls, Shadow DOM encapsulation, and a shared token contract.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @vraxis/osx-components
11
+ ```
12
+
13
+ ```ts
14
+ import { registerOsxComponents } from "@vraxis/osx-components";
15
+ import "@vraxis/osx-components/theme.css";
16
+
17
+ registerOsxComponents();
18
+ ```
19
+
20
+ ## Build with an AI agent
21
+
22
+ Install the versioned `build-with-osx-components` skill so coding agents select real components, follow the theme and accessibility contracts, and verify the finished interface instead of approximating the system from screenshots.
23
+
24
+ ```bash
25
+ # Portable Agent Skills location; works with compatible agents
26
+ npx @vraxis/osx-components agent install
27
+
28
+ # Agent-specific project installation
29
+ npx @vraxis/osx-components agent install --target codex
30
+ npx @vraxis/osx-components agent install --target claude
31
+ npx @vraxis/osx-components agent install --target opencode
32
+ npx @vraxis/osx-components agent install --target cursor
33
+
34
+ # Install every project adapter
35
+ npx @vraxis/osx-components agent install --target all
36
+ ```
37
+
38
+ Use `--scope user` with `agents`, `codex`, `claude`, or `opencode` to install the skill globally. Re-run with `--force` after upgrading the package. Cursor rules remain project scoped.
39
+
40
+ The skill includes component-selection guidance, framework integration patterns, application and agent-workspace compositions, the project quality standard, and a deterministic interface audit:
41
+
42
+ ```bash
43
+ npx @vraxis/osx-components agent install --target agents
44
+ node .agents/skills/build-with-osx-components/scripts/audit-osx-ui.mjs .
45
+ ```
46
+
47
+ ```html
48
+ <div data-osx-theme="aqua">
49
+ <osx-window title="Preferences" subtitle="Appearance">
50
+ <osx-toolbar slot="toolbar">
51
+ <strong slot="leading">General</strong>
52
+ <osx-button slot="trailing" size="small">Show All</osx-button>
53
+ </osx-toolbar>
54
+ <osx-button variant="primary">Save changes</osx-button>
55
+ </osx-window>
56
+ </div>
57
+ ```
58
+
59
+ ## Themes
60
+
61
+ Set `data-osx-theme` on any ancestor. Tokens inherit across each component's Shadow DOM boundary.
62
+
63
+ - `aqua` — bright blue, translucent highlights, and cool raised surfaces
64
+ - `graphite` — the Aqua structure with a neutral accent system
65
+ - `panther` — a dark interpretation designed as if the original system had shipped one
66
+
67
+ Every visual decision is exposed through `--osx-*` custom properties. Override the tokens on an application shell or an individual component.
68
+
69
+ ## Components
70
+
71
+ | Element | Purpose |
72
+ | --- | --- |
73
+ | `<osx-app-shell>` | Responsive application workspace with toolbar, sidebar, content, composer, inspector, status slots, and optional accessible panel resizing |
74
+ | `<osx-agent-composer>` | Prompt input with Enter-to-send, busy state, model context, and stop action |
75
+ | `<osx-agent-message>` | User, assistant, system, streaming, and error conversation states |
76
+ | `<osx-agent-run-status>` | Plan, work, verify, complete, and failure lifecycle visualization |
77
+ | `<osx-agent-approval>` | Risk-aware human approval with explicit action scope |
78
+ | `<osx-thinking>` | Collapsible, streaming reasoning summaries and progress traces |
79
+ | `<osx-plan>` | Ordered agent steps with pending, active, done, failed, and skipped states |
80
+ | `<osx-artifact>` | Generated file, document, and code output with copy, download, open, and version actions |
81
+ | `<osx-markdown>` | Injection-safe, streaming Markdown with code copy, tables, lists, quotes, and links |
82
+ | `<osx-citation>` | Inline citation chip for grounded RAG and search responses |
83
+ | `<osx-source-panel>` | Coordinated source list with selection, domains, and supporting excerpts |
84
+ | `<osx-tool-call>` | Expandable queued, running, successful, and failed tool activity |
85
+ | `<osx-diff-viewer>` | Unified and split code review with line numbers, statistics, and layout controls |
86
+ | `<osx-terminal>` | Command output with lifecycle state, rerun, interrupt, and clear actions |
87
+ | `<osx-file-tree>` | Filterable repository hierarchy with selection and Git status markers |
88
+ | `<osx-alert>` | Persistent information, success, warning, and error feedback |
89
+ | `<osx-toast>` | Transient notifications with placement, timeout, and dismissal control |
90
+ | `<osx-shimmer>` | Flexible reduced-motion-aware loading placeholder |
91
+ | `<osx-skeleton>` | Text, profile, and card loading compositions |
92
+ | `<osx-spinner>` | Compact reduced-motion-aware indeterminate activity feedback |
93
+ | `<osx-icon>` | Curated Lucide SVG iconography with consistent sizing and accessible labels |
94
+ | `<osx-icon-button>` | Accessible icon-only actions with standardized hit areas and states |
95
+ | `<osx-tooltip>` | Supplemental hover and focus hints for compact controls |
96
+ | `<osx-popover>` | Anchored contextual content with explicit dismissal |
97
+ | `<osx-menu>` | Keyboard-oriented collections of application commands |
98
+ | `<osx-menu-item>` | Action and checkbox menu rows with optional shortcuts |
99
+ | `<osx-tabs>` | Related content panels with roving keyboard selection |
100
+ | `<osx-dialog>` | Centered modal with focus management and controlled actions |
101
+ | `<osx-ecosystem-card>` | Transparent first-party product discovery with provenance and host-owned tracking hooks |
102
+ | `<osx-empty-state>` | Zero-data guidance with an optional recovery action |
103
+ | `<osx-badge>` | Compact status, count, and category labels |
104
+ | `<osx-avatar>` | Initials, image fallback, and presence status |
105
+ | `<osx-heading>` | Semantic display, title, section, and label typography |
106
+ | `<osx-copy>` | Body copy with readable measures, sizes, tones, and emphasis |
107
+ | `<osx-link>` | Native navigation with external, download, and disabled states |
108
+ | `<osx-button>` | Default, primary, danger, loading, compact, and Lucide icon actions |
109
+ | `<osx-checkbox>` | Checked, mixed, disabled, and slotted-label states |
110
+ | `<osx-radio-group>` | Native single-choice forms with structured options, validation, and optional choice cards |
111
+ | `<osx-toggle>` | Immediate on/off settings with native switch semantics |
112
+ | `<osx-window>` | Window chrome, controls, toolbar and footer slots |
113
+ | `<osx-toolbar>` | Three-region application toolbar |
114
+ | `<osx-segmented-control>` | Accessible single-selection view control |
115
+ | `<osx-select>` | Native selection with structured options, validation, and OS X pop-up styling |
116
+ | `<osx-sheet>` | Window-attached confirmation and task dialog |
117
+ | `<osx-source-list>` | Finder-style application navigation |
118
+ | `<osx-split-view>` | Primary-detail horizontal or vertical layout |
119
+ | `<osx-status-bar>` | Readiness, activity, and connection state |
120
+ | `<osx-table>` | Responsive native data table with sortable columns and safe narrow-screen scrolling |
121
+ | `<osx-data-table>` | Searchable, sortable, selectable, paginated application data with client and server orchestration modes |
122
+ | `<osx-textarea>` | Labeled multi-line input with validation and controlled resize behavior |
123
+ | `<osx-text-field>` | Labeled text, email, password, search, telephone, and URL inputs with validation and optional Lucide icons |
124
+ | `<osx-progress>` | Determinate and indeterminate progress |
125
+
126
+ ## Events
127
+
128
+ Custom-element events expose Vue event arguments in `event.detail`. Form and selection events bubble through the document, cross shadow boundaries, and update the custom element's public `value` or `checked` property before listeners run.
129
+
130
+ ```js
131
+ document.querySelector("osx-segmented-control")
132
+ .addEventListener("change", (event) => console.log(event.detail[0]));
133
+ ```
134
+
135
+ `<osx-window>` emits `close`, `minimize`, and `zoom`. `<osx-sheet>` emits `close` and `confirm`. Selection and form components emit `change`; `<osx-text-field>` and `<osx-textarea>` also emit `input`, and `<osx-table>` emits `sort` with the selected key and direction. `<osx-app-shell>` emits `panel-resize` with the panel name and its pixel width so the host can persist a preference. `<osx-data-table>` emits `search`, `sort`, `page-change`, `page-size-change`, `selection-change`, and `row-activate`, allowing its client-side behavior to be replaced by server orchestration without changing the visual contract. `<osx-ecosystem-card>` emits `activate` with its product name, destination, and optional tracking ID. It never sends analytics or makes network requests itself; the host application decides whether and how to measure discovery.
136
+
137
+ ## Native forms
138
+
139
+ `<osx-text-field>`, `<osx-textarea>`, `<osx-select>`, `<osx-radio-group>`, `<osx-checkbox>`, and `<osx-toggle>` are form-associated custom elements. Named controls contribute to `FormData`, respect `required` and disabled fieldsets, expose standard validity methods, and restore their initial state on `form.reset()`. Checkbox and toggle values default to `on`. Use `<osx-button type="submit">` or `<osx-button type="reset">` for outer-form actions; the default type is `button`.
140
+
141
+ ```html
142
+ <form id="preferences">
143
+ <osx-text-field name="project" label="Project" required></osx-text-field>
144
+ <osx-checkbox name="telemetry" label="Share diagnostics"></osx-checkbox>
145
+ <osx-button type="submit" variant="primary">Save</osx-button>
146
+ </form>
147
+ ```
148
+
149
+ Agent events preserve backend neutrality. `<osx-agent-composer>` emits `input`, `submit`, and `stop`; `<osx-agent-approval>` emits `approve` and `reject`; `<osx-thinking>` emits `toggle`; `<osx-artifact>` emits `copy`, `download`, and `open`; `<osx-markdown>` emits `copy`; and citations coordinate through `activate` and `select`. `<osx-diff-viewer>` emits `view-change` and `copy`; `<osx-terminal>` emits `rerun`, `interrupt`, and `clear`; `<osx-file-tree>` emits `select` and `toggle`. `<osx-alert>` emits `dismiss`; `<osx-toast>` emits `dismiss` with either `manual` or `timeout` as its reason. Your application owns model calls, tool execution, permission policy, persistence, and streaming transport.
150
+
151
+ ## Icons
152
+
153
+ `<osx-icon>` is the library's shared icon contract. It exposes a curated 56-icon vocabulary from the maintained `@lucide/vue` package, using direct SVG component imports instead of an icon font. Icons share Lucide's consistent stroke geometry and support custom size, stroke width, and accessible labels. Decorative icons are hidden from assistive technology; pass `label` when an icon carries meaning.
154
+
155
+ Use `<osx-icon-button>` for icon-only actions. It requires an accessible label and standardizes small, medium, and large hit areas; pair unfamiliar actions with `<osx-tooltip>` for visible guidance. Standard `<osx-button>` actions accept `icon` and `icon-position` when an icon should reinforce a visible text label.
156
+
157
+ ## Agent workspace
158
+
159
+ The agent components are deliberately composable. The shell manages layout; it does not execute tools or call a model.
160
+
161
+ ```html
162
+ <osx-app-shell app-title="Project Agent" inspector-open resizable>
163
+ <nav slot="sidebar">...</nav>
164
+ <osx-agent-message message-role="assistant" author="Agent" model="Your model">
165
+ <p>I inspected the change and verified the focused test.</p>
166
+ </osx-agent-message>
167
+ <osx-agent-composer slot="composer" model="Provider · Model"></osx-agent-composer>
168
+ <aside slot="inspector">...</aside>
169
+ <osx-status-bar slot="status" label="Ready"></osx-status-bar>
170
+ </osx-app-shell>
171
+ ```
172
+
173
+ The shell fills a definite-height container and keeps oversized workspace content inside its scroll regions. Define the application height chain when the shell should occupy the viewport:
174
+
175
+ ```css
176
+ html,
177
+ body,
178
+ #app {
179
+ height: 100%;
180
+ }
181
+
182
+ osx-app-shell {
183
+ height: 100%;
184
+ }
185
+ ```
186
+
187
+ Use `height: 100dvh` on `<osx-app-shell>` when it is the viewport root. The component retains a 520px minimum height; on narrow screens its workspace remains independently scrollable, and the shell can scroll when the stacked regions exceed the assigned height.
188
+
189
+ ## Framework starters
190
+
191
+ The showcase includes shareable, URL-addressable starters for HTML, Vue, React, and Svelte. Choose a framework in the [Snippet Lab](https://osx-components.vercel.app/#snippets), copy the generated component shell, or share a URL such as `?framework=react#snippets`.
192
+
193
+ ## Component explorer
194
+
195
+ The [Component Explorer](https://osx-components.vercel.app/components) is a Storybook-style second entry point with searchable, deep-linkable, live examples of every published element. It is built from the same package entry point consumers install, so the stories exercise the actual Custom Elements API rather than a private Vue-only layer.
196
+
197
+ ## Development
198
+
199
+ ```bash
200
+ npm install
201
+ npm run dev
202
+ npm run check
203
+ npm run build:site
204
+ ```
205
+
206
+ The showcase deliberately consumes the library as native HTML elements. That keeps framework independence honest. `npm run build` creates the publishable component package in `dist`; `npm run build:site` creates the deployable showcase in `site-dist`.
207
+
208
+ ## Direction
209
+
210
+ The next useful components are breadcrumbs, date pickers, command palettes, disclosure groups, context meters, and inspector panels. Visual fidelity matters, but accessibility and predictable web behavior win when the two conflict.
211
+
212
+ ## License
213
+
214
+ MIT. “Mac,” “Mac OS,” and “OS X” are trademarks of Apple Inc. This independent project is not affiliated with or endorsed by Apple.
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import { cp, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
4
+ import { homedir } from "node:os";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
9
+ const skillName = "build-with-osx-components";
10
+ const skillSource = join(packageRoot, "skills", skillName);
11
+
12
+ function help() {
13
+ console.log(`OSX Components agent installer
14
+
15
+ Usage:
16
+ osx-components agent install [options]
17
+
18
+ Options:
19
+ --target <agents|codex|claude|opencode|cursor|auto|all>
20
+ --scope <project|user> Default: project
21
+ --cwd <path> Default: current directory
22
+ --force Replace an existing installed copy
23
+ --dry-run Print destinations without writing
24
+ --help Show this help
25
+
26
+ Examples:
27
+ npx @vraxis/osx-components agent install
28
+ npx @vraxis/osx-components agent install --target claude --scope user
29
+ npx @vraxis/osx-components agent install --target all --force
30
+ `);
31
+ }
32
+
33
+ async function exists(path) {
34
+ try { await stat(path); return true; }
35
+ catch { return false; }
36
+ }
37
+
38
+ function option(args, name, fallback) {
39
+ const index = args.indexOf(name);
40
+ return index >= 0 ? args[index + 1] : fallback;
41
+ }
42
+
43
+ function targetsFor(requested, cwd) {
44
+ const supported = ["agents", "codex", "claude", "opencode", "cursor"];
45
+ if (requested === "all") return supported;
46
+ if (requested !== "auto") return [requested];
47
+ const detected = supported.filter((target) => target !== "agents" && existsSync(join(cwd, `.${target}`)));
48
+ return detected.length ? detected : ["agents"];
49
+ }
50
+
51
+ function destinationFor(target, scope, cwd) {
52
+ const project = {
53
+ agents: join(cwd, ".agents", "skills", skillName),
54
+ codex: join(cwd, ".codex", "skills", skillName),
55
+ claude: join(cwd, ".claude", "skills", skillName),
56
+ opencode: join(cwd, ".opencode", "skills", skillName),
57
+ cursor: join(cwd, ".cursor", "rules", "osx-components.mdc"),
58
+ };
59
+ const user = {
60
+ agents: join(homedir(), ".agents", "skills", skillName),
61
+ codex: join(homedir(), ".codex", "skills", skillName),
62
+ claude: join(homedir(), ".claude", "skills", skillName),
63
+ opencode: join(homedir(), ".config", "opencode", "skills", skillName),
64
+ };
65
+ if (scope === "user" && target === "cursor") throw new Error("Cursor file-based rules are project scoped. Use --scope project.");
66
+ return (scope === "user" ? user : project)[target];
67
+ }
68
+
69
+ async function cursorRule() {
70
+ const skill = await readFile(join(skillSource, "SKILL.md"), "utf8");
71
+ const body = skill.replace(/^---[\s\S]*?---\s*/, "").replaceAll(/\[([^\]]+)\]\(references\/[^)]+\)/g, "$1 (bundled below)");
72
+ const references = ["component-selection.md", "framework-usage.md", "composition-patterns.md", "quality-standard.md"];
73
+ const bundled = await Promise.all(references.map(async (name) => `\n\n---\n\n${await readFile(join(skillSource, "references", name), "utf8")}`));
74
+ return `---\ndescription: Build and review interfaces with the osx-components design system\nglobs:\nalwaysApply: false\n---\n\n<!-- Generated from the osx-components ${skillName} skill. -->\n\n${body.trim()}${bundled.join("")}\n`;
75
+ }
76
+
77
+ async function install(target, scope, cwd, force, dryRun) {
78
+ const destination = destinationFor(target, scope, cwd);
79
+ if (dryRun) return { target, destination, state: "planned" };
80
+ if (await exists(destination)) {
81
+ if (!force) throw new Error(`${destination} already exists. Re-run with --force to update it.`);
82
+ await rm(destination, { recursive: true, force: true });
83
+ }
84
+ await mkdir(dirname(destination), { recursive: true });
85
+ if (target === "cursor") await writeFile(destination, await cursorRule(), "utf8");
86
+ else await cp(skillSource, destination, { recursive: true });
87
+ return { target, destination, state: "installed" };
88
+ }
89
+
90
+ const args = process.argv.slice(2);
91
+ if (args.includes("--help") || args.length === 0) { help(); process.exit(0); }
92
+ if (args[0] !== "agent" || args[1] !== "install") { help(); process.exitCode = 1; }
93
+ else {
94
+ const target = option(args, "--target", "agents");
95
+ const scope = option(args, "--scope", "project");
96
+ const cwd = resolve(option(args, "--cwd", process.cwd()));
97
+ const supported = new Set(["agents", "codex", "claude", "opencode", "cursor", "auto", "all"]);
98
+ if (!supported.has(target)) throw new Error(`Unsupported target: ${target}`);
99
+ if (!new Set(["project", "user"]).has(scope)) throw new Error(`Unsupported scope: ${scope}`);
100
+ const results = [];
101
+ for (const item of targetsFor(target, cwd)) results.push(await install(item, scope, cwd, args.includes("--force"), args.includes("--dry-run")));
102
+ for (const result of results) console.log(`${result.state === "planned" ? "Would install" : "Installed"} ${result.target}: ${result.destination}`);
103
+ }
@@ -0,0 +1 @@
1
+ :root,[data-osx-theme=aqua]{--osx-font: "Lucida Grande", "Helvetica Neue", Arial, sans-serif;--osx-text: #243b4a;--osx-muted: #526671;--osx-border: #8d9ba5;--osx-border-soft: #c6d0d6;--osx-surface: #f4f7f9;--osx-surface-raised: #ffffff;--osx-surface-sunken: #e4eaee;--osx-title-start: #eef3f6;--osx-title-end: #bdc8cf;--osx-accent: #006da8;--osx-accent-light: #75c8f5;--osx-success: #2f9951;--osx-warning: #c9821e;--osx-danger: #c74d47;--osx-focus: rgba(35, 145, 218, .32);--osx-shadow: 0 14px 38px rgba(31, 49, 61, .24), 0 2px 7px rgba(31, 49, 61, .2);--osx-highlight: rgba(255, 255, 255, .86);color-scheme:light}[data-osx-theme=graphite]{--osx-accent: #506978;--osx-accent-light: #a7bac6;--osx-focus: rgba(91, 121, 140, .32)}[data-osx-theme=panther]{--osx-text: #e5edf2;--osx-muted: #93a3ad;--osx-border: #52616b;--osx-border-soft: #354149;--osx-surface: #1b2328;--osx-surface-raised: #273138;--osx-surface-sunken: #11181c;--osx-title-start: #465159;--osx-title-end: #293138;--osx-accent: #1594d6;--osx-accent-light: #54bced;--osx-success: #42ae67;--osx-warning: #dfa23b;--osx-danger: #e16059;--osx-focus: rgba(59, 177, 233, .38);--osx-shadow: 0 16px 42px rgba(0, 0, 0, .52), 0 2px 7px rgba(0, 0, 0, .46);--osx-highlight: rgba(255, 255, 255, .13);color-scheme:dark}