Skip to content

Commit 3f392fe

Browse files
louis-preclaudeseambot
authored
ci: Add orphan page validator, move 24 orphan pages to trash/ (#1092)
* ci: Add orphan page validator and move 24 orphan pages to trash/ Add validate-orphan-pages CI check that verifies every markdown page in each site section is referenced in its SUMMARY.md. Move 24 existing orphan pages to trash/ to pass the new check. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci: Format code * fix: Remove broken link to trashed Android mobile components page Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Seam Bot <seambot@getseam.com>
1 parent 74bd840 commit 3f392fe

28 files changed

Lines changed: 213 additions & 113 deletions

.github/workflows/generate.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,5 @@ jobs:
8282
run: npm run validate-paths
8383
- name: Validate cross-site links
8484
run: npm run validate-links
85+
- name: Validate all pages are in SUMMARY.md
86+
run: npm run validate-orphan-pages

codegen/validate-orphan-pages.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { readdirSync, readFileSync } from 'node:fs'
2+
import { join, relative } from 'node:path'
3+
4+
import { siteSections } from './lib/config.js'
5+
6+
// Matches markdown links in SUMMARY.md: [Title](path/to/file.md)
7+
const summaryLinkPattern = /\[([^\]]*)\]\(([^)]+)\)/g
8+
9+
function walkDir(dir: string): string[] {
10+
const files: string[] = []
11+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
12+
const fullPath = join(dir, entry.name)
13+
if (entry.isDirectory()) {
14+
// Skip .gitbook directories (assets, includes, etc.)
15+
if (entry.name === '.gitbook') continue
16+
files.push(...walkDir(fullPath))
17+
} else if (entry.name.endsWith('.md')) {
18+
// Skip underscore-prefixed files (e.g., _report.md)
19+
if (entry.name.startsWith('_')) continue
20+
// Skip SUMMARY.md itself
21+
if (entry.name === 'SUMMARY.md') continue
22+
files.push(fullPath)
23+
}
24+
}
25+
return files
26+
}
27+
28+
interface OrphanPage {
29+
section: string
30+
path: string
31+
}
32+
33+
const orphans: OrphanPage[] = []
34+
35+
for (const section of siteSections) {
36+
const summaryPath = join(section.root, 'SUMMARY.md')
37+
const contents = readFileSync(summaryPath, 'utf-8')
38+
39+
// Collect all file paths referenced in SUMMARY.md
40+
const referencedPaths = new Set<string>()
41+
for (const match of contents.matchAll(summaryLinkPattern)) {
42+
const linkPath = match[2] ?? ''
43+
if (linkPath.startsWith('http') || linkPath.startsWith('#')) continue
44+
// Strip anchor fragments
45+
const cleanPath = linkPath.split('#')[0] ?? ''
46+
if (cleanPath !== '') {
47+
referencedPaths.add(cleanPath)
48+
}
49+
}
50+
51+
// Walk all markdown files in this section
52+
const allPages = walkDir(section.root)
53+
54+
for (const fullPath of allPages) {
55+
const relPath = relative(section.root, fullPath)
56+
if (!referencedPaths.has(relPath)) {
57+
orphans.push({ section: section.name, path: relPath })
58+
}
59+
}
60+
}
61+
62+
if (orphans.length > 0) {
63+
// Group by section
64+
const bySection = new Map<string, string[]>()
65+
for (const { section, path } of orphans) {
66+
const existing = bySection.get(section) ?? []
67+
existing.push(path)
68+
bySection.set(section, existing)
69+
}
70+
71+
// eslint-disable-next-line no-console
72+
console.error(
73+
`Found ${orphans.length} page(s) not referenced in SUMMARY.md:\n`,
74+
)
75+
for (const [section, paths] of bySection) {
76+
// eslint-disable-next-line no-console
77+
console.error(` [${section}]`)
78+
for (const p of paths) {
79+
// eslint-disable-next-line no-console
80+
console.error(` ${p}`)
81+
}
82+
// eslint-disable-next-line no-console
83+
console.error('')
84+
}
85+
// eslint-disable-next-line no-console
86+
console.error(
87+
'Either add these pages to SUMMARY.md or move them to the trash/ folder.',
88+
)
89+
process.exit(1)
90+
} else {
91+
// eslint-disable-next-line no-console
92+
console.log('All pages are referenced in SUMMARY.md.')
93+
}

