the_local 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/the_local/refresh.rb +6 -1
- data/lib/the_local/sync.rb +0 -1
- data/lib/the_local/version.rb +1 -1
- data/lib/the_local.rb +0 -1
- metadata +2 -5
- data/lib/the_local/process_doc_writer.rb +0 -48
- data/lib/the_local/process_rules/develop_process_rules.md +0 -97
- data/lib/the_local/process_rules.rb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 16bc7ddfcc1ddab88976b10b156791a4e9a1985265d472517db9c56816d8022e
|
|
4
|
+
data.tar.gz: 57c2ec4821bd1165037311dad0720cbcf1a753770052e0f88ae5a879f4e8c2f7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf6c8dfab319c69dd82da9654cee64085c0aca38253ad29bdd37794887ff8b35136c5c1f5288e4beab1688d767b4f7f53f02ca115c7d0abcc40b3d34eeac2e2f
|
|
7
|
+
data.tar.gz: 33a1549f7efedbcf20f3350f0c38224f03acf2865de2b7524037ba4c13889bf65b0ff75c2eff1d47a0ac6a0b4b57bdf57efcff4bd17b91a8c6a5bd1748258b8c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-07-01
|
|
4
|
+
|
|
5
|
+
- Installing no longer writes a `develop_process_rules.md` into host apps. The
|
|
6
|
+
`ProcessDocWriter`/`ProcessRules` machinery and its bundled doc are removed, so
|
|
7
|
+
`Sync`/`refresh` only install locals and the delegation trigger — a gem's
|
|
8
|
+
process conventions belong in its own guide, not propagated as a shared file.
|
|
9
|
+
- A gem no longer installs its own locals into its own repo: `refresh` excludes
|
|
10
|
+
the gem being run from the direct-dependency set, so a provider working on
|
|
11
|
+
itself doesn't copy its locals back into `.claude/agents/`.
|
|
12
|
+
|
|
3
13
|
## [0.2.0] - 2026-06-20
|
|
4
14
|
|
|
5
15
|
- `rake the_local:build` now refuses a guide that still holds line-leading
|
data/lib/the_local/refresh.rb
CHANGED
|
@@ -16,7 +16,7 @@ module TheLocal
|
|
|
16
16
|
Sync.new(
|
|
17
17
|
registry: TheLocal.registry,
|
|
18
18
|
destination: destination,
|
|
19
|
-
direct_dependencies: definition.dependencies.map(&:name),
|
|
19
|
+
direct_dependencies: definition.dependencies.map(&:name) - [own_gem_name(definition, destination)],
|
|
20
20
|
bundled_gems: definition.specs.map(&:name)
|
|
21
21
|
).call
|
|
22
22
|
end
|
|
@@ -24,5 +24,10 @@ module TheLocal
|
|
|
24
24
|
def self.specs_from(definition)
|
|
25
25
|
definition.specs.map { |spec| { name: spec.name, path: spec.full_gem_path } }
|
|
26
26
|
end
|
|
27
|
+
|
|
28
|
+
def self.own_gem_name(definition, destination)
|
|
29
|
+
here = File.expand_path(destination)
|
|
30
|
+
definition.specs.find { |spec| File.expand_path(spec.full_gem_path) == here }&.name
|
|
31
|
+
end
|
|
27
32
|
end
|
|
28
33
|
end
|
data/lib/the_local/sync.rb
CHANGED
|
@@ -21,7 +21,6 @@ module TheLocal
|
|
|
21
21
|
)
|
|
22
22
|
Installer.new(registry: @registry, destination: @destination, allowed_gems: allowed).call
|
|
23
23
|
TriggerWriter.new(registry: @registry, destination: @destination, allowed_gems: allowed).call
|
|
24
|
-
ProcessDocWriter.new(destination: @destination).call
|
|
25
24
|
allowed
|
|
26
25
|
end
|
|
27
26
|
end
|
data/lib/the_local/version.rb
CHANGED
data/lib/the_local.rb
CHANGED
|
@@ -5,7 +5,6 @@ require_relative "the_local/agent"
|
|
|
5
5
|
require_relative "the_local/registry"
|
|
6
6
|
require_relative "the_local/installer"
|
|
7
7
|
require_relative "the_local/trigger_writer"
|
|
8
|
-
require_relative "the_local/process_doc_writer"
|
|
9
8
|
require_relative "the_local/scope"
|
|
10
9
|
require_relative "the_local/sync"
|
|
11
10
|
require_relative "the_local/refresh"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: the_local
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tylercschneider
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: the_local lets any gem or app declare Claude Code subagents ("locals")
|
|
14
14
|
that know its conventions, and installs the aggregated set from every installed
|
|
@@ -38,9 +38,6 @@ files:
|
|
|
38
38
|
- lib/the_local/cli.rb
|
|
39
39
|
- lib/the_local/disk_providers.rb
|
|
40
40
|
- lib/the_local/installer.rb
|
|
41
|
-
- lib/the_local/process_doc_writer.rb
|
|
42
|
-
- lib/the_local/process_rules.rb
|
|
43
|
-
- lib/the_local/process_rules/develop_process_rules.md
|
|
44
41
|
- lib/the_local/railtie.rb
|
|
45
42
|
- lib/the_local/rake.rb
|
|
46
43
|
- lib/the_local/reference.rb
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "process_rules"
|
|
4
|
-
|
|
5
|
-
module TheLocal
|
|
6
|
-
# Writes the canonical develop-process rules into a host's CLAUDE.md as a
|
|
7
|
-
# managed block, read at the start of every session so the host agent always
|
|
8
|
-
# follows one source of truth. Re-propagated on every install/refresh. Uses
|
|
9
|
-
# its own markers so it coexists with the delegation trigger in the same file.
|
|
10
|
-
class ProcessDocWriter
|
|
11
|
-
BEGIN_MARKER = "<!-- the_local:process:begin -->"
|
|
12
|
-
END_MARKER = "<!-- the_local:process:end -->"
|
|
13
|
-
RULES_FILENAME = "develop_process_rules.md"
|
|
14
|
-
|
|
15
|
-
def initialize(destination:, filename: "CLAUDE.md")
|
|
16
|
-
@destination = destination
|
|
17
|
-
@filename = filename
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def call
|
|
21
|
-
File.write(File.join(@destination, RULES_FILENAME), "#{ProcessRules.content}\n")
|
|
22
|
-
path = File.join(@destination, @filename)
|
|
23
|
-
existing = File.exist?(path) ? File.read(path) : ""
|
|
24
|
-
File.write(path, "#{merge(existing)}\n")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def block
|
|
28
|
-
<<~MARKDOWN.chomp
|
|
29
|
-
#{BEGIN_MARKER}
|
|
30
|
-
Read and follow this develop process for all work in this project. It is
|
|
31
|
-
also written verbatim to `#{RULES_FILENAME}` — reference that file directly.
|
|
32
|
-
|
|
33
|
-
#{ProcessRules.content}
|
|
34
|
-
#{END_MARKER}
|
|
35
|
-
MARKDOWN
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def merge(existing)
|
|
41
|
-
section = /#{Regexp.escape(BEGIN_MARKER)}.*?#{Regexp.escape(END_MARKER)}/m
|
|
42
|
-
return existing.sub(section, block) if existing.match?(section)
|
|
43
|
-
return block if existing.strip.empty?
|
|
44
|
-
|
|
45
|
-
"#{existing.chomp}\n\n#{block}"
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# Develop Process
|
|
2
|
-
|
|
3
|
-
The standard process for writing code across all projects. Default to these rules
|
|
4
|
-
unless a project explicitly overrides them.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Diverging from this process
|
|
9
|
-
|
|
10
|
-
Read this process before starting work and follow it — it is the default for
|
|
11
|
-
every session. If a task genuinely calls for breaking one of these rules, do not
|
|
12
|
-
silently deviate: **PAUSE and ask for a one-time exception**, naming the rule and
|
|
13
|
-
why it should be set aside here. An exception is granted for that instance only —
|
|
14
|
-
it needs no doc or notes update — and then you continue. Do not treat a granted
|
|
15
|
-
exception as a standing change to the process.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Test-Driven Development
|
|
20
|
-
|
|
21
|
-
TDD is the default for everything. Work one tiny cycle at a time:
|
|
22
|
-
|
|
23
|
-
1. **Write one test that asserts one thing.**
|
|
24
|
-
2. **Run it and watch it fail** — for the right reason. A test you never saw fail
|
|
25
|
-
proves nothing.
|
|
26
|
-
3. **Write the minimum code to make it pass.**
|
|
27
|
-
4. **Run the test and watch it pass.**
|
|
28
|
-
5. **Commit.**
|
|
29
|
-
6. Repeat with the next test.
|
|
30
|
-
|
|
31
|
-
One assertion per test. One test per commit cycle. No batching multiple behaviors
|
|
32
|
-
into a single test or a single commit.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Commits
|
|
37
|
-
|
|
38
|
-
- A commit is normally **two files: the test file and the code file.**
|
|
39
|
-
- When implementing or updating an interface (e.g. a new controller endpoint) a
|
|
40
|
-
commit may touch more files (route + controller + view) — that is the minimal
|
|
41
|
-
coherent unit for that interface, and it is allowed.
|
|
42
|
-
- Keep each commit focused on the one behavior the test describes.
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## What to Test
|
|
47
|
-
|
|
48
|
-
- **Test our own code only.**
|
|
49
|
-
- **Never test third-party code** — not a gem, not an API, not a framework. The
|
|
50
|
-
only test that may reference a dependency is one that asserts *our system is
|
|
51
|
-
correctly wired to it* (the integration seam), never the dependency's own
|
|
52
|
-
behavior.
|
|
53
|
-
- **Never test another interface inside a unit test.** A test covers one interface.
|
|
54
|
-
The single exception is the smoke integration test described below.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Smoke Integration Test
|
|
59
|
-
|
|
60
|
-
When implementing an interface, write **one smoke integration test** that exercises
|
|
61
|
-
the interface end to end and proves the pieces are connected. This is the one place
|
|
62
|
-
where touching more than the unit under test is expected and correct.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Pull Requests
|
|
67
|
-
|
|
68
|
-
- **Always work on a feature branch and open a PR.** Confirm the target branch
|
|
69
|
-
before any git operation (`git branch --show-current`).
|
|
70
|
-
- **Keep PRs small and manageable** — typically **no more than 8–10 files.**
|
|
71
|
-
- Keep the focus of a PR narrow. One concern per PR.
|
|
72
|
-
- **All tests pass before opening the PR.**
|
|
73
|
-
- **The linter and every other CI check pass before opening the PR.**
|
|
74
|
-
- Never start a new PR until the previous one is merged.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Code Quality
|
|
79
|
-
|
|
80
|
-
- Follow Clean Code principles: small functions, clear names, no surprises.
|
|
81
|
-
- Follow SOLID principles. Readable by a human first.
|
|
82
|
-
- Keep it simple — no abstraction until a real need calls for it.
|
|
83
|
-
- Explicitly require libraries rather than assuming autoload.
|
|
84
|
-
|
|
85
|
-
## Comments
|
|
86
|
-
|
|
87
|
-
- **Write self-documenting code, not comments.** Code should be clean and readable
|
|
88
|
-
on its own. Names — of classes, methods, variables, and partials — carry the intent.
|
|
89
|
-
- **A comment is a smell.** If you feel a comment is needed, the code is either built
|
|
90
|
-
wrong or needs refactoring (a clearer name, a smaller method, an extracted object or
|
|
91
|
-
partial) so the intent is obvious without prose. Follow SOLID and this resolves itself.
|
|
92
|
-
- Do not leave explanatory headers on classes/methods, inline "what this does" notes,
|
|
93
|
-
or section banners. Delete them and let the structure speak.
|
|
94
|
-
- Narrow exceptions, kept rare: a genuinely non-obvious *why* (a workaround for an
|
|
95
|
-
external bug, a legal/security constraint) and machine-readable annotations the
|
|
96
|
-
tooling requires (e.g. `rubocop:disable`). Prefer refactoring over a "why" comment
|
|
97
|
-
whenever you can.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module TheLocal
|
|
4
|
-
# Loads the canonical develop-process rules the_local propagates into every
|
|
5
|
-
# host, so a host agent reads and follows one source of truth.
|
|
6
|
-
module ProcessRules
|
|
7
|
-
DIR = File.expand_path("process_rules", __dir__)
|
|
8
|
-
|
|
9
|
-
def self.content
|
|
10
|
-
read("develop_process_rules.md")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.read(name)
|
|
14
|
-
File.read(File.join(DIR, name)).chomp
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|