# portaljs - Doramagic AI Context Pack

> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。

## 充分原则

- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。
- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。

## 给宿主 AI 的使用方式

你正在读取 Doramagic 为 portaljs 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。

## Claim 消费规则

- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。
- **事实最低状态**：`supported`
- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。
- `weak`：只能作为低置信度线索，必须要求用户继续核实。
- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。
- `unverified`：不得作为事实使用，应明确说证据不足。
- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。

## 它最适合谁

- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0003` supported 0.86

## 它能做什么

- **多宿主安装与分发**（需要安装后验证）：项目包含插件或 marketplace 配置，说明它面向一个或多个 AI 宿主的安装和分发。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json` Claim：`clm_0001` supported 0.86
- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`.claude/INSTALL.md`, `README.md`, `packages/ckan-api-client-js/README.md`, `packages/ckan/README.md` Claim：`clm_0002` supported 0.86

## 怎么开始

- `curl -fsSL https://raw.githubusercontent.com/datopian/portaljs/main/scripts/install-portaljs-skills.sh | bash` 证据：`README.md` Claim：`clm_0004` supported 0.86
- `npx tiged datopian/portaljs/examples/portaljs-catalog my-portal` 证据：`README.md` Claim：`clm_0005` supported 0.86
- `npm i @portaljs/ckan` 证据：`packages/ckan/README.md` Claim：`clm_0006` supported 0.86, `clm_0007` supported 0.86
- `npm i @portaljs/ckan-api-client-js` 证据：`packages/ckan-api-client-js/README.md` Claim：`clm_0007` supported 0.86
- `/plugin marketplace add datopian/portaljs` 证据：`.claude/INSTALL.md` Claim：`clm_0008` supported 0.86
- `/plugin install portaljs@datopian-portaljs` 证据：`.claude/INSTALL.md` Claim：`clm_0009` supported 0.86

## 继续前判断卡

- **当前建议**：先做角色匹配试用
- **为什么**：这个项目更像角色库，核心风险是选错角色或把角色文案当执行能力；先用 Prompt Preview 试角色匹配，再决定是否沙盒导入。

### 30 秒判断

- **现在怎么做**：先做角色匹配试用
- **最小安全下一步**：先用 Prompt Preview 试角色匹配；满意后再隔离导入
- **先别相信**：角色质量和任务匹配不能直接相信。
- **继续会触碰**：角色选择偏差、命令执行、宿主 AI 配置

### 现在可以相信

- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0003` supported 0.86
- **能力存在：多宿主安装与分发**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json` Claim：`clm_0001` supported 0.86
- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`.claude/INSTALL.md`, `README.md`, `packages/ckan-api-client-js/README.md`, `packages/ckan/README.md` Claim：`clm_0002` supported 0.86
- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0004` supported 0.86

### 现在还不能相信

- **角色质量和任务匹配不能直接相信。**（unverified）：角色库证明有很多角色，不证明每个角色都适合你的具体任务，也不证明角色能产生高质量结果。
- **不能把角色文案当成真实执行能力。**（unverified）：安装前只能判断角色描述和任务画像是否匹配，不能证明它能在宿主 AI 里完成任务。
- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。
- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。
- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json`, `.claude/INSTALL.md`, `AGENTS.md` 等
- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。
- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json`
- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。

### 继续会触碰什么

- **角色选择偏差**：用户对任务应该由哪个专家角色处理的判断。 原因：选错角色会让 AI 从错误专业视角回答，浪费时间或误导决策。
- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`.claude/INSTALL.md`, `README.md`, `packages/ckan-api-client-js/README.md`, `packages/ckan/README.md`
- **宿主 AI 配置**：Claude/Codex/Cursor/Gemini/OpenCode 等宿主的 plugin、Skill 或规则加载配置。 原因：宿主配置会改变 AI 后续工作方式，可能和用户已有规则冲突。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json`, `.claude/INSTALL.md`, `AGENTS.md` 等
- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json`, `.claude/INSTALL.md`, `README.md` 等
- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。

### 最小安全下一步

- **先跑 Prompt Preview**：先用交互式试用验证任务画像和角色匹配，不要先导入整套角色库。（适用：任何项目都适用，尤其是输出质量未知时。）
- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）
- **先备份宿主 AI 配置**：Skill、plugin、规则文件可能改变 Claude/Cursor/Codex 的默认行为。（适用：存在插件 manifest、Skill 或宿主规则入口时。）
- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）

### 退出方式

- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。
- **准备移除宿主 plugin / Skill / 规则入口**：如果试装后行为异常，可以把宿主 AI 恢复到试装前状态。
- **保留原始角色选择记录**：如果输出偏题，可以回到任务画像阶段重新选择角色，而不是继续沿着错误角色推进。
- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。
- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。

## 哪些只能预览

- 解释项目适合谁和能做什么
- 基于项目文档演示典型对话流程
- 帮助用户判断是否值得安装或继续研究

## 哪些必须安装后验证

- 真实安装 Skill、插件或 CLI
- 执行脚本、修改本地文件或访问外部服务
- 验证真实输出质量、性能和兼容性

## 边界与风险判断卡

- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0010` inferred 0.45
- **宿主 AI 插件或 Skill 规则冲突**：新规则可能改变用户现有宿主 AI 的工作方式。 处理方式：安装前先检查插件 manifest 和 Skill 文件，必要时隔离测试。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json` Claim：`clm_0011` supported 0.86
- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`.claude/INSTALL.md`, `README.md`, `packages/ckan-api-client-js/README.md`, `packages/ckan/README.md` Claim：`clm_0012` supported 0.86
- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。
- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。
- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。

## 开工前工作上下文

### 加载顺序

- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。
- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。
- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。
- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。
- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。

### 任务路由

- **多宿主安装与分发**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`.claude-plugin/marketplace.json`, `.claude-plugin/plugin.json` Claim：`clm_0001` supported 0.86
- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`.claude/INSTALL.md`, `README.md`, `packages/ckan-api-client-js/README.md`, `packages/ckan/README.md` Claim：`clm_0002` supported 0.86

### 上下文规模

- 文件总数：1842
- 重要文件覆盖：40/1842
- 证据索引条目：80
- 角色 / Skill 条目：57

### 证据不足时的处理

- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。
- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。
- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。
- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。

## Prompt Recipes

### 适配判断

- 目标：判断这个项目是否适合用户当前任务。
- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。

```text
请基于 portaljs 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。
```

### 安装前体验

- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。
- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。

```text
请把 portaljs 当作安装前体验资产，而不是已安装工具或真实运行环境。