docs/guides/ui-components/seam-mobile-components/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ Seam Mobile Components are pre-built views that let you deliver end-user access
2222

2323
### Platform Guides
2424

25-
<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>iOS Guide</strong><br>Integrate Seam Mobile Components into your iOS app</td><td><a href="../../.gitbook/assets/image (35).png">image (35).png</a></td><td><a href="seam-mobile-components-for-ios/">seam-mobile-components-for-ios</a></td></tr><tr><td><strong>Android Guide</strong><br>Integrate Seam Mobile Components into your Android app</td><td><a href="../../.gitbook/assets/android_logo.png">android_logo.png</a></td><td><a href="seam-mobile-components-for-android/">seam-mobile-components-for-android</a></td></tr></tbody></table>
25+
<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>iOS Guide</strong><br>Integrate Seam Mobile Components into your iOS app</td><td><a href="../../.gitbook/assets/image (35).png">image (35).png</a></td><td><a href="seam-mobile-components-for-ios/">seam-mobile-components-for-ios</a></td></tr></tbody></table>

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"postgenerate": "npm run format",
1919
"validate-paths": "tsx codegen/validate-paths.ts",
2020
"validate-links": "tsx codegen/validate-links.ts",
21+
"validate-orphan-pages": "tsx codegen/validate-orphan-pages.ts",
2122
"typecheck": "tsc",
2223
"lint": "eslint .",
2324
"postlint": "prettier --check --ignore-path .prettierignore .",

docs/brand-guides/smartthings-hubs-+-smart-locks.md renamed to trash/brand-guides/smartthings-hubs-+-smart-locks.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,30 @@ description: Guide for using SmartThings hubs + smart locks with Seam
88

