@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 +21 -0
- package/README.md +214 -0
- package/bin/osx-components.mjs +103 -0
- package/dist/osx-components.css +1 -0
- package/dist/osx-components.js +10060 -0
- package/package.json +81 -0
- package/skills/build-with-osx-components/SKILL.md +57 -0
- package/skills/build-with-osx-components/agents/openai.yaml +4 -0
- package/skills/build-with-osx-components/references/component-selection.md +72 -0
- package/skills/build-with-osx-components/references/composition-patterns.md +47 -0
- package/skills/build-with-osx-components/references/framework-usage.md +105 -0
- package/skills/build-with-osx-components/references/quality-standard.md +44 -0
- package/skills/build-with-osx-components/scripts/audit-osx-ui.mjs +71 -0
- package/types/index.d.ts +248 -0
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}
|