请严格输出四段：
1. 先问我 3 个必要问题。
2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。
3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。
4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。

硬性边界：
- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。
- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。
- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。
- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。
- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。
- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。

```

### 角色 / Skill 选择

- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。
- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。

```text
请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。
```

### 风险预检

- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。
- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。

```text
请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。
```

### 宿主 AI 开工指令

- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。
- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。

```text
请基于 portaljs 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。
```

## 角色 / Skill 索引

- 共索引 57 个角色 / Skill / 项目文档条目。

- **Changesets**（project_doc）：Hello and welcome! This folder has been automatically generated by @changesets/cli , a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it in our repository https://github.com/changesets/changesets 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.changeset/README.md`
- **Quickstart**（project_doc）：PortalJS The AI-native framework for building data portals. Describe the portal you want — your agent helps you choose an architecture, scaffolds it, and loads your data. Docs · Discussions · Report a bug 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`
- **Giftless on Cloudflare R2 — staging deployment**（project_doc）：Giftless on Cloudflare R2 — staging deployment 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`giftless/README.md`
- **Flowershow default template**（project_doc）：Flowershow default app template. Uses Next.js with Tailwind and MDX. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/README.md`
- **Deployment**（project_doc）：This is a repo intended to serve as an example of a data catalog that get its data from a CKAN Instance. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/ckan-ssg/README.md`
- **Getting Started**（project_doc）：This is a Next.js https://nextjs.org/ project bootstrapped with create-next-app https://github.com/vercel/next.js/tree/canary/packages/create-next-app . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/ckan/README.md`
- **How to use**（project_doc）：This example creates a portal/showcase for a single dataset. The dataset should be a Frictionless dataset data package fd i.e. there should be a datapackage.json . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/dataset-frictionless/README.md`
- **Data**（project_doc）：! goodtables.io https://goodtables.io/badge/github/datasets/country-codes.svg https://goodtables.io/github/datasets/country-codes 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/dataset-frictionless/public/country-codes/README.md`
- **Data**（project_doc）：CBOE Volatility Index VIX time-series dataset including daily open, close, high and low. The CBOE Volatility Index VIX is a key measure of market expectations of near-term volatility conveyed by S&P 500 stock index option prices introduced in 1993. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/dataset-frictionless/public/dataset/README.md`
- **PortalJS Demo replicating the FiveThirtyEight data portal**（project_doc）：PortalJS Demo replicating the FiveThirtyEight data portal 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/fivethirtyeight/README.md`
- **FiveThirtyEight Dataset Build Script**（project_doc）：FiveThirtyEight Dataset Build Script 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/fivethirtyeight/scripts/README.md`
- **A data catalog with data on GitHub**（project_doc）：This example showcases a simple data catalog that get its data from a list of GitHub repos that serve as datasets. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/github-backed-catalog/README.md`
- **Readme**（project_doc）：PortalJS Learn Example - https://portaljs.com/docs 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/learn/README.md`
- **A data catalog with data on GitHub**（project_doc）：This example showcases a simple data catalog that get its data from a list of GitHub repos that serve as datasets. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/openspending/README.md`
- **Readme**（project_doc）：Spending Data Handbook ====================== 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/openspending/content/resources/handbook/README.md`
- **PortalJS Catalog Template dynamic routes**（project_doc）：PortalJS Catalog Template dynamic routes 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/portaljs-catalog/README.md`
- **Metadata profiles**（project_doc）：The metadata-profile contract is the seam that defines how a dataset's schema and descriptive metadata are authored and surfaced. It sits beside the other two seams: 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/portaljs-catalog/lib/metadata/README.md`
- **Data providers**（project_doc）：The data-provider contract is the seam that keeps a PortalJS portal decoupled from where its data lives. The three surfaces — the home page, the /search catalog, and the /@ / showcase — read datasets only through a DataProvider . Swap the provider and the source of data changes without touching a single page. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/portaljs-catalog/lib/providers/README.md`
- **Data query the compute seam**（project_doc）：Where the data-provider contract ../providers answers which datasets exist , the data-query contract answers how to compute over a dataset's data — running SQL over it, beyond a flat-file preview. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/portaljs-catalog/lib/query/README.md`
- **PortalJS Template**（project_doc）：This is the canonical template used by the /portaljs-new-portal skill. It is a real Next.js project — you can run it directly. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/portaljs-template/README.md`
- **Getting started**（project_doc）：This demo d ata portal is designed for https://hatespeechdata.com. It catalogs datasets annotated for hate speech, online abuse, and offensive language which are useful for training a natural language processing system to detect this online abuse. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/turing/README.md`
- **Giftless on Cloudflare Containers — production host**（project_doc）：Giftless on Cloudflare Containers — production host 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`giftless/cloudflare/README.md`
- **CKAN API client - JavaScript**（project_doc）：Among other JS clients publicly available, the objectives of this one are: 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/ckan-api-client-js/README.md`
- **PortalJS CKAN Library**（project_doc）：This is a library intended for the use with a CKAN Backend, it is composed of: 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/ckan/README.md`
- **@portaljs/core**（project_doc）：Core Portal.JS package containing components, styles, and utils. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/core/README.md`
- **create-portaljs**（project_doc）：Scaffold a PortalJS https://github.com/datopian/portaljs data portal in one command. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`packages/create-portaljs/README.md`
- **Installing PortalJS skills**（project_doc）：PortalJS ships a set of Claude Code https://docs.claude.com/en/docs/claude-code skills that scaffold and extend data portals: /portaljs-new-portal , /portaljs-add-dataset , /portaljs-add-chart , /portaljs-add-map , and /portaljs-deploy . They run from any project — /portaljs-new-portal fetches the template from GitHub when you're not inside a clone of this repo. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.claude/INSTALL.md`
- **AGENTS.md**（project_doc）：The agent guide for this repository lives in CLAUDE.md ./CLAUDE.md — it's the single source of truth for conventions, repo structure, component selection, and how to build PortalJS data portals with an AI assistant. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`AGENTS.md`
- **PortalJS — AI Development Guide**（project_doc）：PortalJS is a Next.js framework for building data portals and catalogs. This file teaches AI assistants the conventions, patterns, and idioms used across this repo. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CLAUDE.md`
- **When to use it**（project_doc）：The advisory entry point — turns three questions about your needs into a concrete, scaffoldable architecture, then hands off to the build skills. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/docs/skills/portaljs-architect.md`
- **When to use it**（project_doc）：Wire a portal to a CKAN backend over its API instead of static files — the decoupled, any-backend path. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/docs/skills/portaljs-connect-ckan.md`
- **Hub-and-spoke**（project_doc）：Harvest datasets from a CKAN instance or a DCAT /data.json catalog into the static PortalJS catalog — the copy-into-the-portal path. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/docs/skills/portaljs-migrate.md`
- **When to use it**（project_doc）：Scaffold a production-ready PortalJS portal from a brief — a real, editable Next.js project you own. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/docs/skills/portaljs-new-portal.md`
- **Our repository**（project_doc）：https://github.com/datopian/datahub 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CONTRIBUTING.md`
- **How to contribute**（project_doc）：OpenSpending is a project that aims to make public financial data more accessible, understandable, and usable. It is powered by PortalJS, a framework for building data portals that are fast, secure, and easy to customize. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`examples/openspending/content/contributing.md`
- **PortalJS Skill Authoring Guide**（project_doc）：Skills live in .claude/commands/ OSS, no Datopian keys required or .claude/datopian/ Datopian-internal, requires API access . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.claude/AUTHORING.md`
- **Landing Page Design — portaljs.com**（project_doc）：Design brief for revamping the PortalJS website landing page. Derived from VISION.md VISION.md . This is the source of truth for the marketing site's homepage — copy, structure, and visual direction. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`DESIGN.md`
- **PortalJS Roadmap**（project_doc）：Direction and sequencing for the PortalJS revamp. Living document — decisions here are revisited as we learn. For the conceptual model behind the product, see Core concepts site/content/docs/core-concepts.md ; for the architecture decision layer, see the decision framework site/content/docs/architecture/decision-framework.md . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`ROADMAP.md`
- **PortalJS Vision**（project_doc）：PortalJS is becoming the AI-native framework for building data portals . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`VISION.md`
- **PortalJS skill-suite naming audit**（project_doc）：Status: inventory + recommendation no renames performed — see bead po-ok8 . Scope: the OSS agentic skills PortalJS ships into a user's Claude Code skill namespace. Gas Town internal commands done , handoff , review are excluded — they are not shipped see scripts/install-portaljs-skills.sh and .claude-plugin/plugin.json . Decision owners: Anu / Joao. STOP at the recommendation — the actual rename is a follow-up bead. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`docs/skill-naming-audit.md`
- **/connect-ckan → /portaljs-connect-ckan**（project_doc）：Renamed → /portaljs-connect-ckan. This alias will be removed next minor release. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.claude/commands/connect-ckan.md`
- **/portaljs-architect**（project_doc）：Recommend a data-portal architecture storage, compute, catalog, access, hosting, metadata from your needs, then hand off to the build skills. The advisory entry point. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.claude/commands/portaljs-architect.md`
- **/portaljs-connect-ckan**（project_doc）：Wire a scaffolded PortalJS portal to a CKAN backend over its API. Generates a tiny server-side fetch client no runtime dependency and feeds the /search catalog and /@ / showcases from CKAN instead of datasets.json. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.claude/commands/portaljs-connect-ckan.md`
- **/portaljs-migrate**（project_doc）：Migrate harvest datasets between open-data platforms. Reads CKAN, a DCAT-US /data.json catalog DKAN, ArcGIS Hub, data.gov , Socrata, OpenDataSoft, or an ArcGIS FeatureServer, and writes them to a static PortalJS catalog datasets.json, link-by-URL or download data files into Cloudflare R2 via Git LFS / Giftless or pushes them into a CKAN instance over its API. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.claude/commands/portaljs-migrate.md`
- **/portaljs-new-portal**（project_doc）：Scaffold a new PortalJS data portal from a brief. Copies the canonical template from examples/portaljs-catalog and substitutes project tokens. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`.claude/commands/portaljs-new-portal.md`
- **Introduction**（project_doc）：Learn how Scottish & Southern Electricity Networks partnered with us at Datopian to create a user-first open data portal that handles millions of data points daily, enhances energy management, and supports sustainable goals. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/case-studies/open-energy-data-how-ssen-tackled-massive-challenge-portaljs-ckan.md`
- **Profile**（project_doc）：Manage your PortalJS Cloud profile, password, plan, and API keys. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/account.md`
- **Browse datasets**（project_doc）：Browse, create, edit, and delete datasets and resources in PortalJS Cloud, including the DCAT metadata schema and table schema. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/datasets.md`
- **Sign up**（project_doc）：Create your PortalJS Cloud account, sign in, and find your way around the admin dashboard. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/getting-started.md`
- **Permissions**（project_doc）：Create and manage groups to categorize datasets in PortalJS Cloud. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/groups.md`
- **Supported sources**（project_doc）：Automatically sync datasets from external sources into PortalJS Cloud. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/harvesters.md`
- **Contents**（project_doc）：Administrator guide for PortalJS Cloud: manage datasets, organizations, users, visualizations, and your public portal. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/index.md`
- **Find your MCP URL**（project_doc）：Connect AI chatbots to your PortalJS Cloud portal through the MCP server. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/mcp-server.md`
- **The main organization**（project_doc）：Manage organizations, members, roles, and sysadmins in PortalJS Cloud. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/organizations.md`
- **How the portal works**（project_doc）：Deploy your public PortalJS Cloud portal, customize its repository, and understand what visitors see. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/portal.md`
- **Permissions**（project_doc）：Invite, edit, and remove users in your PortalJS Cloud portal. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/users.md`
- **Permissions**（project_doc）：Publish and manage visualizations and data apps in PortalJS Cloud. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`site/content/cloud/docs/visualizations.md`

