@drkmttr/adhere 0.2.2 → 0.3.1

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/src/rules.ts CHANGED
@@ -1,4 +1,10 @@
1
- import { ConfigUnavailable, type Rule, type RuleId, type RuleSource } from "#config.ts";
1
+ import {
2
+ ConfigUnavailable,
3
+ type Rule,
4
+ type RuleId,
5
+ type RuleSource,
6
+ SKIPPED_DIRECTORIES,
7
+ } from "#config.ts";
2
8
  import { parseRuleMarkdown } from "#markdown.ts";
3
9
  import { Effect, FileSystem, Path, Record } from "effect";
4
10
 
@@ -31,7 +37,13 @@ const isMarkdown = (path: string): boolean => path.endsWith(".md");
31
37
  const isNestedRuleFile = (relative: string): boolean => {
32
38
  const segments = segmentsOf(relative);
33
39
  const adhere = segments.lastIndexOf(ADHERE_SEGMENT);
34
- return adhere >= 0 && segments[adhere + 1] !== CACHE_SEGMENT && isMarkdown(relative);
40
+ return (
41
+ adhere >= 0 &&
42
+ segments[adhere + 1] !== CACHE_SEGMENT &&
43
+ isMarkdown(relative) &&
44
+ // Only the path to the `.adhere/`: `.adhere/e2e/` is a rule topic, not a skip.
45
+ !segments.slice(0, adhere).some((segment) => SKIPPED_DIRECTORIES.has(segment))
46
+ );
35
47
  };
36
48
 
