diff --git a/CONVENTIONS.md b/CONVENTIONS.md index 1a9269c..6cc4981 100644 --- a/CONVENTIONS.md +++ b/CONVENTIONS.md @@ -72,6 +72,42 @@ validation in every shipped build. The client dropped them from its schema first (`.passthrough()` meant it ignored the ones still arriving), and only then did the payload stop carrying them. +## Bypassing a check means owning what it was doing + +Workflow files (`.amphi-workflow`) are offered for download from two tutorials. +The obvious spelling — a markdown link to a file sitting next to the page — +fails the build, and the error is actively misleading: + +``` +Found dead link ./downloads/%E4%B8%8A%E6%8A%A5...amphi-workflow +[vitepress] 3 dead link(s) found. +``` + +The files were **committed and present**. VitePress resolves a markdown link +against its page routes unless the extension is one it treats as an asset; +`.amphi-workflow` is not, so each link was read as a route, matched no page, and +`ignoreDeadLinks: false` turned that into a failed build. Reproduced by creating +the files and building: identical errors. Reading "dead link" as "file missing" +sends you looking in the wrong place — the fix is the *link*, not the file. + +What works: the file in `docs/public/` (copied to the site root untouched, no +pipeline to confuse), linked with a raw `` tag, carrying `download` — the +server recognises no extension here and sends an empty `Content-Type`, so a +browser may otherwise render the bytes instead of saving them. + +The part worth generalising is what raw HTML costs. The dead-link check only +parses markdown link syntax, so switching to `` gets the build passing by +**opting out of the check**, not by satisfying it. That trade is usually invisible +and always one-way: a typo in that href would now build clean, deploy clean, and +404 on click — strictly worse than the failure it replaced, which at least +announced itself. So `check:api` re-imposes the guarantee: every +`href="/downloads/..."` must exist under `docs/public` and must carry `download`. + +**When you route around a check, you inherit its job.** Three of this repo's +checks now exist for exactly that reason — links hardcoded in `config.ts`, pages +absent from the payload, and these download links — each one covering a place the +framework stopped looking. + ## The languages are allowed to diverge Both languages live under a prefix (`/zh/`, `/en/`) instead of one at the root, so diff --git a/README.md b/README.md index 69ad77d..13b7d76 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,38 @@ renders it so you can preview, `bun run build` drops it, and `check:api` does no ask for a payload entry. The reverse is enforced too: an entry may not point at a draft, since that would be a card leading to a 404. Rename when it is ready. +## Offering a file for download + +For anything the reader downloads rather than views — an exported +`.amphi-workflow`, a sample dataset — follow this exactly. The obvious way does +not work, and fails in a way that is easy to misread: + +1. Put the file in `docs/public/downloads/`, with an **ASCII name**. +2. Link it with a raw `` tag and the `download` attribute: + ```html + 上报开发任务 + ``` +3. `bun run check:api` + +Why each part, since none of it is guessable: + +- **`docs/public/`** is copied to the site root untouched. Under `docs/` the file + goes through the asset pipeline, which only recognises extensions it knows. +- **Raw ``, not `[text](link)`** — VitePress resolves a markdown link against + its *page routes* unless the extension is a known asset type. An unknown one is + read as a route, matches no page, and `ignoreDeadLinks: false` fails the build + **even though the file is right there**. The error says "dead link", which reads + like the file is missing; it is not. +- **`download`** — the server recognises no extension here and sends an empty + `Content-Type`, so without it a browser may render the bytes instead of saving + a file. +- **ASCII name** — a name with spaces or CJK does resolve once encoded, but the + emitted `href` carries the raw characters, and an unencoded request 404s. + +Raw HTML buys its way past the dead-link check, so `check:api` re-imposes it: +every `href="/downloads/..."` must exist under `docs/public` and carry +`download`. Otherwise a typo would build clean, deploy clean, and 404 on click. + ## Bilingual contract Both languages sit under a prefix (`/zh/`, `/en/`) rather than one at the root, so diff --git a/docs/public/api/workflows.zh.json b/docs/public/api/workflows.zh.json index ecf964b..dc463e0 100644 --- a/docs/public/api/workflows.zh.json +++ b/docs/public/api/workflows.zh.json @@ -12,7 +12,7 @@ { "id": "e-commerce-product-scraper", "name": "天猫超市商品抓取教程", - "desc": "演示从天猫超市抓取某一类商品信息并自动化下载商品图片", + "desc": "演示从天猫超市抓取某一类商品信息、自动化下载商品图片并批量存入excel文件中", "domain": "浏览器自动化", "status": "verified", "path": "zh/workflows/e-commerce-product-scraper" diff --git a/docs/public/downloads/bug-analysis-report.amphi-workflow b/docs/public/downloads/bug-analysis-report.amphi-workflow new file mode 100644 index 0000000..f94fcbb Binary files /dev/null and b/docs/public/downloads/bug-analysis-report.amphi-workflow differ diff --git a/docs/public/downloads/report-dev-task.amphi-workflow b/docs/public/downloads/report-dev-task.amphi-workflow new file mode 100644 index 0000000..a0bb283 Binary files /dev/null and b/docs/public/downloads/report-dev-task.amphi-workflow differ diff --git a/docs/public/downloads/tmall-snack-scraper.amphi-workflow b/docs/public/downloads/tmall-snack-scraper.amphi-workflow new file mode 100644 index 0000000..4e3492a Binary files /dev/null and b/docs/public/downloads/tmall-snack-scraper.amphi-workflow differ diff --git a/docs/zh/workflows/e-commerce-images/check-condition-1.webp b/docs/zh/workflows/e-commerce-images/check-condition-1.webp index 11c740f..5c529ea 100644 Binary files a/docs/zh/workflows/e-commerce-images/check-condition-1.webp and b/docs/zh/workflows/e-commerce-images/check-condition-1.webp differ diff --git a/docs/zh/workflows/e-commerce-images/check-condition-2.webp b/docs/zh/workflows/e-commerce-images/check-condition-2.webp index e756233..2aae09c 100644 Binary files a/docs/zh/workflows/e-commerce-images/check-condition-2.webp and b/docs/zh/workflows/e-commerce-images/check-condition-2.webp differ diff --git a/docs/zh/workflows/e-commerce-images/clarify-1.webp b/docs/zh/workflows/e-commerce-images/clarify-1.webp index b9c0949..583a433 100644 Binary files a/docs/zh/workflows/e-commerce-images/clarify-1.webp and b/docs/zh/workflows/e-commerce-images/clarify-1.webp differ diff --git a/docs/zh/workflows/e-commerce-images/clarify-2.webp b/docs/zh/workflows/e-commerce-images/clarify-2.webp index 626d7ca..0b2129f 100644 Binary files a/docs/zh/workflows/e-commerce-images/clarify-2.webp and b/docs/zh/workflows/e-commerce-images/clarify-2.webp differ diff --git a/docs/zh/workflows/e-commerce-images/clarify-3.webp b/docs/zh/workflows/e-commerce-images/clarify-3.webp index 0039c51..0d568c5 100644 Binary files a/docs/zh/workflows/e-commerce-images/clarify-3.webp and b/docs/zh/workflows/e-commerce-images/clarify-3.webp differ diff --git a/docs/zh/workflows/e-commerce-images/clarify-4.webp b/docs/zh/workflows/e-commerce-images/clarify-4.webp new file mode 100644 index 0000000..e45aa76 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/clarify-4.webp differ diff --git a/docs/zh/workflows/e-commerce-images/clarify-5.webp b/docs/zh/workflows/e-commerce-images/clarify-5.webp new file mode 100644 index 0000000..d1fd073 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/clarify-5.webp differ diff --git a/docs/zh/workflows/e-commerce-images/login-page.webp b/docs/zh/workflows/e-commerce-images/login-page.webp index a096b6b..105dc46 100644 Binary files a/docs/zh/workflows/e-commerce-images/login-page.webp and b/docs/zh/workflows/e-commerce-images/login-page.webp differ diff --git a/docs/zh/workflows/e-commerce-images/login-prompt.webp b/docs/zh/workflows/e-commerce-images/login-prompt.webp index b9f4015..cf78464 100644 Binary files a/docs/zh/workflows/e-commerce-images/login-prompt.webp and b/docs/zh/workflows/e-commerce-images/login-prompt.webp differ diff --git a/docs/zh/workflows/e-commerce-images/login-submit.webp b/docs/zh/workflows/e-commerce-images/login-submit.webp index f1b08a1..db6d859 100644 Binary files a/docs/zh/workflows/e-commerce-images/login-submit.webp and b/docs/zh/workflows/e-commerce-images/login-submit.webp differ diff --git a/docs/zh/workflows/e-commerce-images/new-task.webp b/docs/zh/workflows/e-commerce-images/new-task.webp index b111f6b..d9a8b8d 100644 Binary files a/docs/zh/workflows/e-commerce-images/new-task.webp and b/docs/zh/workflows/e-commerce-images/new-task.webp differ diff --git a/docs/zh/workflows/e-commerce-images/running-1.webp b/docs/zh/workflows/e-commerce-images/running-1.webp new file mode 100644 index 0000000..e48f437 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/running-1.webp differ diff --git a/docs/zh/workflows/e-commerce-images/running-excel.webp b/docs/zh/workflows/e-commerce-images/running-excel.webp new file mode 100644 index 0000000..0889642 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/running-excel.webp differ diff --git a/docs/zh/workflows/e-commerce-images/running-result.webp b/docs/zh/workflows/e-commerce-images/running-result.webp new file mode 100644 index 0000000..e31269f Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/running-result.webp differ diff --git a/docs/zh/workflows/e-commerce-images/running-success.webp b/docs/zh/workflows/e-commerce-images/running-success.webp new file mode 100644 index 0000000..7949d51 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/running-success.webp differ diff --git a/docs/zh/workflows/e-commerce-images/task-req-1.webp b/docs/zh/workflows/e-commerce-images/task-req-1.webp index 46849cf..a9972f5 100644 Binary files a/docs/zh/workflows/e-commerce-images/task-req-1.webp and b/docs/zh/workflows/e-commerce-images/task-req-1.webp differ diff --git a/docs/zh/workflows/e-commerce-images/task-req-2.webp b/docs/zh/workflows/e-commerce-images/task-req-2.webp index 0cb756f..f9c6847 100644 Binary files a/docs/zh/workflows/e-commerce-images/task-req-2.webp and b/docs/zh/workflows/e-commerce-images/task-req-2.webp differ diff --git a/docs/zh/workflows/e-commerce-images/task-req-second.webp b/docs/zh/workflows/e-commerce-images/task-req-second.webp new file mode 100644 index 0000000..54b0551 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/task-req-second.webp differ diff --git a/docs/zh/workflows/e-commerce-images/workflow-card.webp b/docs/zh/workflows/e-commerce-images/workflow-card.webp new file mode 100644 index 0000000..d51178f Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/workflow-card.webp differ diff --git a/docs/zh/workflows/e-commerce-images/workflow-created.webp b/docs/zh/workflows/e-commerce-images/workflow-created.webp new file mode 100644 index 0000000..e20b9a5 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/workflow-created.webp differ diff --git a/docs/zh/workflows/e-commerce-images/workflow-naming.webp b/docs/zh/workflows/e-commerce-images/workflow-naming.webp new file mode 100644 index 0000000..8f39474 Binary files /dev/null and b/docs/zh/workflows/e-commerce-images/workflow-naming.webp differ diff --git a/docs/zh/workflows/e-commerce-product-scraper.md b/docs/zh/workflows/e-commerce-product-scraper.md index 18969b6..9c33a9a 100644 --- a/docs/zh/workflows/e-commerce-product-scraper.md +++ b/docs/zh/workflows/e-commerce-product-scraper.md @@ -1,10 +1,26 @@ -# 【教程】自动采集天猫超市商品信息 (WIP) +# 【教程】自动采集天猫超市商品信息 -本教程介绍如何使用Bridgic Agent构建自动化工作流,从天猫超市抓取某一类的商品信息,包括自动化获取商品图片。 +本教程介绍如何使用Bridgic Agent构建自动化工作流,从天猫超市抓取某一类的商品信息(包括自动化获取商品图片),批量存入excel文件中。 本教程详细记录了该工作流的构建过程和运行过程。 ## 成品展示 +在本教程结束后,你将会看到一个成功构建的工作流: + +![工作流截图workflow-card.webp](./e-commerce-images/workflow-card.webp) + +该工作流可直接下载并导入进你的Bridgic Agent,作为参考: + + + +**注意**:由于每个人的电脑桌面运行环境不同,这个工作流未必能在导入后直接运行。仅作为参考,你可以参考它们制作自己真正需要的工作流。 +如果你一定要运行这个工作流,可以在运行碰到问题后,要求Bridgic Agent根据你的实际运行环境修复它即可。 + +你还会看到,运行该工作后产出的excel文件(里面存放着从天猫超市采集到的商品信息列表): + +![工作流截图running-excel.webp](./e-commerce-images/running-excel.webp) ## 工作流构建教程 @@ -28,6 +44,8 @@ Bridgic Agent对于需求中不明确的描述会主动和你确认(需求澄 ![工作流截图clarify-3.webp](./e-commerce-images/clarify-3.webp) +![工作流截图clarify-4.webp](./e-commerce-images/clarify-4.webp) + Bridgic Agent会提示你选择或确认任务的验收标准: ![工作流截图check-condition-1.webp](./e-commerce-images/check-condition-1.webp) @@ -56,15 +74,48 @@ Bridgic Agent发现天猫超市需要用户登录,所以弹框告知用户来 ![工作流截图login-submit.webp](./e-commerce-images/login-submit.webp) +Bridgic Agent在运行过程中又发现了一个需求澄清的点: + +![工作流截图clarify-5.webp](./e-commerce-images/clarify-5.webp) + +需求澄清后,Bridgic Agent会引导你第二次确认任务说明书的变动: + +![工作流截图task-req-second.webp](./e-commerce-images/task-req-second.webp) + +构建工作流的最后一步:给工作流取个名字。 + +![工作流截图workflow-naming.webp](./e-commerce-images/workflow-naming.webp) + +工作流创建成功! + +![工作流截图workflow-created.webp](./e-commerce-images/workflow-created.webp) + +这个新创建的工作流,以后你随时可以在工作流页面中找到它。工作流卡片如下: + +![工作流截图workflow-card.webp](./e-commerce-images/workflow-card.webp) + ### 运行工作流 +![工作流截图running-1.webp](./e-commerce-images/running-1.webp) -### 调度工作流 +![工作流截图running-success.webp](./e-commerce-images/running-success.webp) + +点击“查看结果”,可以看到刚才工作流的运行结果: + +![工作流截图running-result.webp](./e-commerce-images/running-result.webp) +可以把最后的excel表格下载出来,里面存放着从天猫超市采集到的商品信息列表(该示例批次为50个商品): +![工作流截图running-excel.webp](./e-commerce-images/running-excel.webp) + +### 调度工作流 +如果需要定期采集,可以使用Bridgic Agent提供的“调度”功能,来设置定时执行。此处略。 ## 注意事项 -修改工作流 +- 由于电脑本地的执行环境不同,你的构建过程可能也会碰到很多差异,未必跟以上记录的过程完全相同。具体的过程体验取决于环境和模型能力;建议使用好的模型来构建工作流,然后可以使用次一级的模型来运行它。 +- 构建过程中如果发生意外情况,不要慌张,可以随时向agent提问,请它提供更多信息或者让它给建议。在中间过程可以把碰到的问题/疑问都抛给Bridgic Agent。 +- Bridgic Agent对于工作流的构建,成功率非常高。只要需求描述清晰且可行,通常能够一次性成功。但偶尔出现失败的情况,也不要紧,可以让Bridgic Agent修复工作流。修复时告诉它你碰到的异常情况。 +- 工作流构建出来之后,并非一成不变,Bridgic Agent提供了强大的工作流修改能力。如果你需求有所变动,随时告诉Bridgic Agent:“修改 @XXX工作流,我要XXXX”。你可以不断优化自己的工作流,让它越来越精细,也越来越贴近你的需求。 diff --git a/docs/zh/workflows/github-trending/new-task-1.png b/docs/zh/workflows/github-trending/new-task-1.png new file mode 100644 index 0000000..6a9d593 Binary files /dev/null and b/docs/zh/workflows/github-trending/new-task-1.png differ diff --git a/docs/zh/workflows/github-trending/new-task-2.png b/docs/zh/workflows/github-trending/new-task-2.png new file mode 100644 index 0000000..55e6464 Binary files /dev/null and b/docs/zh/workflows/github-trending/new-task-2.png differ diff --git a/docs/zh/workflows/project-management-automation.md b/docs/zh/workflows/project-management-automation.md index 211c800..33b9afe 100644 --- a/docs/zh/workflows/project-management-automation.md +++ b/docs/zh/workflows/project-management-automation.md @@ -16,6 +16,18 @@ ![工作流截图workflow-card-2.webp](./pma-images/workflow-card-2.webp) +本教程产出的这两个自动化工作流,可直接下载并导入进Bridgic Agent,作为参考: + + + +**注意**:由于每个人的电脑桌面运行环境不同,这两个工作流未必能在导入后直接运行。仅作为参考,你可以参考它们制作自己真正需要的工作流。 +如果你一定要运行这两个工作流,可以在运行碰到问题后,要求Bridgic Agent根据你的实际运行环境修复它们即可。 + 还有一个定时调度任务: ![工作流截图scheduled-success-result.webp](./pma-images/scheduled-success-result.webp) @@ -32,7 +44,9 @@ ### 准备工作 -准备你自己的飞书账号,创建一个多维表格出来,用来保存和展示开发任务(新特性开发或Bug记录)。如下: +准备你自己的飞书账号,创建一个多维表格出来,用来保存和展示开发任务(新特性开发或Bug记录)。 + +注:创建多维表格其实也可以让Bridgic Agent来做,当因为初次连接飞书表格可能会有些麻烦,并且这是个一次性的操作,这里建议先用手工创建这个多维表格。如下: ![工作流截图table-creation.webp](./pma-images/table-creation.webp) @@ -187,7 +201,7 @@ Bridgic Agent提示你选择任务的验收标准: ## 注意事项 -- 用户本地的环境不同,构建过程可能也会碰到很多差异。可能需要根据具体情况来合理处理。尤其是这个工作流底层需要的lark-cli的安装和配置过程,具体的过程体验取决于环境和模型能力。建议使用好模型来构建工作流,然后可以使用次一些的模型来运行它。 +- 由于电脑本地的执行环境不同,你的构建过程可能也会碰到很多差异,未必跟以上记录的过程完全相同。你需要根据具体情况来合理处理,尤其是这个工作流底层需要的lark-cli的安装和配置过程,其具体的过程体验取决于环境和模型能力。建议使用好的模型来构建工作流,然后可以使用次一级的模型来运行它。 - 构建过程中如果发生意外情况,不要慌张,可以随时向agent提问,请它提供更多信息或者让它给建议。在中间过程可以把碰到的问题/疑问都抛给Bridgic Agent。 - Bridgic Agent对于工作流的构建,成功率非常高。只要需求描述清晰且可行,通常能够一次性成功。但偶尔出现失败的情况,也不要紧,可以让Bridgic Agent修复工作流。修复时告诉它你碰到的异常情况。 -- 工作流构建出来之后,并非一成不变,Bridgic Agent提供了强大的工作流修改能力。如果你需求有所变动,随时告诉Bridgic Agent:“修复 @XXX工作流,我要XXXX”。 +- 工作流构建出来之后,并非一成不变,Bridgic Agent提供了强大的工作流修改能力。如果你需求有所变动,随时告诉Bridgic Agent:“修改 @XXX工作流,我要XXXX”。你可以不断优化自己的工作流,让它越来越精细,也越来越贴近你的需求。 diff --git a/scripts/check-api.ts b/scripts/check-api.ts index c998847..53f1833 100644 --- a/scripts/check-api.ts +++ b/scripts/check-api.ts @@ -159,6 +159,35 @@ for (const link of configLinks) { } } +// --- download links in raw HTML point at files that exist ------------------- +// The same blind spot, one step further. A workflow file has to be linked with a +// raw `` tag: VitePress resolves markdown links against its page routes, and +// `.amphi-workflow` is not an extension it treats as an asset, so the markdown +// form is reported as a dead link and fails the build even when the file is +// right there. Raw HTML sidesteps that check -- and with it, every guarantee it +// was providing. A typo here would build clean, deploy clean, and 404 on click. +function checkDownloadLinks(lang: string): number { + const dir = join(DOCS, lang, 'workflows') + if (!existsSync(dir)) return 0 + let count = 0 + for (const name of readdirSync(dir)) { + if (!name.endsWith('.md')) continue + const source = readFileSync(join(dir, name), 'utf8') + for (const m of source.matchAll(/href="(\/downloads\/[^"]+)"/g)) { + count++ + const href = m[1] as string + if (!existsSync(join(DOCS, 'public', href.replace(/^\//, '')))) { + fail(`${lang}/workflows/${name} links to '${href}', which does not exist under docs/public`) + } + if (!/download(\s|=|>)/.test(source.slice(m.index ?? 0, (m.index ?? 0) + 200))) { + fail(`${lang}/workflows/${name}: '${href}' needs the \`download\` attribute -- the server sends no Content-Type for this extension`) + } + } + } + return count +} +const downloads = checkDownloadLinks('zh') + checkDownloadLinks('en') + // --- every workflow page is reachable from its own payload ------------------ // checkEntry already covers the other direction (an entry whose `path` points at // nothing). This catches the opposite slip: overwriting an entry when meaning to @@ -190,5 +219,5 @@ if (errors.length > 0) { console.log( `check-api: ok -- ${zh.length} zh / ${en.length} en workflows, ` + `${zhPages.length} zh / ${enPages.length} en pages all listed, ` + - `${seenLinks.size} config links resolve`, + `${seenLinks.size} config links resolve, ${downloads} download links resolve`, )