99
[SmartThings Hubs](https://www.samsung.com/fr/smartthings/) are connected to your local network using either Wi-Fi or Ethernet. You pair smart locks to SmartThings hubs using Zigbee or Z-Wave. Them, you can unlock and lock these smart locks remotely, and you can program access codes on them for keyless entry.
1010

11-
***
11+
---
1212

1313
## Supported Devices
1414

1515
This integration supports the SmartThings hub and door locks paired with it.
1616

1717
For detailed information about the SmartThings hubs that Seam supports, see our [SmartThings Supported Devices page](https://www.seam.co/manufacturers/smartthings).
1818

19-
***
19+
---
2020

2121
## Supported Features
2222

2323
We support the following features:
2424

25-
* [Triggering web lock and unlock actions](https://docs.seam.co/latest/capability-guides/smart-locks/lock-and-unlock) on paired smart locks that support this feature
26-
* [Programming access codes](https://docs.seam.co/latest/capability-guides/smart-locks/access-codes) on paired smart locks that support this feature
25+
- [Triggering web lock and unlock actions](https://docs.seam.co/latest/capability-guides/smart-locks/lock-and-unlock) on paired smart locks that support this feature
26+
- [Programming access codes](https://docs.seam.co/latest/capability-guides/smart-locks/access-codes) on paired smart locks that support this feature
2727

28-
***
28+
---
2929

3030
### Device Provider Key
3131

3232
To create a [Connect Webview](https://docs.seam.co/latest/core-concepts/connect-webviews) that enables your users to connect their August devices to Seam, include the `smartthings` device provider key in the `accepted_providers` list. For more information, see [Customize the Brands to Display in Your Connect Webviews](https://docs.seam.co/latest/core-concepts/connect-webviews/customizing-connect-webviews#customize-the-brands-to-display-in-your-connect-webviews).
3333

34-
***
34+
---
3535

3636
## Setup Instructions
3737

@@ -41,7 +41,7 @@ To control SmartThings-connected devices using Seam, you must prompt owners of t
4141
2. Follow [these instructions](https://www.samsung.com/ca/support/mobile-devices/smartthings-how-to-set-up-your-hub/) to pair your devices to the SmartThings hub.
4242
3. Note your login credentials for the SmartThings app, and use these credentials to log in to the [Seam Connect Webview](https://docs.seam.co/latest/core-concepts/connect-webviews) to add your devices to Seam.
4343

44-
***
44+
---
4545

4646
## Brand-Specific Features
4747

@@ -51,12 +51,12 @@ Note the following SmartThings-specific features:
5151

5252
For SmartThings-connected devices, you can report the set of supported access code lengths or the minimum and maximum supported code lengths. For details, see [Report Device Access Code Constraints](https://docs.seam.co/latest/api/access_codes/report_device_constraints).
5353

54-
***
54+
---
5555

5656
## Where to Order
5757

5858
To order SmartThings hubs, see the Aeotec **Where to buy** page.
5959

6060
<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td></td><td><strong>Aeotec Where to buy page</strong></td><td></td><td><a href="https://aeotec.com/where-to-buy/">https://aeotec.com/where-to-buy/</a></td><td><a href=".gitbook/assets/smartthings-logo.png">smartthings-logo.png</a></td></tr></tbody></table>
6161

62-
***
62+
---
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,3 @@ We're here for you every step of the way!
1010
:computer: [Contact Support](mailto:support@seam.co)
1111

1212
:wave: [Contact Sales](https://www.seam.co/contact-us)
13-

docs/guides/core-concepts/device-capabilities.md renamed to trash/guides/core-concepts/device-capabilities.md

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,21 @@ For example, a battery-powered door lock with a pin-pad such as Yale Assure woul
88

99
Seam exposes each capability as a set of APIs. Furthermore, those APIs are standardized across brands for ease of integration.
1010

11-
12-
1311
![](<../.gitbook/assets/image (10).png>)
1412

1513
### Capabilities -> Actions, Properties, and Events
1614

1715
Each device capability decomposes into 3 sets of affordances:&#x20;
1816

19-
* **Actions** — things you can do to it.&#x20;
20-
* **Properties** — the current state of the device.
21-
* **Events** — reports from the device describing state transitions.&#x20;
17+
- **Actions** — things you can do to it.&#x20;
18+
- **Properties** — the current state of the device.
19+
- **Events** — reports from the device describing state transitions.&#x20;
2220

2321
For example, the `lock` capability decomposes in the following manner:
2422

25-
* **Actions:** `UNLOCK` and `LOCK`
26-
* **Properties:** a `locked` status to determine the lock's current status
27-
* **Events:** a list of lock/unlock events logging all of the lock's transitions.
23+
- **Actions:** `UNLOCK` and `LOCK`
24+
- **Properties:** a `locked` status to determine the lock's current status
25+
- **Events:** a list of lock/unlock events logging all of the lock's transitions.
2826

2927
### Standardizing Capabilities Across Device Brands
3028

@@ -36,9 +34,4 @@ For example, some door locks with the `access_codes` capability require differen
3634

3735
In those instances, we attempt to handle these differences for you. For example, we will generate and set a pin code of the appropriate length. However, you may wish to set your own code. We let you do so, but it must meet the constraints set by the device.
3836

39-
40-
41-
42-
4337
\[1] This device interaction model leans heavily on the wonderful work done by the [W3C WoT](https://www.w3.org/TR/wot-architecture/#sec-interaction-model).
44-

docs/guides/developer-tools/sandbox-and-sample-data/hubitat-hub-sample-data.md renamed to trash/guides/developer-tools/sandbox-and-sample-data/hubitat-hub-sample-data.md

File renamed without changes.

docs/guides/developer-tools/sandbox-and-sample-data/lockly-sample-data.md renamed to trash/guides/developer-tools/sandbox-and-sample-data/lockly-sample-data.md

File renamed without changes.

docs/guides/developer-tools/sandbox-and-sample-data/minut-sample-data.md renamed to trash/guides/developer-tools/sandbox-and-sample-data/minut-sample-data.md

File renamed without changes.

0 commit comments

Comments
 (0)