37
49
  const rulePathOf = (segments: ReadonlyArray<string>): ReadonlyArray<string> => {
@@ -1,4 +1,5 @@
1
1
  import { Context, Effect, FileSystem, Layer, Path } from "effect";
2
+ import { ADHERE_DIRECTORY, SKIPPED_DIRECTORIES } from "#config.ts";
2
3
  import type { ScannedFile } from "#models/Audit.ts";
3
4
  import { WalkUnavailable } from "#models/Audit.ts";
4
5
 
@@ -20,21 +21,15 @@ export class SourceWalker extends Context.Service<
20
21
  * trees. Otherwise read the working directory itself.
21
22
  */
22
23
  const WORKSPACE_DIRS = ["agents", "apps", "packages"] as const;
23
- /** Path fragments that mark generated, vendored, or dependency trees. */
24
- const SKIPS = [
25
- "/node_modules/",
26
- "/.adhere/",
27
- "/dist/",
28
- "/.agents/",
29
- "/.claude/",
30
- "/.direnv/",
31
- "/.alchemy/",
32
- "/coverage/",
33
- "/.vite/",
34
- "/references/",
35
- "/vendor/",
36
- "/e2e/",
37
- ] as const;
24
+ /**
25
+ * A path, relative to the root being read, through a skipped directory or
26
+ * through `.adhere/`, whose files are rules and cache rather than source.
27
+ * Relative, so the directories above the working directory never count.
28
+ */
29
+ export const isInSkippedTree = (relative: string): boolean =>
30
+ relative
31
+ .split(/[\\/]/)
32
+ .some((segment) => segment === ADHERE_DIRECTORY || SKIPPED_DIRECTORIES.has(segment));
38
33
 
39
34
  const isInside = (file: string, root: string): boolean =>
40
35
  file === root || file.startsWith(`${root}/`);
@@ -45,7 +40,6 @@ const isScannable = (file: string, self: string): boolean =>
45
40
  !file.endsWith(".test.ts") &&
46
41
  !file.endsWith("/adhere.config.ts") &&
47
42
  !file.endsWith("/.adhere.config.ts") &&
48
- SKIPS.every((skip) => !file.includes(skip)) &&
49
43
  // The audit's own detector patterns are data, not violations of themselves.
50
44
  !isInside(file, self);
51
45
 
@@ -57,7 +51,10 @@ const rooted = (root: string, paths: ReadonlyArray<string>) => paths.map((rel) =
57
51
 
58
52
  /** What the root actually contains: only paths the audit reads. */
59
53
  const scannable = (root: string, paths: ReadonlyArray<string>, self: string) =>
60
- rooted(root, paths).filter((file) => isScannable(file, self));
54
+ rooted(
55
+ root,
56
+ paths.filter((relative) => !isInSkippedTree(relative)),
57
+ ).filter((file) => isScannable(file, self));
61
58
 
62
59
  /** One root's paths, filtered to what the audit reads. */
63
60
  const listRoot = Effect.fn("SourceWalker.listRoot")(
package/.adhere/config.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { Config } from "../src/index.ts";
2
-
3
- // Type-only import: erased at runtime, so the compiled binary loads this file
4
- // without resolving the package (see README, "Configuration").
5
- export default {
6
- presets: ["effect"],
7
- } satisfies Config;
@@ -1,17 +0,0 @@
1
- ---
2
- description: An error raised while reading a config, rule, or cache file names that file in its message, so the user can open it.
3
- threshold: 0.8
4
- ---
5
-
6
- Adhere's own rule. A refusal is the only thing the user sees, so it points
7
- at the file it is about.
8
-
9
- ```ts
10
- const front =
11
- yield *
12
- Schema.decodeUnknownEffect(FrontMatter)(fields).pipe(
13
- Effect.mapError((problem) =>
14
- ConfigUnavailable.make({ message: `${file}: ${problem.message}` }),
15
- ),
16
- );
17
- ```
@@ -1,27 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- pull_request:
5
- push:
6
- branches: [main]
7
-
8
- jobs:
9
- verify:
10
- runs-on: ubuntu-latest
11
- steps:
12
- - uses: actions/checkout@v4
13
- - uses: oven-sh/setup-bun@v2
14
- with:
15
- bun-version: "1.4.2"
16
- - run: bun install --frozen-lockfile
17
- - run: bun run typecheck
18
- - run: bun run test
19
- - run: bun run build:npm
20
- - name: Run the launcher against the linux-x64 package
21
- run: |
22
- # Outside the checkout, where the launcher has no source to fall back to.
23
- launcher="$RUNNER_TEMP/launcher"
24
- mkdir -p "$launcher/node_modules/@drkmttr"
25
- cp -r bin "$launcher/bin"
26
- ln -s "$PWD/dist/npm/linux-x64" "$launcher/node_modules/@drkmttr/adhere-linux-x64"
27
- node "$launcher/bin/adhere.js" --version
@@ -1,68 +0,0 @@
1
- name: Publish
2
-
3
- on:
4
- workflow_call:
5
- inputs:
6
- tag_name:
7
- description: "Release tag to publish, for example v0.3.0."
8
- required: true
9
- type: string
10
- workflow_dispatch:
11
- inputs:
12
- tag_name:
13
- description: "Release tag to publish, for example v0.3.0."
14
- required: true
15
- type: string
16
-
17
- permissions:
18
- id-token: write
19
- contents: read
20
-
21
- jobs:
22
- publish:
23
- runs-on: ubuntu-latest
24
- steps:
25
- - uses: actions/checkout@v4
26
- with:
27
- ref: main
28
- - uses: oven-sh/setup-bun@v2
29
- with:
30
- bun-version: "1.4.2"
31
- - uses: actions/setup-node@v4
32
- with:
33
- node-version: "24"
34
- registry-url: "https://registry.npmjs.org"
35
- - name: Verify release tag matches package version
36
- env:
37
- TAG_NAME: ${{ inputs.tag_name }}
38
- run: |
39
- version="${TAG_NAME#v}"
40
- if [[ "$version" == "$TAG_NAME" || ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.+][0-9A-Za-z.-]+)?$ ]]; then
41
- echo "Release tags must look like vX.Y.Z, optionally with a prerelease/build suffix." >&2
42
- exit 1
43
- fi
44
- package_version="$(node -p "require('./package.json').version")"
45
- if [ "$version" != "$package_version" ]; then
46
- echo "Release tag $TAG_NAME does not match package.json version $package_version." >&2
47
- exit 1
48
- fi
49
- - run: bun install --frozen-lockfile
50
- - run: bun run typecheck
51
- - run: bun run test
52
- - run: bun run build:npm
53
- - name: Publish the platform packages
54
- run: |
55
- for directory in dist/npm/*/; do
56
- name="$(node -p "require('./${directory}package.json').name")"
57
- version="$(node -p "require('./${directory}package.json').version")"
58
- # A rerun after a partial publish skips the versions already on npm.
59
- if npm view "$name@$version" version >/dev/null 2>&1; then
60
- echo "$name@$version is already published."
61
- else
62
- npm publish "$directory" --access public --provenance
63
- fi
64
- done
65
- - name: Publish @drkmttr/adhere with the platform packages as optional dependencies
66
- run: |
67
- bun scripts/npm-packages.ts pin
68
- npm publish --access public --provenance
@@ -1,71 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- push:
5
- tags:
6
- - "v*"
7
-
8
- permissions:
9
- contents: write
10
-
11
- jobs:
12
- release:
13
- runs-on: ubuntu-latest
14
- steps:
15
- - name: Derive version from tag
16
- id: release
17
- shell: bash
18
- run: |
19
- version="${GITHUB_REF_NAME#v}"
20
- if [[ "$version" == "$GITHUB_REF_NAME" || ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.+][0-9A-Za-z.-]+)?$ ]]; then
21
- echo "Release tags must look like vX.Y.Z, optionally with a prerelease/build suffix." >&2
22
- exit 1
23
- fi
24
- echo "version=$version" >> "$GITHUB_OUTPUT"
25
-
26
- - uses: actions/checkout@v4
27
- with:
28
- ref: main
29
- fetch-depth: 0
30
-
31
- - name: Ensure tag was cut from current main
32
- shell: bash
33
- run: |
34
- tag_sha="$(git rev-list -n 1 "$GITHUB_REF_NAME")"
35
- main_sha="$(git rev-parse HEAD)"
36
- if [[ "$tag_sha" != "$main_sha" ]]; then
37
- echo "Tag $GITHUB_REF_NAME must point at current main before release-it adds the version bump commit." >&2
38
- echo "tag=$tag_sha main=$main_sha" >&2
39
- exit 1
40
- fi
41
-
42
- - uses: oven-sh/setup-bun@v2
43
- with:
44
- bun-version: "1.4.2"
45
-
46
- - uses: actions/setup-node@v4
47
- with:
48
- node-version: "24"
49
-
50
- - name: Configure git author
51
- run: |
52
- git config user.name "github-actions[bot]"
53
- git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
54
-
55
- - run: bun install --frozen-lockfile
56
- - run: bun run typecheck
57
- - run: bun run test
58
- - run: bun run build:npm
59
- - name: Create GitHub release
60
- run: bun run release -- --ci "${{ steps.release.outputs.version }}"
61
- env:
62
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63
-
64
- publish:
65
- needs: release
66
- uses: ./.github/workflows/publish.yaml
67
- permissions:
68
- contents: read
69
- id-token: write
70
- with:
71
- tag_name: ${{ github.ref_name }}