@gspothq/cli 0.1.1 → 0.2.0
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/README.md +58 -11
- package/configurations/database/postgres/manifest.toml +51 -57
- package/configurations/database/postgres/rules/POSTGRES.md +14 -13
- package/configurations/framework/astro/manifest.toml +33 -35
- package/configurations/framework/astro/rules/ASTRO.md +2 -2
- package/configurations/framework/expo/manifest.toml +19 -19
- package/configurations/framework/express/manifest.toml +10 -4
- package/configurations/framework/express/rules/EXPRESS.md +9 -7
- package/configurations/framework/fastapi/manifest.toml +9 -3
- package/configurations/framework/fastapi/rules/FASTAPI.md +19 -18
- package/configurations/framework/nestjs/manifest.toml +12 -12
- package/configurations/framework/nestjs/rules/NESTJS.md +9 -9
- package/configurations/framework/nextjs/manifest.toml +39 -79
- package/configurations/framework/nextjs/rules/NEXTJS.md +9 -7
- package/configurations/framework/nextjs/tool-files/semgrep/nextjs.yml +35 -0
- package/configurations/framework/react/manifest.toml +33 -43
- package/configurations/framework/react/rules/REACT.md +14 -20
- package/configurations/framework/react-dom/manifest.toml +6 -6
- package/configurations/framework/react-native/manifest.toml +11 -11
- package/configurations/framework/react-native/rules/REACT-NATIVE.md +3 -5
- package/configurations/framework/site/manifest.toml +57 -110
- package/configurations/framework/site/rules/SITE.md +1 -1
- package/configurations/framework/svelte/manifest.toml +29 -31
- package/configurations/framework/svelte/rules/SVELTE.md +6 -6
- package/configurations/framework/vue/manifest.toml +37 -37
- package/configurations/framework/vue/rules/VUE.md +6 -6
- package/configurations/general/commits/manifest.toml +20 -84
- package/configurations/general/commits/rules/GIT.md +24 -13
- package/configurations/general/coverage/manifest.toml +1 -1
- package/configurations/general/dependencies/manifest.toml +47 -107
- package/configurations/general/dependencies/rules/DEPENDENCIES.md +13 -7
- package/configurations/general/docs/manifest.toml +28 -43
- package/configurations/general/docs/rules/DOCS.md +16 -9
- package/configurations/general/duplication/manifest.toml +12 -14
- package/configurations/general/engineering/manifest.toml +6 -2
- package/configurations/general/engineering/rules/agent/PLANNING.md +9 -6
- package/configurations/general/engineering/rules/agent/SUPPRESSIONS.md +20 -11
- package/configurations/general/engineering/rules/agent/TASKS.md +6 -2
- package/configurations/general/engineering/rules/agent/WORKING.md +34 -29
- package/configurations/general/engineering/rules/code/ACCESSIBILITY.md +9 -7
- package/configurations/general/engineering/rules/code/CLI.md +12 -9
- package/configurations/general/engineering/rules/code/COMMENTS.md +11 -1
- package/configurations/general/engineering/rules/code/CONFIGURATION.md +2 -0
- package/configurations/general/engineering/rules/code/ERRORS.md +5 -3
- package/configurations/general/engineering/rules/code/HTTP.md +9 -10
- package/configurations/general/engineering/rules/code/LOGGING.md +10 -9
- package/configurations/general/engineering/rules/code/TESTING.md +18 -11
- package/configurations/general/files/manifest.toml +45 -73
- package/configurations/general/files/rules/YAML.md +20 -10
- package/configurations/general/format/manifest.toml +53 -106
- package/configurations/general/gspot/manifest.toml +19 -39
- package/configurations/general/gspot/rules/GENERATED.md +14 -4
- package/configurations/general/licenses/manifest.toml +12 -14
- package/configurations/general/naming/defaults.json +14 -13
- package/configurations/general/naming/manifest.toml +17 -17
- package/configurations/general/naming/rules/NAMING.md +87 -67
- package/configurations/general/prose/manifest.toml +166 -25
- package/configurations/general/prose/rules/WRITING.md +6 -2
- package/configurations/general/repository/manifest.toml +12 -12
- package/configurations/general/secrets/manifest.toml +52 -73
- package/configurations/general/secrets/rules/SECRETS.md +3 -1
- package/configurations/general/security/manifest.toml +29 -52
- package/configurations/general/security/rules/SECURITY.md +8 -6
- package/configurations/general/spelling/manifest.toml +15 -25
- package/configurations/general/structure/manifest.toml +31 -31
- package/configurations/infrastructure/ansible/manifest.toml +15 -15
- package/configurations/infrastructure/docker/manifest.toml +55 -67
- package/configurations/infrastructure/docker/rules/DOCKER.md +15 -13
- package/configurations/infrastructure/github-actions/manifest.toml +21 -41
- package/configurations/infrastructure/github-actions/rules/GITHUB-ACTIONS.md +16 -12
- package/configurations/infrastructure/github-actions/tool-files/zizmor.yml +5 -0
- package/configurations/infrastructure/nginx/manifest.toml +20 -20
- package/configurations/infrastructure/nginx/rules/NGINX.md +5 -4
- package/configurations/infrastructure/openapi/manifest.toml +20 -20
- package/configurations/infrastructure/openapi/rules/OPENAPI.md +3 -1
- package/configurations/infrastructure/xcode/manifest.toml +55 -75
- package/configurations/infrastructure/xcode/rules/XCODE.md +5 -3
- package/configurations/language/bash/manifest.toml +89 -170
- package/configurations/language/bash/rules/BASH.md +79 -17
- package/configurations/language/bash/rules/LANGUAGE.md +30 -26
- package/configurations/language/bash/rules/OPERATIONS.md +10 -8
- package/configurations/language/bash/rules/SAFETY.md +39 -35
- package/configurations/language/css/manifest.toml +22 -61
- package/configurations/language/css/rules/CSS.md +21 -2
- package/configurations/language/css/rules/TAILWIND.md +7 -5
- package/configurations/language/html/manifest.toml +16 -35
- package/configurations/language/html/rules/HTML.md +23 -5
- package/configurations/language/javascript/eslint-runtime-names.json +66 -61
- package/configurations/language/javascript/eslint-runtime.mjs +118 -0
- package/configurations/language/javascript/manifest.toml +135 -207
- package/configurations/language/javascript/rules/BUN.md +2 -2
- package/configurations/language/javascript/rules/COMPONENTS.md +4 -4
- package/configurations/language/javascript/rules/DENO.md +1 -1
- package/configurations/language/javascript/rules/JAVASCRIPT.md +30 -17
- package/configurations/language/javascript/rules/NODE.md +2 -2
- package/configurations/language/javascript/rules/PLAYWRIGHT.md +10 -9
- package/configurations/language/markdown/manifest.toml +20 -51
- package/configurations/language/python/manifest.toml +231 -342
- package/configurations/language/python/rules/DESIGN.md +40 -33
- package/configurations/language/python/rules/FLOW.md +8 -6
- package/configurations/language/python/rules/PACKAGING.md +14 -7
- package/configurations/language/python/rules/PYTHON.md +83 -33
- package/configurations/language/python/rules/TYPING.md +25 -23
- package/configurations/language/sql/manifest.toml +19 -37
- package/configurations/language/sql/rules/SQL.md +90 -2
- package/configurations/language/swift/manifest.toml +67 -78
- package/configurations/language/swift/rules/SWIFT.md +138 -40
- package/configurations/language/swift/rules/SWIFTUI.md +11 -9
- package/configurations/language/swift/rules/UIKIT.md +21 -19
- package/configurations/language/typescript/manifest.toml +34 -34
- package/configurations/language/typescript/rules/TYPESCRIPT.md +62 -10
- package/configurations/library/drizzle/manifest.toml +25 -38
- package/configurations/library/drizzle/rules/DRIZZLE.md +4 -2
- package/configurations/library/react-hook-form/manifest.toml +4 -4
- package/configurations/library/react-hook-form/rules/REACT-HOOK-FORM.md +15 -13
- package/configurations/library/tanstack-query/manifest.toml +6 -6
- package/configurations/library/tanstack-query/rules/TANSTACK-QUERY.md +5 -3
- package/configurations/library/testing-library/manifest.toml +6 -6
- package/configurations/library/translations/manifest.toml +22 -22
- package/configurations/library/translations/rules/NEXT-INTL.md +6 -8
- package/configurations/library/translations/rules/TRANSLATIONS.md +22 -23
- package/configurations/library/trpc/manifest.toml +3 -3
- package/configurations/library/trpc/rules/TRPC.md +8 -6
- package/configurations/library/zod/manifest.toml +6 -6
- package/configurations/library/zod/rules/ZOD.md +4 -2
- package/configurations/library/zustand/manifest.toml +4 -4
- package/configurations/library/zustand/rules/ZUSTAND.md +16 -14
- package/configurations/platform/cloudflare/manifest.toml +28 -47
- package/configurations/platform/cloudflare/rules/CLOUDFLARE.md +11 -6
- package/configurations/platform/supabase/manifest.toml +48 -61
- package/configurations/platform/supabase/rules/SUPABASE.md +27 -28
- package/configurations/testing/jest/manifest.toml +21 -22
- package/configurations/testing/pytest/manifest.toml +28 -28
- package/configurations/testing/swift-tests/manifest.toml +18 -29
- package/configurations/testing/swift-tests/rules/SWIFT-TESTS.md +7 -5
- package/configurations/testing/vitest/manifest.toml +32 -32
- package/configurations/testing/vitest/rules/VITEST.md +3 -1
- package/dist/gspot.js +22297 -24707
- package/dist/{linkinator-program.js → linkinator-process.js} +5 -7
- package/dist/{purgecss-program.js → purgecss-process.js} +12 -12
- package/package.json +7 -9
- package/configurations/infrastructure/github-actions/zizmor.yml +0 -3
- package/configurations/language/bash/rules/NAMING.md +0 -62
- package/configurations/language/css/rules/NAMING.md +0 -17
- package/configurations/language/html/rules/NAMING.md +0 -16
- package/configurations/language/javascript/rules/NAMING.md +0 -31
- package/configurations/language/markdown/markdownlint-cli2.mjs +0 -19
- package/configurations/language/python/rules/NAMING.md +0 -53
- package/configurations/language/sql/rules/NAMING.md +0 -90
- package/configurations/language/swift/rules/NAMING.md +0 -88
- package/configurations/language/typescript/rules/NAMING.md +0 -73
- package/configurations/library/swift-snapshot-testing/manifest.toml +0 -32
- package/dist/THIRD-PARTY-NOTICES.md +0 -25
- package/dist/eslint-rule-levels.json +0 -10
- package/dist/tool-versions.json +0 -3
- package/gspot.schema.json +0 -45991
- /package/{dist/LICENSE.md → LICENSE.md} +0 -0
- /package/configurations/framework/express/{semgrep → tool-files/semgrep}/express.yml +0 -0
- /package/configurations/framework/fastapi/{semgrep → tool-files/semgrep}/fastapi.yml +0 -0
- /package/configurations/general/dependencies/{syncpack.json → tool-files/syncpack.json} +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/LICENSES.md +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/ampm.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/conscious-language.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/contractions.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/currency.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/dashes.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/date-ordinals.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/dates.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/file-paths.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/future.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/hedging.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/history.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/idioms.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/interface-verbs.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/jargon.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/leading-conjunctions.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/link-text.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/locations.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/marketing.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/merge-conflict-markers.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/militaristic-language.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/modals.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/numbered-units.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/obvious-fields.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/ordinal-adverbs.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/percentage-numbers.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/placeholders.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/product-centric-writing.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/punctuated-headings.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/self-reference.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/session-identifiers.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/since.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/straight-quotes.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/suspended-hyphens.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/symbols.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/time-ranges.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/url-prepositions.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/version-range.yml +0 -0
- /package/configurations/general/secrets/{gitleaks.toml → tool-files/gitleaks.toml} +0 -0
- /package/configurations/infrastructure/docker/{trivyignore → tool-files/trivyignore} +0 -0
- /package/configurations/language/bash/{semgrep → tool-files/semgrep}/bash.yml +0 -0
- /package/configurations/language/javascript/{semgrep → tool-files/semgrep}/javascript.yml +0 -0
- /package/configurations/language/swift/{semgrep → tool-files/semgrep}/swift.yml +0 -0
- /package/configurations/platform/cloudflare/{semgrep → tool-files/semgrep}/cloudflare.yml +0 -0
- /package/configurations/platform/supabase/{semgrep → tool-files/semgrep}/supabase.yml +0 -0
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# Bash Operations
|
|
2
2
|
|
|
3
|
+
Read this rule when you write a deployment, publishing, or remote shell script.
|
|
4
|
+
|
|
3
5
|
## Module ownership and visibility
|
|
4
6
|
|
|
5
7
|
<!-- level: all -->
|
|
6
8
|
|
|
7
|
-
Each file owns one cohesive responsibility, and the
|
|
9
|
+
Each file owns one cohesive responsibility, and the folder supplies the family name.
|
|
8
10
|
|
|
9
11
|
- A sourced public function carries its family name, such as `release_prepare` or
|
|
10
12
|
`cache_read_state`.
|
|
11
|
-
-
|
|
13
|
+
- Keep a function with one caller in the same file as the call.
|
|
12
14
|
|
|
13
15
|
## Deployment and publishing pipelines
|
|
14
16
|
|
|
@@ -16,11 +18,11 @@ Deployment, publishing, and long-running scripts separate validation, planning,
|
|
|
16
18
|
execution, readiness checks, and cleanup.
|
|
17
19
|
|
|
18
20
|
- Fail before any work when the script lacks a required input, command, file, host, or secret.
|
|
19
|
-
-
|
|
21
|
+
- State the target explicitly: never infer production, a remote, a host, or an artifact from a
|
|
20
22
|
branch name without a confirmation or a CI contract.
|
|
21
23
|
- A destructive or remote action asks for confirmation unless CI owns the guard.
|
|
22
24
|
- Use idempotent commands and stop at the first failed required step.
|
|
23
|
-
- Check readiness after deploying or publishing, and print
|
|
25
|
+
- Check readiness after deploying or publishing, and print messages a person can act on.
|
|
24
26
|
- Keep rollback and cleanup explicit, and delete no artifact or result as a side effect.
|
|
25
27
|
- Log enough to reconstruct what happened, without secrets.
|
|
26
28
|
|
|
@@ -44,9 +46,9 @@ confirm_exact() {
|
|
|
44
46
|
## Remote commands
|
|
45
47
|
|
|
46
48
|
Copy a reviewed script to the remote host and invoke it with arguments. SSH joins its arguments
|
|
47
|
-
into one remote shell string, so local quoting does not keep
|
|
48
|
-
|
|
49
|
-
input
|
|
49
|
+
into one remote shell string, so local quoting does not keep their boundaries. Validate host,
|
|
50
|
+
user, service, and path values before you use them. Never build a remote command from user
|
|
51
|
+
input. Give every remote call that can hang a timeout.
|
|
50
52
|
|
|
51
53
|
Good, for a remote Bash login shell:
|
|
52
54
|
|
|
@@ -58,7 +60,7 @@ ssh -- "${host}" "${remote_command}"
|
|
|
58
60
|
## Persisted state
|
|
59
61
|
|
|
60
62
|
Never `source` generated state or pass it to `bash -c`. Write state in a fixed data format with an
|
|
61
|
-
exact key schema to a restricted file in the destination folder
|
|
63
|
+
exact key schema to a restricted file in the destination folder. Replace the previous version
|
|
62
64
|
with an atomic `mv`. A reader treats a malformed, duplicate, or unknown key as an error.
|
|
63
65
|
|
|
64
66
|
## Retries
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# Bash Safety
|
|
2
2
|
|
|
3
|
+
Read this rule when a shell script runs commands, handles paths, downloads files, or deletes files.
|
|
4
|
+
|
|
3
5
|
## Calling commands
|
|
4
6
|
|
|
5
|
-
Use fixed command names with argument arrays, never strings built from input
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
`shift` and invokes `"$@"`.
|
|
7
|
+
Use fixed command names with argument arrays, never strings built from input. Never pass
|
|
8
|
+
untrusted input to a shell. Never use `bash -lc` in repository scripts. A function that runs a
|
|
9
|
+
caller-supplied command takes it and its arguments after `shift` and invokes `"$@"`.
|
|
9
10
|
|
|
10
11
|
Check uncommon commands with `command -v` before a long-running, destructive, publishing, or
|
|
11
12
|
error-handling path depends on them. Prefer builtins and parameter expansion to external
|
|
@@ -28,14 +29,14 @@ require_command() {
|
|
|
28
29
|
|
|
29
30
|
## Processes and privilege
|
|
30
31
|
|
|
31
|
-
Treat process names as advisory information, never authorization. Stop and restart paths
|
|
32
|
-
process ids
|
|
33
|
-
`pgrep -x`, never `ps | grep`. A script that starts background jobs saves
|
|
34
|
-
each, captures
|
|
32
|
+
Treat process names as advisory information, never authorization. Stop and restart paths kill only
|
|
33
|
+
process ids that the owning script family recorded, found through the service manager, a `PID` file, or
|
|
34
|
+
`pgrep -x`, never `ps | grep`. A script that starts background jobs saves every `PID`, waits for
|
|
35
|
+
each job, captures its status, and writes its output to a separate file. It bounds its
|
|
35
36
|
fan-out and kills owned children on `INT`, `TERM`, and `EXIT`. `sudo command > file` redirects
|
|
36
37
|
as the current user, and a glob in `sudo command /path/*` expands before `sudo` runs.
|
|
37
|
-
|
|
38
|
-
with no input.
|
|
38
|
+
Send privileged writes through `sudo tee`, and keep the shell string you pass to `sudo` a fixed
|
|
39
|
+
literal with no input.
|
|
39
40
|
|
|
40
41
|
```bash
|
|
41
42
|
generate_config | sudo tee /etc/service/config >/dev/null
|
|
@@ -74,7 +75,7 @@ with ad hoc `grep | sed | awk` unless the script controls the input and the form
|
|
|
74
75
|
Prefer machine output modes such as JSON, `NUL`, or explicit format flags and never parse process lists,
|
|
75
76
|
pretty tables, progress bars, or localized text by fixed field numbers. Quote `tr` character
|
|
76
77
|
classes and pin `LC_ALL=C` when converting case. macOS and GNU `sed -i` differ; a committed
|
|
77
|
-
script rewrites through a temporary file unless its documentation restricts it to one
|
|
78
|
+
script rewrites through a temporary file unless its documentation restricts it to one system.
|
|
78
79
|
|
|
79
80
|
```bash
|
|
80
81
|
# get_service_url: Prints a required nonempty service URL from JSON configuration.
|
|
@@ -89,9 +90,9 @@ get_service_url() {
|
|
|
89
90
|
|
|
90
91
|
## Network
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
tool
|
|
94
|
-
|
|
93
|
+
Download with `curl --fail --show-error --silent --location` into an explicit file. Set timeouts
|
|
94
|
+
with the options of the tool, such as `--connect-timeout` plus `--max-time`, or SSH `ConnectTimeout`.
|
|
95
|
+
Do not use GNU `timeout`, which macOS lacks. Download executable content, verify it against an
|
|
95
96
|
independently obtained checksum or signature, and only then run it.
|
|
96
97
|
|
|
97
98
|
```bash
|
|
@@ -132,19 +133,19 @@ require_env() {
|
|
|
132
133
|
|
|
133
134
|
## Temporary files, locks, and cleanup
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
Create temporary paths with `mktemp` or `mktemp -d` under the system location or a dedicated
|
|
137
|
+
project folder, never with predictable names. Register cleanup immediately after creation.
|
|
137
138
|
Put downloaded, copied, or generated content in a temporary file, validate it with the real
|
|
138
139
|
parser, and replace the destination with `mv`. The file keeps the restrictive permissions
|
|
139
140
|
`mktemp` gave it unless deployment needs others. Remove failed artifacts unless the script
|
|
140
|
-
documents keeping them. Acquire
|
|
141
|
-
|
|
141
|
+
documents keeping them. Acquire a lock atomically with `mkdir` on a folder that stores the holder
|
|
142
|
+
`PID`, or with `noclobber` redirection, never with a `test` followed by a create.
|
|
142
143
|
|
|
143
144
|
Stop commands remove only what the script created. Validate a cleanup path from
|
|
144
145
|
input or persistent state against its permitted root. Reject empty values, `/`,
|
|
145
|
-
the repository root, `$HOME`, symlinks, and anything outside the
|
|
146
|
+
the repository root, `$HOME`, symlinks, and anything outside the folder the script created. Keep a `mktemp -d` result
|
|
146
147
|
exactly. Never widen the path to its neighbors. `|| true` never follows a destructive
|
|
147
|
-
|
|
148
|
+
step or a required installation, publishing, build, or runtime command.
|
|
148
149
|
|
|
149
150
|
```bash
|
|
150
151
|
downloaded_file="$(mktemp "${config_file}.XXXXXX")" || exit 1
|
|
@@ -165,11 +166,12 @@ printf '%s\n' "$$" >"${lock_dir}/pid" || {
|
|
|
165
166
|
trap 'rm -f -- "${lock_dir}/pid"; rmdir -- "${lock_dir}"' EXIT
|
|
166
167
|
```
|
|
167
168
|
|
|
168
|
-
Put recursive deletes in one script
|
|
169
|
-
|
|
169
|
+
Put recursive deletes in one script. To accept the `bash/safety` finding for that script, follow the suppression
|
|
170
|
+
rules.
|
|
171
|
+
Validate its cleanup path against the approved root folder:
|
|
170
172
|
|
|
171
173
|
```bash
|
|
172
|
-
# remove_build_dir: Removes the build child of the approved
|
|
174
|
+
# remove_build_dir: Removes the build child of the approved root folder.
|
|
173
175
|
remove_build_dir() {
|
|
174
176
|
local owner_root build_dir
|
|
175
177
|
|
|
@@ -186,10 +188,9 @@ remove_build_dir() {
|
|
|
186
188
|
|
|
187
189
|
macOS and BSD
|
|
188
190
|
differ from GNU in `sed`, `date`, `readlink`, `mktemp`, `stat`, `xargs`, and `grep`; keep a
|
|
189
|
-
|
|
190
|
-
parsing differences. macOS `/bin/bash`
|
|
191
|
-
|
|
192
|
-
developer's `PATH`. Symlink-aware absolute paths come from `pwd -P` after `cd`, or from
|
|
191
|
+
system-specific branch with the operation that owns it. Handle `realpath` and `date`
|
|
192
|
+
parsing differences. macOS `/bin/bash` runs an old Bash version. Linux-only utilities need
|
|
193
|
+
checks in scripts that also run on macOS. CI does not share the `PATH` of the developer. Symlink-aware absolute paths come from `pwd -P` after `cd`, or from
|
|
193
194
|
product-owned application code.
|
|
194
195
|
|
|
195
196
|
## Verification and debugging
|
|
@@ -198,13 +199,15 @@ Run the configured syntax, ShellCheck, and shfmt commands. Run destructive or pr
|
|
|
198
199
|
only in a throwaway environment.
|
|
199
200
|
|
|
200
201
|
Production scripts gain no test-only flags, branches, or command replacements. When
|
|
201
|
-
debugging, start from the exact error and line Bash reports
|
|
202
|
+
debugging, start from the exact error and line Bash reports. Run `bash -n` and ShellCheck,
|
|
202
203
|
reduce to the smallest reproducing block, and expose invisible characters with
|
|
203
|
-
`printf '%q\n'`.
|
|
204
|
-
|
|
204
|
+
`printf '%q\n'`.
|
|
205
|
+
|
|
206
|
+
Trace with `bash -x` or a local `set -x` block whose `PS4` names file, line, and function,
|
|
207
|
+
only while you debug. Never commit broad tracing, `trap DEBUG`, or stepping
|
|
205
208
|
code. Bash 4.4 supports `BASH_XTRACEFD`. A debug helper preserves the status it diagnoses.
|
|
206
209
|
|
|
207
|
-
|
|
210
|
+
`unexpected EOF` indicates an unmatched quote, an unterminated here document,
|
|
208
211
|
a missing `fi`, `done`, or `esac`, or a CRLF ending hiding the delimiter.
|
|
209
212
|
|
|
210
213
|
`too many arguments` indicates an unquoted expansion inside `[ ... ]`. `event not found` indicates interactive history expansion
|
|
@@ -213,10 +216,11 @@ Failure before the shebang indicates a byte order mark (BOM) or CRLF.
|
|
|
213
216
|
|
|
214
217
|
## Refactoring existing scripts
|
|
215
218
|
|
|
216
|
-
Read the whole script and its sourced libraries
|
|
217
|
-
remote host, or package script
|
|
218
|
-
|
|
219
|
-
|
|
219
|
+
Read the whole script and its sourced libraries. Identify the caller interface: local, CI,
|
|
220
|
+
remote host, or package script. Preserve behavior before you change style.
|
|
221
|
+
|
|
222
|
+
Fix quoting and argument arrays near the touched logic, and add explicit checks around dangerous commands.
|
|
223
|
+
Share a helper across the script family only when it has a real common contract. Do not
|
|
220
224
|
convert a large script in one pass or change shebangs across a family without verifying the
|
|
221
225
|
runtime. Run the narrow shell lint and format command before the broader checks. Move complex script
|
|
222
226
|
logic into application code and call it directly.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
allowed_words = ["CSS"]
|
|
2
|
+
|
|
2
3
|
[configuration]
|
|
4
|
+
description = "CSS files and style blocks in Vue and Svelte components: Stylelint with the standard rules, Prettier for layout, and module classes both defined and used. SCSS gets formatting only."
|
|
3
5
|
title = "CSS"
|
|
4
|
-
description = "CSS files and the style blocks of Vue and Svelte components: Stylelint with the standard rules, Prettier for layout, and CSS module classes that are both defined and used. SCSS receives formatting only."
|
|
5
6
|
|
|
6
7
|
[detect]
|
|
7
8
|
extensions = [".css", ".vue", ".svelte"]
|
|
@@ -9,90 +10,50 @@ extensions = [".css", ".vue", ".svelte"]
|
|
|
9
10
|
[files]
|
|
10
11
|
extensions = [".css"]
|
|
11
12
|
|
|
13
|
+
[rules]
|
|
14
|
+
"TAILWIND.md" = { dependencies = ["tailwindcss"] }
|
|
15
|
+
|
|
12
16
|
[[tool]]
|
|
13
17
|
name = "stylelint"
|
|
18
|
+
npm = "stylelint"
|
|
19
|
+
replace = [".stylelintrc", ".stylelintrc.json", ".stylelintrc.js", ".stylelintrc.cjs", ".stylelintrc.mjs", ".stylelintrc.yml", ".stylelintrc.yaml", "stylelint.config.js", "stylelint.config.cjs", "stylelint.config.mjs"]
|
|
14
20
|
suppression = { marker = "^(?:/\\*|//)\\s*stylelint-disable(?:-next-line|-line)?(?=\\s|$)", reason = " -- (?<reason>\\S(?:[\\s\\S]*?\\S)?)\\s*(?:\\*/)?$" }
|
|
15
21
|
version = "16.23.1"
|
|
16
|
-
npm = "stylelint"
|
|
17
|
-
[[tool.replace]]
|
|
18
|
-
file = ".stylelintrc"
|
|
19
|
-
shared = false
|
|
20
|
-
|
|
21
|
-
[[tool.replace]]
|
|
22
|
-
file = ".stylelintrc.json"
|
|
23
|
-
shared = false
|
|
24
|
-
|
|
25
|
-
[[tool.replace]]
|
|
26
|
-
file = ".stylelintrc.js"
|
|
27
|
-
shared = false
|
|
28
|
-
|
|
29
|
-
[[tool.replace]]
|
|
30
|
-
file = ".stylelintrc.cjs"
|
|
31
|
-
shared = false
|
|
32
|
-
|
|
33
|
-
[[tool.replace]]
|
|
34
|
-
file = ".stylelintrc.mjs"
|
|
35
|
-
shared = false
|
|
36
22
|
|
|
37
|
-
[[tool.
|
|
38
|
-
file = ".stylelintrc.yml"
|
|
39
|
-
shared = false
|
|
40
|
-
|
|
41
|
-
[[tool.replace]]
|
|
42
|
-
file = ".stylelintrc.yaml"
|
|
43
|
-
shared = false
|
|
44
|
-
|
|
45
|
-
[[tool.replace]]
|
|
46
|
-
file = "stylelint.config.js"
|
|
47
|
-
shared = false
|
|
48
|
-
|
|
49
|
-
[[tool.replace]]
|
|
50
|
-
file = "stylelint.config.cjs"
|
|
51
|
-
shared = false
|
|
52
|
-
|
|
53
|
-
[[tool.replace]]
|
|
54
|
-
file = "stylelint.config.mjs"
|
|
55
|
-
shared = false
|
|
56
|
-
|
|
57
|
-
[[tool.replace]]
|
|
23
|
+
[[tool.replace_key]]
|
|
58
24
|
file = "package.json"
|
|
59
25
|
key = "stylelint"
|
|
60
26
|
redirect = true
|
|
61
|
-
shared = true
|
|
62
27
|
|
|
63
28
|
[[tool]]
|
|
64
|
-
name = "stylelint-config-standard"
|
|
65
29
|
kind = "library"
|
|
66
|
-
|
|
30
|
+
name = "stylelint-config-standard"
|
|
67
31
|
npm = "stylelint-config-standard"
|
|
32
|
+
version = "39.0.0"
|
|
68
33
|
|
|
69
34
|
[[tool]]
|
|
70
|
-
name = "postcss-html"
|
|
71
35
|
kind = "library"
|
|
72
|
-
|
|
36
|
+
name = "postcss-html"
|
|
73
37
|
npm = "postcss-html"
|
|
38
|
+
version = "2.0.0"
|
|
74
39
|
|
|
75
40
|
[[tool_file]]
|
|
76
|
-
target = ".gspot/config/stylelint.json"
|
|
77
|
-
tool = "stylelint"
|
|
78
|
-
rule_keys = ["rules"]
|
|
79
41
|
per_scope = true
|
|
80
42
|
pointer = { path = ".stylelintrc.json", body = "{\n \"extends\": \"{target}\"\n}\n" }
|
|
43
|
+
target = ".gspot/config/stylelint.json"
|
|
44
|
+
tool = "stylelint"
|
|
81
45
|
|
|
82
46
|
[[check]]
|
|
83
|
-
name = "stylelint"
|
|
84
|
-
tool = ["stylelint", "stylelint-config-standard"]
|
|
85
|
-
example = "The declaration `color: #ggg` uses an invalid hexadecimal color and reports a Stylelint finding. Replace it with a valid intended color such as `#abc`."
|
|
86
|
-
level = "recommended"
|
|
87
|
-
stage = "commit"
|
|
88
47
|
command = ["stylelint", "--config", "{tool_file:stylelint}", "--config-basedir", "{root}/.gspot", "--formatter", "unix", "--allow-empty-input", "{files}"]
|
|
89
|
-
|
|
48
|
+
example = "The declaration `color: #ggg` holds an invalid hex value and reports a finding. Replace it with a valid one such as `#abc`."
|
|
90
49
|
exit_codes = [2]
|
|
91
50
|
files = { extensions = [".css", ".vue", ".svelte"] }
|
|
51
|
+
fix = ["stylelint", "--config", "{tool_file:stylelint}", "--config-basedir", "{root}/.gspot", "--fix", "--allow-empty-input", "{files}"]
|
|
52
|
+
help = "Run `gspot check --fix` for the rules that fix themselves. Turn one rule off with `gspot ignore css/stylelint --rule <name> --reason \"<why>\"`."
|
|
53
|
+
level = "recommended"
|
|
54
|
+
name = "stylelint"
|
|
92
55
|
output = { format = "regex", pattern = "^(?<file>.+?):(?<line>\\d+):(?<column>\\d+): (?<message>.*) \\((?<rule>[\\w/@-]+)\\) \\[\\w+\\]$" }
|
|
56
|
+
stage = "commit"
|
|
93
57
|
summary = "Lints every stylesheet with the standard stylelint rules: unknown properties, overridden selectors, and invalid values."
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
[rules]
|
|
98
|
-
"TAILWIND.md" = { dependencies = ["tailwindcss"] }
|
|
58
|
+
tool = ["stylelint", "stylelint-config-standard"]
|
|
59
|
+
why = "A browser silently skips a declaration it cannot parse, so a typo in a property ships as a missing style."
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# CSS
|
|
2
2
|
|
|
3
|
+
Read this rule when you change a stylesheet.
|
|
4
|
+
|
|
3
5
|
## Correctness and accessibility
|
|
4
6
|
|
|
5
7
|
- Use logical properties where layout follows the writing direction.
|
|
@@ -9,7 +11,7 @@
|
|
|
9
11
|
|
|
10
12
|
<!-- level: all -->
|
|
11
13
|
|
|
12
|
-
- Keep shared color, spacing, type, radius, and motion tokens in one
|
|
14
|
+
- Keep shared color, spacing, type, radius, and motion tokens in one file.
|
|
13
15
|
- Keep feature styles with their component or import them through the stylesheet entry.
|
|
14
16
|
- Order rules from general styles to component states.
|
|
15
17
|
|
|
@@ -18,7 +20,7 @@
|
|
|
18
20
|
<!-- level: all -->
|
|
19
21
|
|
|
20
22
|
- Prefer class selectors with low specificity.
|
|
21
|
-
- Prefer grid and flexbox for layout. Keep
|
|
23
|
+
- Prefer grid and flexbox for layout. Keep content in normal document flow.
|
|
22
24
|
|
|
23
25
|
## Files
|
|
24
26
|
|
|
@@ -26,3 +28,20 @@
|
|
|
26
28
|
|
|
27
29
|
- Keep presentation in stylesheets or framework-owned component style blocks.
|
|
28
30
|
- Let the framework own style scoping rather than duplicating selectors manually.
|
|
31
|
+
|
|
32
|
+
## Naming
|
|
33
|
+
|
|
34
|
+
### Selector and file names
|
|
35
|
+
|
|
36
|
+
<!-- level: all -->
|
|
37
|
+
|
|
38
|
+
- Name classes for the component or state, such as `order-card`, `order-card-title`, `is-active`, or `has-error`.
|
|
39
|
+
- A state class starts with `is-` or `has-`. A script toggles it. Never style it alone.
|
|
40
|
+
- Custom properties name the role of the value, not its appearance:
|
|
41
|
+
`--color-surface`, `--space-2`, `--font-size-body`, never `--blue` or `--big-margin`.
|
|
42
|
+
- Theme overrides reuse the same property names under their selector and add no new ones.
|
|
43
|
+
- Keyframe names describe the motion, such as `fade-in` or `slide-from-start`.
|
|
44
|
+
- Name stylesheet files for what they hold, such as `order-card.css`,
|
|
45
|
+
`tokens.css`, or `layout.css`.
|
|
46
|
+
- When the project uses a utility system, keep its class names. Do not write your own utility classes
|
|
47
|
+
beside it.
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# Tailwind CSS
|
|
2
2
|
|
|
3
|
+
Read this rule when you change Tailwind CSS classes or configuration.
|
|
4
|
+
|
|
3
5
|
## Generated styles
|
|
4
6
|
|
|
5
7
|
- Verify that source detection covers templates and content containing class names. Tailwind CSS 4
|
|
6
|
-
detects sources automatically; register excluded
|
|
8
|
+
detects sources automatically; register excluded ones with `@source`. Tailwind CSS 3 uses
|
|
7
9
|
`content` configuration.
|
|
8
10
|
- Keep complete class names in source so the scanner can find them.
|
|
9
11
|
- Preserve the application's configured dark-mode strategy.
|
|
10
|
-
- When the project configures a
|
|
12
|
+
- When the project configures a formatter plugin that sorts classes, let it own the order.
|
|
11
13
|
|
|
12
14
|
Use the [source detection documentation](https://tailwindcss.com/docs/detecting-classes-in-source-files)
|
|
13
15
|
for the installed major version.
|
|
@@ -17,10 +19,10 @@ for the installed major version.
|
|
|
17
19
|
<!-- level: all -->
|
|
18
20
|
|
|
19
21
|
- Use theme tokens for colors, spacing, radii, fonts, and breakpoints. Explain deliberate values
|
|
20
|
-
outside those tokens
|
|
22
|
+
outside those tokens where the code uses them.
|
|
21
23
|
- Compose component styles with utility classes. Keep reusable theme and utility declarations
|
|
22
|
-
in
|
|
24
|
+
in the configured stylesheet.
|
|
23
25
|
- Use the project's adopted class-merging function when conditional utilities conflict.
|
|
24
26
|
Do not introduce a separate merging implementation.
|
|
25
27
|
- Avoid handwritten CSS that duplicates an existing utility without a component requirement.
|
|
26
|
-
- Follow the installed Tailwind version
|
|
28
|
+
- Follow the syntax of the installed Tailwind version for custom utilities, variants, and plugins.
|
|
@@ -1,59 +1,40 @@
|
|
|
1
1
|
allowed_words = ["HTML"]
|
|
2
|
+
|
|
2
3
|
[configuration]
|
|
4
|
+
description = "HTML files: html-validate for structure and accessibility, and no inline script or handler."
|
|
3
5
|
title = "HTML"
|
|
4
|
-
description = "HTML files: html-validate for structure and accessibility, no inline script or handler, and templates that hold placeholders in place of copy."
|
|
5
6
|
|
|
6
7
|
[files]
|
|
7
8
|
extensions = [".html", ".htm"]
|
|
8
9
|
|
|
9
10
|
[[tool]]
|
|
10
11
|
name = "html-validate"
|
|
12
|
+
npm = "html-validate"
|
|
13
|
+
replace = [".htmlvalidate.json", ".htmlvalidate.js", ".htmlvalidate.cjs"]
|
|
11
14
|
suppression = { marker = "^<!--\\s*\\[?html-validate-disable(?:-next|-block)?(?=\\s|\\]|$)", reason = "(?: -- |: )(?<reason>\\S(?:[\\s\\S]*?\\S)?)\\s*\\]?\\s*(?:--!?>)?$" }
|
|
12
15
|
version = "11.6.1"
|
|
13
|
-
npm = "html-validate"
|
|
14
|
-
[[tool.replace]]
|
|
15
|
-
file = ".htmlvalidate.json"
|
|
16
|
-
shared = false
|
|
17
|
-
|
|
18
|
-
[[tool.replace]]
|
|
19
|
-
file = ".htmlvalidate.js"
|
|
20
|
-
shared = false
|
|
21
|
-
|
|
22
|
-
[[tool.replace]]
|
|
23
|
-
file = ".htmlvalidate.cjs"
|
|
24
|
-
shared = false
|
|
25
16
|
|
|
26
17
|
[[tool_file]]
|
|
18
|
+
check = "html/html-validate"
|
|
27
19
|
target = ".gspot/config/html-validate-source.json"
|
|
28
20
|
tool = "html-validate"
|
|
29
|
-
check = "html/validate"
|
|
30
|
-
rule_keys = ["rules"]
|
|
31
21
|
|
|
32
22
|
[[check]]
|
|
33
|
-
name = "validate"
|
|
34
|
-
example = "An `<img src=\"logo.png\">` element without alternative text reports an accessibility finding under the configured rules. Add meaningful `alt` text, or an empty `alt` value for a decorative image."
|
|
35
|
-
level = "recommended"
|
|
36
|
-
stage = "commit"
|
|
37
23
|
command = ["html-validate", "--config", "{tool_file:html-validate-source}", "--formatter", "json", "{files}"]
|
|
24
|
+
example = "An `<img src=\"logo.png\">` without alternative text reports a finding. Add `alt` text, or leave it empty for a decorative image."
|
|
25
|
+
help = "Change the markup the way the rule page says. Turn one rule off with `gspot ignore html/html-validate --rule <name> --reason \"<why>\"`."
|
|
26
|
+
level = "recommended"
|
|
27
|
+
name = "html-validate"
|
|
38
28
|
output = { format = "json", children = "messages", fields = { file = "filePath", line = "line", column = "column", rule = "ruleId", message = "message" } }
|
|
39
|
-
summary = "Validates every HTML file: elements where they may sit, required attributes, text alternatives, and one style for void elements."
|
|
40
|
-
why = "A browser repairs broken markup in its own way, and a screen reader reads what the repair left."
|
|
41
|
-
help = "Change the markup the way the rule page says. Turn one rule off with gspot ignore html/validate --rule `<name>` --reason \"`<why>`\"."
|
|
42
|
-
|
|
43
|
-
[[check]]
|
|
44
|
-
name = "scripts"
|
|
45
|
-
example = "A button using an inline `onclick` attribute reports embedded executable code. Remove the attribute and attach the event listener from a separate script file."
|
|
46
|
-
level = "all"
|
|
47
29
|
stage = "commit"
|
|
48
|
-
summary = "
|
|
49
|
-
why = "
|
|
50
|
-
help = "Move the script into a file, and attach the handler from that file. Structured data of type application/ld+json stays inline."
|
|
30
|
+
summary = "Validates HTML files for nesting, required attributes, text alternatives, and one style for void elements."
|
|
31
|
+
why = "Each browser repairs broken markup differently, and a screen reader announces only what remains."
|
|
51
32
|
|
|
52
33
|
[[check]]
|
|
53
|
-
|
|
54
|
-
|
|
34
|
+
example = "A button with an inline `onclick` attribute reports a finding. Remove it, and attach the listener from a script file."
|
|
35
|
+
help = "Move the script into its own file, and attach the handler there. Structured data of type `application/ld+json` stays inline."
|
|
55
36
|
level = "all"
|
|
37
|
+
name = "scripts"
|
|
56
38
|
stage = "commit"
|
|
57
|
-
summary = "
|
|
58
|
-
why = "
|
|
59
|
-
help = "Replace the text with a placeholder and put the words in the content file. Remove files that are not templates from html.templates."
|
|
39
|
+
summary = "Reports inline scripts, event handler attributes, and executable URLs in HTML files."
|
|
40
|
+
why = "A content security policy can block injected code only when the pages carry no inline script."
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# HTML
|
|
2
2
|
|
|
3
|
+
Read this rule when you change HTML or an HTML template.
|
|
4
|
+
|
|
3
5
|
## Document
|
|
4
6
|
|
|
5
|
-
- `<html lang="...">` names the page language; set `dir` for
|
|
7
|
+
- `<html lang="...">` names the page language; set `dir` for right-to-left text.
|
|
6
8
|
- One `<title>` that names the page, a `<meta name="viewport">`, and a `<meta charset="utf-8">`
|
|
7
9
|
first in `<head>`.
|
|
8
10
|
- Landmarks such as `header`, `nav`, `main`, `footer`, and `aside` structure the page. One `main`.
|
|
9
11
|
|
|
10
12
|
## Elements
|
|
11
13
|
|
|
12
|
-
- Use the element that means the thing: `button` for actions, `a`
|
|
13
|
-
|
|
14
|
-
for dates, `figure` and `figcaption` for captioned media.
|
|
15
|
-
- Never a `div` or `span` with a click handler standing in for a button or link.
|
|
14
|
+
- Use the element that means the thing: `button` for actions, `a` with a real `href` for links,
|
|
15
|
+
and `nav` for navigation. Use `ul` and `ol` for lists, `table` for data, `time` with `datetime`
|
|
16
|
+
for dates, and `figure` and `figcaption` for captioned media.
|
|
16
17
|
- `target="_blank"` links carry `rel="noopener"`.
|
|
17
18
|
|
|
18
19
|
## Script safety
|
|
@@ -25,3 +26,20 @@
|
|
|
25
26
|
|
|
26
27
|
- A template stays declarative: no logic beyond conditionals and loops the engine provides.
|
|
27
28
|
- Generate deterministic HTML: the same inputs produce byte-identical output.
|
|
29
|
+
|
|
30
|
+
## Naming
|
|
31
|
+
|
|
32
|
+
### Route and attribute names
|
|
33
|
+
|
|
34
|
+
<!-- level: all -->
|
|
35
|
+
|
|
36
|
+
- Use kebab-case file names that match the public route: `about-us.html`, `pricing/index.html`.
|
|
37
|
+
Folder routes end in `index.html` in generated output.
|
|
38
|
+
- Name public route segments in lowercase kebab-case with no trailing slash ambiguity: one
|
|
39
|
+
canonical form, with the other redirected.
|
|
40
|
+
- Use `id` attributes for anchors, labels, and descriptions, not for styling.
|
|
41
|
+
- Name `data-*` attributes in kebab-case for their value, such as `data-device-class`.
|
|
42
|
+
- Placeholders follow the engine's convention and name the value.
|
|
43
|
+
- Name content files for the route or topic they serve, such as `content/legal/privacy.md`.
|
|
44
|
+
- Name asset files in kebab-case for their subject and role, such as `hero-phone-dark.webp`. Never use
|
|
45
|
+
`image1.png` or `final-v2.svg`. Generate hashed names rather than writing them by hand.
|