mcpField
C
create-html-app

create-html-app

github.com/bholmesdev开发7329 次安装13 周前更新
代码仓库

关于 create-html-app

Create HTML App 是用于 Hubble 的技能,指导在文件夹中创建单文件 HTML 交互界面。它面向构建工具、仪表板或小型应用的开发者,应用运行于沙盒中,并可通过 Hubble Files API 操作工作区 Markdown 文件。

主要功能

  1. 01以单个 HTML 文件构建界面
  2. 02使用 Hubble 提供的 Alpine 与 Tailwind
  3. 03在沙盒 iframe 中运行
  4. 04通过 Files API 读写工作区文件
  5. 05打开或创建 Markdown 文件

适用场景

  1. 01构建文件夹内的交互式工具
  2. 02制作读取工作区文件的仪表板
  3. 03创建可浏览并打开 Markdown 的界面

MCP 相关

输入未说明该技能与 MCP 的关系。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bholmesdev/hubble-skills --skill create-html-app

安装后在 Claude Code 中输入/create-html-app确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
buttons.md
files-api.md
forms.md
lists-and-empty-states.md
radio-selects.md
tabs.md

详细介绍

创建 HTML App

Hubble HTML App 是一个文件夹内的 .html 文件,Hubble 会将其作为独立的交互式 UI 运行。打开文件后,App 会显示在主内容面板中。你可以将任意交互体验——工具、仪表板或 App——构建为 Folder 中的单个 .html 文件。

要在 Markdown File 中内嵌 HTML App,请参阅 create-embed。

运行时

Hubble 提供 App 运行时。编写普通 HTML,并假设以下全局对象已可用:

  • hubble
  • Alpine
  • Tailwind browser v4
  • Hubble 主题令牌

默认使用 Alpine 和 Tailwind。不要添加依赖项 <script> 标签,也不要创建包文件、锁文件或 node_modules。

HTML App 在沙箱化的 iframe 中运行。Hubble 允许:

  • allow-scripts:Alpine、Tailwind browser 和 Hubble 运行时可以执行。
  • allow-forms:搭配 @submit.prevent 等 Alpine 处理程序时,原生 HTML 表单语义可正常工作。

Hubble 不允许:

  • allow-same-origin:App 保持不透明来源,无法使用 App 来源存储、Cookie 或同源访问。
  • allow-top-navigation:App 无法导航桌面应用框架。
  • allow-popups / allow-popups-to-escape-sandbox:App 无法打开未经沙箱限制的弹出窗口。
  • allow-downloads:App 无法直接启动下载。
  • allow-modals:App 无法使用浏览器模态对话框。

文件 API

App 通过 hubble.files 访问 Workspace 文件。这是一个异步代理,而非直接的文件系统访问方式。所有路径均相对于 Workspace,且指向 Markdown 文件。

await hubble.files.list("todos/*.md")
// → [{ name, path, modified_at, size }], sorted by path
await hubble.files.read("notes/today.md")
// → { path, body, properties }
await hubble.files.open("notes/today.md")
// → { path }, navigates the editor to the file
await hubble.files.create({ path, body, properties, open })
// → { path, body, properties }
await hubble.files.update(path, { body, properties })
// → { path, body, properties }, patch
await hubble.files.remove("notes/today.md")
// → { path }

方法失败时会抛出异常;每个方法都有对应的 safe* 变体。有关数据结构、补丁语义和错误处理,请参阅 文件 API。

模板

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<title>Folder files</title>
	</head>
	<body class="m-0 bg-background p-3 font-sans text-foreground">
		<main
			class="grid gap-3 rounded-md border border-border bg-card p-3 text-card-foreground"
			x-data="{
				files: [],
				error: '',
				async init() {
					try {
						this.files = await hubble.files.list('**/*.md')
					} catch (error) {
						this.error = error.message || 'Could not load files'
					}
				},
			}"
		>
			<header class="flex items-center justify-between gap-3">
				<h1 class="m-0 text-base font-semibold">Folder files</h1>
				<span class="text-sm text-muted-foreground" x-text="`${files.length} files`"></span>
			</header>

			<p class="m-0 text-sm text-muted-foreground" x-show="!error && files.length === 0">
				Loading files...
			</p>
			<p class="m-0 text-sm text-destructive" x-show="error" x-text="error"></p>

			<ul class="m-0 grid list-none gap-2 p-0" x-show="!error && files.length > 0">
				<template x-for="file in files" :key="file.path">
					<li class="rounded-sm border border-border bg-background px-3 py-2">
						<span class="text-sm font-medium" x-text="file.path"></span>
					</li>
				</template>
			</ul>
		</main>
	</body>
</html>

组织逻辑

对于简单状态(标志、计数器、当前标签页),内联 x-data 即可。对于更复杂的逻辑,例如异步加载器、多个方法或计算逻辑,请在 <script> 中注册 Alpine.data() 组件,并通过名称引用。

<script>
	document.addEventListener('alpine:init', () => {
		Alpine.data('fileList', () => ({
			files: [],
			error: '',
			async init() {
				try {
					this.files = await hubble.files.list('**/*.md')
				} catch (error) {
					this.error = error.message || 'Could not load files'
				}
			},
		}))
	})
</script>

<main x-data="fileList">…</main>

与大型内联表达式相比,这样做的优势:

  • Alpine 会将 x-data 解析为单个表达式。包含箭头函数、对象方法或 </>/& 的多行内容可能会被 HTML 转义或错误解析,导致无提示的“Alpine Expression Error”错误。
  • 逻辑位于真正的 JavaScript 中,支持语法高亮和常规引号,而不是写在属性字符串里。
  • 组件可复用、可测试,并能让标记保持易读。

在 alpine:init 中注册组件,确保 Alpine 扫描 DOM 前组件已就绪。

原生体验

通过 Tailwind 类使用 Hubble 令牌,让 App 的体验更贴近原生:

  • 表面:bg-background、bg-card、bg-popover
  • 文本:text-foreground、text-muted-foreground、text-card-foreground
  • 边框/环形:border-border、border-input、ring-ring、focus-visible:ring-ring
  • 操作:bg-primary text-primary-foreground、bg-secondary text-secondary-foreground
  • 状态:hover:bg-accent、bg-selected text-selected-foreground

保持紧凑的间距:gap-2、gap-3、p-2、p-3、px-3、py-2。控件使用 rounded-sm 或 rounded-md。

除非用户要求特定主题视觉效果,否则避免使用临时配色、过大的卡片、主视觉布局和装饰性渐变。

参考资料

只阅读你需要的模式:

评论

支持 Markdown