## 证据索引

- 共索引 80 条证据。

- **Changesets**（documentation）：Hello and welcome! This folder has been automatically generated by @changesets/cli , a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it in our repository https://github.com/changesets/changesets 证据：`.changeset/README.md`
- **Quickstart**（documentation）：PortalJS The AI-native framework for building data portals. Describe the portal you want — your agent helps you choose an architecture, scaffolds it, and loads your data. Docs · Discussions · Report a bug 证据：`README.md`
- **Giftless on Cloudflare R2 — staging deployment**（documentation）：Giftless on Cloudflare R2 — staging deployment 证据：`giftless/README.md`
- **Flowershow default template**（documentation）：Flowershow default app template. Uses Next.js with Tailwind and MDX. 证据：`site/README.md`
- **Deployment**（documentation）：This is a repo intended to serve as an example of a data catalog that get its data from a CKAN Instance. 证据：`examples/ckan-ssg/README.md`
- **Getting Started**（documentation）：This is a Next.js https://nextjs.org/ project bootstrapped with create-next-app https://github.com/vercel/next.js/tree/canary/packages/create-next-app . 证据：`examples/ckan/README.md`
- **How to use**（documentation）：This example creates a portal/showcase for a single dataset. The dataset should be a Frictionless dataset data package fd i.e. there should be a datapackage.json . 证据：`examples/dataset-frictionless/README.md`
- **Data**（documentation）：! goodtables.io https://goodtables.io/badge/github/datasets/country-codes.svg https://goodtables.io/github/datasets/country-codes 证据：`examples/dataset-frictionless/public/country-codes/README.md`
- **Data**（documentation）：CBOE Volatility Index VIX time-series dataset including daily open, close, high and low. The CBOE Volatility Index VIX is a key measure of market expectations of near-term volatility conveyed by S&P 500 stock index option prices introduced in 1993. 证据：`examples/dataset-frictionless/public/dataset/README.md`
- **PortalJS Demo replicating the FiveThirtyEight data portal**（documentation）：PortalJS Demo replicating the FiveThirtyEight data portal 证据：`examples/fivethirtyeight/README.md`
- **FiveThirtyEight Dataset Build Script**（documentation）：FiveThirtyEight Dataset Build Script 证据：`examples/fivethirtyeight/scripts/README.md`
- **A data catalog with data on GitHub**（documentation）：This example showcases a simple data catalog that get its data from a list of GitHub repos that serve as datasets. 证据：`examples/github-backed-catalog/README.md`
- **Readme**（documentation）：PortalJS Learn Example - https://portaljs.com/docs 证据：`examples/learn/README.md`
- **A data catalog with data on GitHub**（documentation）：This example showcases a simple data catalog that get its data from a list of GitHub repos that serve as datasets. 证据：`examples/openspending/README.md`
- **Readme**（documentation）：Spending Data Handbook ====================== 证据：`examples/openspending/content/resources/handbook/README.md`
- **PortalJS Catalog Template dynamic routes**（documentation）：PortalJS Catalog Template dynamic routes 证据：`examples/portaljs-catalog/README.md`
- **Metadata profiles**（documentation）：The metadata-profile contract is the seam that defines how a dataset's schema and descriptive metadata are authored and surfaced. It sits beside the other two seams: 证据：`examples/portaljs-catalog/lib/metadata/README.md`
- **Data providers**（documentation）：The data-provider contract is the seam that keeps a PortalJS portal decoupled from where its data lives. The three surfaces — the home page, the /search catalog, and the /@ / showcase — read datasets only through a DataProvider . Swap the provider and the source of data changes without touching a single page. 证据：`examples/portaljs-catalog/lib/providers/README.md`
- **Data query the compute seam**（documentation）：Where the data-provider contract ../providers answers which datasets exist , the data-query contract answers how to compute over a dataset's data — running SQL over it, beyond a flat-file preview. 证据：`examples/portaljs-catalog/lib/query/README.md`
- **PortalJS Template**（documentation）：This is the canonical template used by the /portaljs-new-portal skill. It is a real Next.js project — you can run it directly. 证据：`examples/portaljs-template/README.md`
- **Getting started**（documentation）：This demo d ata portal is designed for https://hatespeechdata.com. It catalogs datasets annotated for hate speech, online abuse, and offensive language which are useful for training a natural language processing system to detect this online abuse. 证据：`examples/turing/README.md`
- **Giftless on Cloudflare Containers — production host**（documentation）：Giftless on Cloudflare Containers — production host 证据：`giftless/cloudflare/README.md`
- **CKAN API client - JavaScript**（documentation）：Among other JS clients publicly available, the objectives of this one are: 证据：`packages/ckan-api-client-js/README.md`
- **PortalJS CKAN Library**（documentation）：This is a library intended for the use with a CKAN Backend, it is composed of: 证据：`packages/ckan/README.md`
- **@portaljs/core**（documentation）：Core Portal.JS package containing components, styles, and utils. 证据：`packages/core/README.md`
- **create-portaljs**（documentation）：Scaffold a PortalJS https://github.com/datopian/portaljs data portal in one command. 证据：`packages/create-portaljs/README.md`
- **Installing PortalJS skills**（documentation）：PortalJS ships a set of Claude Code https://docs.claude.com/en/docs/claude-code skills that scaffold and extend data portals: /portaljs-new-portal , /portaljs-add-dataset , /portaljs-add-chart , /portaljs-add-map , and /portaljs-deploy . They run from any project — /portaljs-new-portal fetches the template from GitHub when you're not inside a clone of this repo. 证据：`.claude/INSTALL.md`
- **Marketplace**（structured_config）：{ "name": "datopian-portaljs", "owner": { "name": "Datopian", "url": "https://www.datopian.com" }, "metadata": { "description": "PortalJS agentic skills — build data portals with AI.", "version": "0.1.0" }, "plugins": { "name": "portaljs", "source": ".", "description": "Scaffold and extend PortalJS data portals: /portaljs-new-portal, /portaljs-add-dataset, /portaljs-add-chart, /portaljs-add-map, /portaljs-deploy." } } 证据：`.claude-plugin/marketplace.json`
- **Plugin**（structured_config）：{ "name": "portaljs", "version": "0.1.0", "description": "Agentic skills for building PortalJS data portals — recommend an architecture, scaffold a portal, add datasets, charts, and maps, connect a CKAN backend, deploy, and audit data quality.", "author": { "name": "Datopian", "url": "https://www.datopian.com" }, "homepage": "https://github.com/datopian/portaljs", "repository": "https://github.com/datopian/portaljs", "license": "MIT", "keywords": "portaljs", "data-portal", "ckan", "nextjs", "data-catalog" , "commands": "./.claude/commands/portaljs-architect.md", "./.claude/commands/portaljs-new-portal.md", "./.claude/commands/portaljs-add-dataset.md", "./.claude/commands/portaljs-add-resour… 证据：`.claude-plugin/plugin.json`
- **AGENTS.md**（documentation）：The agent guide for this repository lives in CLAUDE.md ./CLAUDE.md — it's the single source of truth for conventions, repo structure, component selection, and how to build PortalJS data portals with an AI assistant. 证据：`AGENTS.md`
- **PortalJS — AI Development Guide**（documentation）：PortalJS is a Next.js framework for building data portals and catalogs. This file teaches AI assistants the conventions, patterns, and idioms used across this repo. 证据：`CLAUDE.md`
- **When to use it**（documentation）：/portaljs-architect is the advisory skill. Before you scaffold anything, it works out what to build: from what you're building, what your data is, and what it's for, it recommends a concrete architecture across six slots — storage, catalog, compute, access, hosting, and metadata — then hands off to the build skills like /portaljs-new-portal /docs/skills/portaljs-new-portal . It decides ; it doesn't build. 证据：`site/content/docs/skills/portaljs-architect.md`
- **When to use it**（documentation）：/portaljs-connect-ckan connects an existing PortalJS portal to a live CKAN /ckan backend. The portal stops reading the static datasets.json manifest and /public/data/ files, and instead feeds both surfaces — the catalog at /search and the dataset showcases at /@ / — straight from a CKAN instance's REST API package search / package show through a tiny generated fetch client. The output is plain, editable Next.js code with no runtime dependency — no opaque framework wiring. 证据：`site/content/docs/skills/portaljs-connect-ckan.md`
- **Hub-and-spoke**（documentation）：/portaljs-migrate harvests datasets from an external open-data platform into an existing portaljs-catalog portal. It reads the source over its API, maps each dataset to the template's canonical shape, and writes the results into datasets.json — so the /search catalog and the /@ / showcases render them like any hand-added dataset. 证据：`site/content/docs/skills/portaljs-migrate.md`
- **When to use it**（documentation）：/portaljs-new-portal scaffolds a production-ready PortalJS data portal from a short brief. It copies the canonical lightweight template, substitutes your project tokens, installs dependencies, and verifies the build — so you start from a working project, not a blank page. 证据：`site/content/docs/skills/portaljs-new-portal.md`
- **Package**（package_manifest）：{ "name": "portaljs", "workspaces": "./packages/ " , "version": "0.0.0", "license": "MIT", "engines": { "node": " =22" }, "scripts": { "changeset": "changeset", "release": "changeset publish", "gen:skills": "node scripts/gen-skills-docs.mjs", "gen:skills:check": "node scripts/gen-skills-docs.mjs --check" }, "private": true, "devDependencies": { "@changesets/changelog-github": "^0.4.8", "@changesets/cli": "^2.26.1", "@types/node": "18.14.2", "@types/react": "18.0.28", "@types/react-dom": "18.0.11", "@typescript-eslint/eslint-plugin": "^5.36.1", "@typescript-eslint/parser": "^5.36.1", "eslint": "~8.15.0", "eslint-config-prettier": "8.1.0", "prettier": "^2.6.2", "typescript": "~4.9.5" } } 证据：`package.json`
- **Package**（package_manifest）：{ "name": "@flowershow/template", "private": true, "version": "1.0.0", "engines": { "node": " =20 <21" }, "scripts": { "dev": "npm run mddb && next dev", "build": "next build", "prebuild": "npm run mddb && node ./scripts/fix-symlinks.mjs", "postbuild": "next-sitemap && node ./scripts/generate-feeds.js", "start": "next start", "mddb": "mddb content", "smoke:markdown": "node ./scripts/smoke-markdown-pages.mjs" }, "dependencies": { "@docsearch/react": "^4.6.3", "@flowershow/remark-wiki-link": "^3.4.0", "@headlessui/react": "^2.2.10", "@heroicons/react": "^2.0.18", "@lottiefiles/react-lottie-player": "^3.6.0", "@portaljs/core": "^1.0.6", "@portaljs/remark-callouts": "^1.0.5", "@portaljs/remark-… 证据：`site/package.json`
- **Our repository**（documentation）：https://github.com/datopian/datahub 证据：`CONTRIBUTING.md`
- **Package**（package_manifest）：{ "name": "arc-api", "private": true, "type": "module", "scripts": { "test": "vitest run", "dev": "wrangler dev", "deploy": "wrangler deploy", "deploy:staging": "bash ../deploy.sh api staging", "deploy:prod": "bash ../deploy.sh api production", "migrations:check:prod": "bash ../deploy.sh api production --check", "typecheck": "tsc --noEmit", "migrate:staging": "wrangler d1 migrations apply portaljs-arc-staging --remote" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240909.0", "typescript": "^5.5.4", "vitest": "^2.1.1", "wrangler": "^3.78.0" } } 证据：`cloud/api/package.json`
- **Package**（package_manifest）：{ "name": "arc-auth", "private": true, "type": "module", "scripts": { "test": "vitest run", "dev": "wrangler dev", "deploy": "wrangler deploy", "deploy:staging": "bash ../deploy.sh auth staging", "deploy:prod": "bash ../deploy.sh auth production", "migrations:check:prod": "bash ../deploy.sh auth production --check", "typecheck": "tsc --noEmit" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240909.0", "typescript": "^5.5.4", "vitest": "^2.1.1", "wrangler": "^3.78.0" } } 证据：`cloud/auth/package.json`
- **Package**（package_manifest）：{ "name": "arc-router", "private": true, "type": "module", "scripts": { "test": "vitest run", "dev": "wrangler dev", "deploy": "wrangler deploy", "deploy:staging": "bash ../deploy.sh worker staging", "deploy:prod": "bash ../deploy.sh worker production", "migrations:check:prod": "bash ../deploy.sh worker production --check", "typecheck": "tsc --noEmit" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240909.0", "typescript": "^5.5.4", "vitest": "^2.1.1", "wrangler": "^3.78.0" } } 证据：`cloud/worker/package.json`
- **Package**（package_manifest）：{ "name": "my-app", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@heroicons/react": "^2.0.17", "@portaljs/ckan": "^0.0.2", "@portaljs/remark-wiki-link": "^1.0.4", "next": "13.3.1", "next-seo": "^6.0.0", "octokit": "^2.0.14", "react": "18.2.0", "react-dom": "18.2.0", "react-markdown": "^8.0.7", "remark-gfm": "^3.0.1" }, "devDependencies": { "@tailwindcss/typography": "^0.5.9", "@types/node": "18.16.0", "@types/react": "18.0.38", "@types/react-dom": "18.0.11", "autoprefixer": "^10.4.14", "eslint": "8.39.0", "eslint-config-next": "13.3.1", "postcss": "^8.4.23", "tailwindcss": "^3.3.1… 证据：`examples/ckan-ssg/package.json`
- **Package**（package_manifest）：{ "name": "ckan", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "prebuild": "npm run mddb", "build": "next build", "start": "next start", "lint": "next lint", "mddb": "mddb ./content" }, "dependencies": { "@githubocto/flat-ui": "^0.14.1", "@heroicons/react": "^2.0.18", "@portaljs/ckan": "^0.0.2", "@portaljs/components": "0.1.6", "@portaljs/core": "^1.0.5", "@portaljs/remark-callouts": "^1.0.5", "@portaljs/remark-embed": "^1.0.4", "@portaljs/remark-wiki-link": "^1.0.4", "@tailwindcss/typography": "^0.5.9", "@types/node": "20.2.3", "@types/react": "18.2.6", "@types/react-dom": "18.2.4", "autoprefixer": "10.4.14", "eslint": "8.41.0", "eslint-config-next": "13.4.3", "isom… 证据：`examples/ckan/package.json`
- **Package**（package_manifest）：{ "name": "portal", "description": "The data presentation framework", "author": "Datopian", "license": "MIT", "version": "0.1.0", "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "export": "yarn build && next export", "test": "jest --coverage" }, "dependencies": { "@tailwindcss/typography": "^0.4.0", "autoprefixer": "^10.0.4", "datapackage-render": "git+https://github.com/frictionlessdata/datapackage-render-js.git", "frictionless.js": "^0.13.4", "next": "latest", "portal": "https://github.com/datopian/portal.js.git 25f3c6b32a60c4f922394c85d2d7d03fe2cbc143", "postcss": "^8.2.10", "react": "^17.0.1", "react-dom": "^17.0.1", "remark": "^13.0.0", "remark-html": "^13… 证据：`examples/dataset-frictionless/package.json`
- **Package**（package_manifest）：{ "name": "fiverthirtyeight-example", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "build:datasets": "node scripts/build-datasets.js", "start": "next start", "lint": "next lint" }, "dependencies": { "@headlessui/react": "^1.7.14", "@heroicons/react": "^2.0.18", "@portaljs/components": "^0.1.8", "@portaljs/core": "^1.0.5", "@portaljs/remark-wiki-link": "^1.0.4", "@tailwindcss/typography": "^0.5.9", "@types/node": "20.1.1", "@types/react": "18.2.6", "@types/react-dom": "18.2.4", "autoprefixer": "10.4.14", "eslint": "8.40.0", "eslint-config-next": "13.4.1", "flexsearch": "^0.7.31", "next": "13.4.1", "next-mdx-remote": "^4.4.1", "next-seo": "^6.0.0… 证据：`examples/fivethirtyeight/package.json`
- **Package**（package_manifest）：{ "name": "my-app", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "prettier": "prettier --write ." }, "dependencies": { "@portaljs/components": "^0.1.6", "@portaljs/core": "^1.0.5", "@portaljs/remark-callouts": "^1.0.5", "@portaljs/remark-embed": "^1.0.4", "@portaljs/remark-wiki-link": "^1.0.4", "@types/node": "18.16.0", "@types/react": "18.0.38", "@types/react-dom": "18.0.11", "eslint": "8.39.0", "eslint-config-next": "13.3.1", "mddb": "^0.1.9", "next": "13.4.3", "next-mdx-remote": "^4.4.1", "next-seo": "^6.0.0", "octokit": "^2.0.14", "react": "18.2.0", "react-dom": "18.2.0", "react-markdown": "^8.0.7… 证据：`examples/github-backed-catalog/package.json`
- **Package**（package_manifest）：{ "name": "basic-example", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "export": "npm run build && next export -o out", "prebuild": "npm run mddb", "mddb": "mddb ./content" }, "dependencies": { "@githubocto/flat-ui": "^0.14.1", "@heroicons/react": "^2.0.17", "@opentelemetry/api": "^1.4.0", "@portaljs/components": "^0.1.8", "@portaljs/core": "^1.0.5", "@portaljs/remark-callouts": "^1.0.5", "@portaljs/remark-embed": "^1.0.4", "@portaljs/remark-wiki-link": "^1.0.4", "@tanstack/react-table": "^8.8.5", "flexsearch": "0.7.21", "gray-matter": "^4.0.3", "hastscript": "^7.2.0", "mddb": "^0.1.9", "mdx-mermaid"… 证据：`examples/learn/package.json`
- **Package**（package_manifest）：{ "name": "my-app", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "prebuild": "npm run mddb", "mddb": "mddb ./content", "test": "vitest" }, "dependencies": { "@githubocto/flat-ui": "^0.14.1", "@headlessui/react": "^1.7.14", "@heroicons/react": "^2.0.18", "@octokit/plugin-throttling": "^5.2.2", "@portaljs/ckan": "^0.0.2", "@portaljs/components": "0.1.12", "@portaljs/core": "^1.0.5", "@portaljs/remark-callouts": "^1.0.5", "@portaljs/remark-embed": "^1.0.4", "@portaljs/remark-wiki-link": "^1.0.4", "@tailwindcss/typography": "^0.5.9", "@types/flexsearch": "^0.7.3", "@types/node": "20.2.3", "@types/react":… 证据：`examples/openspending/package.json`
- **Package**（package_manifest）：{ "name": " PROJECT SLUG ", "version": "0.1.0", "private": true, "engines": { "node": " =22" }, "scripts": { "generate:dcat": "tsx scripts/generate-dcat.ts", "predev": "npm run generate:dcat", "dev": "next dev", "prebuild": "npm run generate:dcat", "build": "next build", "check-export": "node scripts/check-export.mjs", "start": "next start" }, "dependencies": { "@duckdb/duckdb-wasm": "^1.32.0", "@heroicons/react": "^2.0.0", "@tanstack/react-table": "^8.21.0", "next": "^16.2.7", "papaparse": "^5.4.0", "react": "^19.2.0", "react-dom": "^19.2.0" }, "devDependencies": { "@tailwindcss/typography": "^0.5.0", "@types/node": "^20.0.0", "@types/papaparse": "^5.3.0", "@types/react": "^19.0.0", "@type… 证据：`examples/portaljs-catalog/package.json`
- **Package**（package_manifest）：{ "name": " PROJECT SLUG ", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start" }, "dependencies": { "@heroicons/react": "^2.0.0", "@tanstack/react-table": "^8.21.0", "next": "14.2.35", "papaparse": "^5.4.0", "react": "18.3.1", "react-dom": "18.3.1" }, "devDependencies": { "@tailwindcss/typography": "^0.5.0", "@types/node": "^20.0.0", "@types/papaparse": "^5.3.0", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "autoprefixer": "^10.0.0", "postcss": "^8.0.0", "tailwindcss": "^3.0.0", "typescript": "^5.0.0" } } 证据：`examples/portaljs-template/package.json`
- **Package**（package_manifest）：{ "name": "tailwindui-template", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "prebuild": "npm run mddb", "mddb": "mddb ./content" }, "browserslist": "defaults, not ie <= 11", "dependencies": { "@headlessui/react": "^1.7.13", "@heroicons/react": "^2.0.17", "@mapbox/rehype-prism": "^0.8.0", "@mdx-js/loader": "^2.1.5", "@mdx-js/react": "^2.1.5", "@next/mdx": "^13.0.2", "@opentelemetry/api": "^1.4.0", "@portaljs/core": "^1.0.5", "@portaljs/remark-callouts": "^1.0.5", "@portaljs/remark-embed": "^1.0.4", "@portaljs/remark-wiki-link": "^1.0.4", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/typography": "^0.… 证据：`examples/turing/package.json`
- **Package**（package_manifest）：{ "name": "giftless-cloudflare", "version": "0.1.0", "private": true, "description": "Cloudflare Containers deploy of the Giftless LFS-on-R2 host production ", "scripts": { "deploy": "./scripts/deploy.sh", "smoke": "./scripts/smoke-remote.sh", "typecheck": "tsc --noEmit" }, "dependencies": { "@cloudflare/containers": "^0.3.7" }, "devDependencies": { "@cloudflare/workers-types": "^4.20250101.0", "typescript": "^5.5.0", "wrangler": "^4.0.0" } } 证据：`giftless/cloudflare/package.json`
- **Package**（package_manifest）：{ "name": "@portaljs/ckan-api-client-js", "version": "1.4.0", "description": "", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts", "engines": { "node": " =22" }, "scripts": { "test": "npm run build && mocha -r dotenv/config", "clean": "rimraf dist/ ", "build": "rollup -c", "prepare": "npm run build" }, "author": "Datopian Viderum Inc. trading as ", "license": "ISC", "devDependencies": { "@changesets/cli": "^2.27.7", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-typescript": "^11.1.6", "@types/node": "^20.14.2", "chai": "^5.2.0", "chai-as-promised": "^8.0.1", "dotenv": "^16.5.0", "mocha": "^11.4.0", "rimr… 证据：`packages/ckan-api-client-js/package.json`
- **Package**（package_manifest）：{ "name": "@portaljs/ckan", "version": "0.1.0", "type": "module", "engines": { "node": " =22" }, "description": "https://portaljs.com", "keywords": "data portal", "data catalog", "table", "charts", "visualization" , "scripts": { "build": "tsc && vite build && npm run build-tailwind", "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "build-tailwind": "NODE ENV=production npx tailwindcss -o ./dist/styles.css --minify", "prepare": "npm run build" }, "peerDependencies": { "react": "^18.2.0", "react-dom": "^18.2.0" }, "files": "dist" , "devDependencies": { "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@typescript-eslint/eslint-plugin": "^5.57.… 证据：`packages/ckan/package.json`
- **Package**（package_manifest）：{ "name": "@portaljs/core", "version": "1.0.9", "description": "Core Portal.JS components, configs and utils.", "engines": { "node": " =22" }, "repository": { "type": "git", "url": "git+https://github.com/datopian/portaljs.git", "directory": "packages/core" }, "author": "Rufus Pollock", "license": "MIT", "bugs": { "url": "https://github.com/datopian/portaljs/issues" }, "homepage": "https://github.com/datopian/portaljs readme", "publishConfig": { "access": "public" }, "scripts": { "clean": "rimraf dist", "build": "rollup -c rollup.config.mjs", "prepare": "npm run build" }, "files": "dist" , "type": "module", "module": "./dist/index.js", "types": "./dist/src/index.d.ts", "exports": { ".": { "… 证据：`packages/core/package.json`
- **Package**（package_manifest）：{ "name": "create-portaljs", "version": "0.6.0", "description": "Scaffold a PortalJS data portal — npm create portaljs@latest", "type": "module", "bin": { "create-portaljs": "index.mjs" }, "files": "index.mjs", "README.md" , "engines": { "node": " =22" }, "keywords": "portaljs", "data-portal", "create", "scaffold", "cli", "nextjs" , "homepage": "https://github.com/datopian/portaljs/tree/main/packages/create-portaljs", "repository": { "type": "git", "url": "https://github.com/datopian/portaljs.git", "directory": "packages/create-portaljs" }, "license": "MIT", "publishConfig": { "access": "public" }, "dependencies": { "giget": "^1.2.3", "prompts": "^2.4.2" } } 证据：`packages/create-portaljs/package.json`
- **How to contribute**（documentation）：OpenSpending is a project that aims to make public financial data more accessible, understandable, and usable. It is powered by PortalJS, a framework for building data portals that are fast, secure, and easy to customize. 证据：`examples/openspending/content/contributing.md`
- **License**（source_file）：Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files the "Software" , to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 证据：`license`
- **PortalJS Skill Authoring Guide**（documentation）：Skills live in .claude/commands/ OSS, no Datopian keys required or .claude/datopian/ Datopian-internal, requires API access . 证据：`.claude/AUTHORING.md`
- **Landing Page Design — portaljs.com**（documentation）：Design brief for revamping the PortalJS website landing page. Derived from VISION.md VISION.md . This is the source of truth for the marketing site's homepage — copy, structure, and visual direction. 证据：`DESIGN.md`
- 其余 20 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。

## 宿主 AI 必须遵守的规则

- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`.changeset/README.md`, `README.md`, `giftless/README.md`
- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`.changeset/README.md`, `README.md`, `giftless/README.md`

## 用户开工前应该回答的问题

- 你准备在哪个宿主 AI 或本地环境中使用它？
- 你只是想先体验工作流，还是准备真实安装？
- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？

## 验收标准

- 所有能力声明都能回指到 evidence_refs 中的文件路径。
- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。
- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。

---

## Doramagic Context Augmentation

下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。

## Human Manual 骨架

使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。

宿主 AI 硬性规则：
- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。
- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。
- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。

- **概览与快速上手**：importance `high`
  - source_paths: README.md, VISION.md, ROADMAP.md, packages/create-portaljs/index.mjs, packages/create-portaljs/README.md
- **系统架构与数据流**：importance `high`
  - source_paths: DESIGN.md, examples/portaljs-catalog/lib/providers/index.ts, examples/portaljs-catalog/lib/providers/static-provider.ts, examples/portaljs-catalog/lib/providers/types.ts, examples/portaljs-catalog/lib/metadata/index.ts
- **代理技能与 AI 集成**：importance `high`
  - source_paths: .claude-plugin/plugin.json, .claude-plugin/marketplace.json, .claude/INSTALL.md, .claude/AUTHORING.md, .claude/commands/portaljs-architect.md
- **后端集成、扩展与部署**：importance `high`
  - source_paths: packages/ckan/src/index.ts, packages/ckan/src/lib/ckanapi.tsx, packages/ckan/src/components/DatasetCard.tsx, packages/ckan/src/components/DatasetSearchForm.tsx, packages/ckan-api-client-js/src/index.ts

## Repo Inspection Evidence / 源码检查证据

- repo_clone_verified: true
- repo_inspection_verified: true
- repo_commit: `09390877b14c2522a07433f06c6b33e4d4aa031b`
- inspected_files: `README.md`, `package.json`, `docs/skill-naming-audit.md`, `examples/ckan/.eslintrc.json`, `examples/ckan/README.md`, `examples/ckan/content/test.md`, `examples/ckan/lib/markdown.js`, `examples/ckan/lib/mddb.ts`, `examples/ckan/next.config.js`, `examples/ckan/package-lock.json`, `examples/ckan/package.json`, `examples/ckan/pages/api/cors.ts`, `examples/ckan/postcss.config.js`, `examples/ckan/tailwind.config.js`, `examples/ckan/tsconfig.json`, `examples/ckan-ssg/.eslintrc.json`, `examples/ckan-ssg/README.md`, `examples/ckan-ssg/index.d.ts`, `examples/ckan-ssg/next-env.d.ts`, `examples/ckan-ssg/next.config.js`

宿主 AI 硬性规则：
- 没有 repo_clone_verified=true 时，不得声称已经读过源码。
- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。
- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。

## Doramagic Pitfall Constraints / 踩坑约束

这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。

### Constraint 1: 可能修改宿主 AI 配置

- Trigger: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- Host AI rule: 列出会写入的配置文件、目录和卸载/回滚步骤。
- Why it matters: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- Evidence: capability.host_targets | https://github.com/datopian/portaljs | host_targets=claude_code, claude
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 2: 能力判断依赖假设

- Trigger: README/documentation is current enough for a first validation pass.
- Host AI rule: 将假设转成下游验证清单。
- Why it matters: 假设不成立时，用户拿不到承诺的能力。
- Evidence: capability.assumptions | https://github.com/datopian/portaljs | README/documentation is current enough for a first validation pass.
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 3: 来源证据：Feedback on research.portaljs.com

- Trigger: GitHub 社区证据显示该项目存在一个运行相关的待验证问题：Feedback on research.portaljs.com
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/datopian/portaljs/issues/1618 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 4: 维护活跃度未知

- Trigger: 未记录 last_activity_observed。
- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。
- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- Evidence: evidence.maintainer_signals | https://github.com/datopian/portaljs | last_activity_observed missing
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

- Trigger: no_demo
- Evidence: downstream_validation.risk_items | https://github.com/datopian/portaljs | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 6: 存在评分风险

- Trigger: no_demo
- Why it matters: 风险会影响是否适合普通用户安装。
- Evidence: risks.scoring_risks | https://github.com/datopian/portaljs | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 7: 来源证据：Add 6 new FAQs in FAQ page

- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add 6 new FAQs in FAQ page
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能影响升级、迁移或版本选择。
- Evidence: community_evidence:github | https://github.com/datopian/portaljs/issues/1502 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 8: issue/PR 响应质量未知

- Trigger: issue_or_pr_quality=unknown。
- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。
- Why it matters: 用户无法判断遇到问题后是否有人维护。
- Evidence: evidence.maintainer_signals | https://github.com/datopian/portaljs | issue_or_pr_quality=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 9: 发布节奏不明确

- Trigger: release_recency=unknown。
- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。
- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。
- Evidence: evidence.maintainer_signals | https://github.com/datopian/portaljs | release_recency=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。
