@ggdna/dna-gg 0.13.0 → 0.14.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 CHANGED
@@ -9,7 +9,15 @@ publish.
9
9
  `dna/doc/guides/develop-without-ai-guide.md` — the ticket driven
10
10
  workflow, with and without an AI
11
11
  - `dna/doc/guides/for-ai/ai-dev-guide.md` — the same workflow as
12
- instructions for an agent
12
+ instructions for an agent. Its section "Keep every repo in its scope"
13
+ makes the agent propose on its own to split a repo, add a new or an
14
+ existing one, or move code, whenever code leaves the scope of its repo
15
+ — and its section "Keep the index.jsonc up to date" makes it update the
16
+ `index.jsonc` with every code change that alters what the repo does or
17
+ uses, and create it in every repo of a ticket that has none yet. Its
18
+ section "Describe every repo in its own terms" keeps the parent repos of
19
+ a ticket out of what the agent writes into their dependencies: commit
20
+ and merge messages, changelog, blog posts, code comments, `index.jsonc`
13
21
  - `dna/doc/guides/install-guide/install-gg-guide.md`,
14
22
  `dna/doc/guides/install-guide/install-gg-workspace-guide.md` — install
15
23
  `gg` and set up a workspace
@@ -26,10 +34,12 @@ publish.
26
34
  All skills of this layer are prefixed with `gg-`:
27
35
 
28
36
  - `/gg` — lists the skills below and says which one comes next
29
- - `/gg-ticket` — creates a ticket and adds the repos it needs
37
+ - `/gg-ticket` — creates a ticket, adds the repos it needs and keeps
38
+ every repo in its scope
30
39
  - `/gg-commit` — proposes a message and commits through `gg do commit`
31
40
  - `/gg-push` — pushes the ticket branches
32
- - `/gg-review` — writes the blog posts and opens the pull requests
41
+ - `/gg-review` — checks the scope of every repo, writes the blog posts
42
+ and opens the pull requests
33
43
  - `/gg-publish` — releases the ticket
34
44
  - `/gg-cleanup` — removes what the ticket left behind
35
45
 
@@ -91,9 +101,11 @@ appends the `Workspace` section.
91
101
  - `dnaJiraPrefix` — the prefix of a ticket id
92
102
  - `dnaGitQuickCheckPipelineName` — the name the branch rules require
93
103
  - `dnaPubDevPublisher` — the pub.dev publisher packages are transferred to
94
- - `dnaPmRepo` — the project management repo the prompts go to: a repo
95
- name beside the repo's own origin, or a full git URL. Empty by default,
96
- then no prompt is kept
104
+ - `dnaPmRepo` — the project management repo the prompts go to: its name
105
+ with `.git` appended, e.g. `my_pm.git`, which finds it beside the repo's
106
+ own origin, or a full git URL. helix re-cases a bare name like `my_pm`
107
+ to the case of the reference, `.git` keeps it as written. Empty by
108
+ default, then no prompt is kept
97
109
 
98
110
  `dnaCopyrightHolder`, `dnaCompany` and `dnaJiraPrefix` name the
99
111
  organization, so they are never inherited: every layer or project listing
@@ -39,7 +39,7 @@
39
39
  "ecosystem": null,
40
40
  "resolvedVersion": null,
41
41
  "via": null,
42
- "hash": "0x5cf663c108f9dc04"
42
+ "hash": "0xb282e7ad6fa403dc"
43
43
  }
44
44
  ],
45
45
  "claude": {
@@ -55,7 +55,7 @@
55
55
  },
56
56
  {
57
57
  "path": ".claude/hooks/pm-prompts.mjs",
58
- "hash": "0xd579ad4abeb87732"
58
+ "hash": "0x988aed96a8073727"
59
59
  },
60
60
  {
61
61
  "path": ".claude/settings.json",
@@ -67,7 +67,7 @@
67
67
  },
68
68
  {
69
69
  "path": ".claude/skills/gg-commit/SKILL.md",
70
- "hash": "0xdb7a268397facfc4"
70
+ "hash": "0x7fbe4b075588fc4d"
71
71
  },
72
72
  {
73
73
  "path": ".claude/skills/gg-publish/SKILL.md",
@@ -79,11 +79,11 @@
79
79
  },
80
80
  {
81
81
  "path": ".claude/skills/gg-review/SKILL.md",
82
- "hash": "0x09df48b6f6bf1de6"
82
+ "hash": "0x9f7bbbe511238684"
83
83
  },
84
84
  {
85
85
  "path": ".claude/skills/gg-ticket/SKILL.md",
86
- "hash": "0xa238364995ac50f8"
86
+ "hash": "0xc238102fbb3eda52"
87
87
  },
88
88
  {
89
89
  "path": ".claude/skills/gg/SKILL.md",
@@ -111,7 +111,7 @@
111
111
  },
112
112
  {
113
113
  "path": "doc/guides/for-ai/ai-dev-guide.md",
114
- "hash": "0xb4ae698a82bc9e2c"
114
+ "hash": "0xba608ae9efe904ab"
115
115
  },
116
116
  {
117
117
  "path": "doc/guides/index-guide.md",
@@ -73,11 +73,12 @@ confirmation; add the repos as shown below.
73
73
  Automatically: look at the `index.jsonc` of each repo in .ocean and decide
74
74
  which repos need to be added to the ticket.
75
75
  Make a plan for how you roughly want to implement the ticket.
76
- If certain parts of the implementation belong to a domain that does not yet
77
- exist in the .ocean folder, consider creating a new repository.
78
- Ask the user about this. Also explain to the user what you roughly want to
79
- change in which repo to implement the ticket and let them confirm that the
80
- corresponding repos are added to the ticket.
76
+ Check the plan against the scope of each repo (see
77
+ [Keep every repo in its scope](#keep-every-repo-in-its-scope)) and propose
78
+ a split, a new repo or a move wherever a part does not fit.
79
+ Also explain to the user what you roughly want to change in which repo to
80
+ implement the ticket and let them confirm that the corresponding repos are
81
+ added to the ticket.
81
82
 
82
83
  If the ticket is only planned (see below), the project management repo may
83
84
  be the only repo of the ticket.
@@ -88,6 +89,47 @@ After the user's confirmation, add the repos to the ticket:
88
89
  gg do add repo1 repo2
89
90
  ```
90
91
 
92
+ ## Keep every repo in its scope
93
+
94
+ Every repo covers one fixed scope: the `summary` and `domain` of its
95
+ `index.jsonc`. If a repo has none, take the scope from its README.md and
96
+ create the `index.jsonc` with the first change of the ticket in that repo
97
+ (see [Keep the index.jsonc up to date](#keep-the-indexjsonc-up-to-date)).
98
+ Code outside that scope blurs the repo. Check the scope whenever you decide
99
+ where code goes — while choosing the repos, while implementing and before
100
+ the review — and propose a change on your own, without being asked, as soon
101
+ as code does not fit the repo it is in or is about to land in:
102
+
103
+ - **Split a repo** — the repo has grown a second scope: propose splitting
104
+ it into two repos, each with a scope of its own
105
+ - **Add a new repo** — the code belongs to a domain no repo in .ocean
106
+ covers: propose creating one with `gg do create repo`, which adds it to
107
+ the ticket
108
+ - **Add an existing repo** — the code belongs to a repo in .ocean that is
109
+ not part of the ticket yet: propose adding it with `gg do add`
110
+ - **Move code** — existing code, or code you just wrote, belongs to another
111
+ repo: propose moving it there
112
+
113
+ For each proposal, name the code concerned, the repo it is in, the repo it
114
+ should go to, and why it fits the scope of that repo better. Then let the
115
+ user decide:
116
+
117
+ - **Now** — change it within this ticket: add or create the repo, move the
118
+ code, and adjust the dependencies and imports of both sides
119
+ - **Later** — keep it as a follow-up ticket: in the project management repo
120
+ if the ticket has one, otherwise in the ticket. Continue with the code
121
+ where it is.
122
+
123
+ Whenever the scope of a repo changes, update the `index.jsonc` of each repo
124
+ concerned (see
125
+ [Keep the index.jsonc up to date](#keep-the-indexjsonc-up-to-date)): a new
126
+ or split-off repo gets its own `summary` and `domain`, the repo that gives
127
+ code away is narrowed accordingly, and `interfaces.uses` and
128
+ `interfaces.usedBy` follow the new dependencies.
129
+
130
+ Never split a repo, add or create one, or move code without the user's
131
+ confirmation.
132
+
91
133
  ## Open the workspace in Vscode
92
134
 
93
135
  ```bash
@@ -117,10 +159,67 @@ Ask the user whether the ticket is implemented now, or whether it is only
117
159
  planned. Some tickets are only planned; the implementation follows in a later
118
160
  ticket.
119
161
 
120
- - Implement: implement your features based on the guides
162
+ - Implement: implement your features based on the guides. Write the code
163
+ comments and documentation of a dependency in its own terms, without its
164
+ parents (see
165
+ [Describe every repo in its own terms](#describe-every-repo-in-its-own-terms)).
166
+ Keep every repo in its scope while you code: stop and propose a split,
167
+ a new repo or a move as soon as code does not fit (see
168
+ [Keep every repo in its scope](#keep-every-repo-in-its-scope))
121
169
  - Plan only: skip this step. The following steps then apply to the project
122
170
  management repo only.
123
171
 
172
+ ## Keep the index.jsonc up to date
173
+
174
+ The `index.jsonc` of a repo describes what the repo is: its `summary`, its
175
+ `domain` and its `interfaces`. Other agents choose the repos of a ticket by
176
+ it, so it must match the code at all times, not only at the review.
177
+
178
+ Whenever you change code in a repo, check whether its `index.jsonc` still
179
+ matches and update it in the same step:
180
+
181
+ - `summary` and `domain` — when the repo can do something new, no longer
182
+ does something, or its scope changed
183
+ - `interfaces.uses` — when the repo starts or stops using another repo, or
184
+ uses a different API of it
185
+ - `interfaces.usedBy` — when another repo starts or stops using this one;
186
+ update the `uses` of that repo too, so both sides agree
187
+
188
+ A repo without `index.jsonc` gets one with the first change of the ticket,
189
+ whatever the change: copy `doc/templates/index-template.jsonc` to
190
+ `index.jsonc` and fill it from the README.md and the code. Never leave a
191
+ repo of the ticket without one.
192
+
193
+ Follow `doc/guides/index-guide.md`: keywords instead of sentences, the
194
+ fields of the template only. Once the file exists, a change that leaves all
195
+ three fields true — a bug fix, a refactoring inside the repo — needs no
196
+ update.
197
+
198
+ ## Describe every repo in its own terms
199
+
200
+ A ticket often changes a repo together with one of its dependencies: the
201
+ parent repo uses the dependency. The dependency does not know its parents,
202
+ so what you write into it describes its own change only — never why a
203
+ parent needs it. This holds for everything you write into the dependency:
204
+
205
+ - commit messages, `nextCommitMessage` and `mergeMessage` — and with them
206
+ the `CHANGELOG.md` entry and the pull request title
207
+ - blog posts
208
+ - code comments and documentation
209
+ - its `index.jsonc`, except `interfaces.usedBy`, which names the parents
210
+ on purpose
211
+
212
+ Never name a parent repo there, nor the goal of the ticket or the use case
213
+ of the parent. The parent, in turn, may name the dependency and what it
214
+ uses of it.
215
+
216
+ - Wrong in `gg_git`: `Add remote creation for gg do create repo`
217
+ - Right in `gg_git`: `Add a function that creates a remote repository`
218
+ - Right in `gg`: `Create the remote repository with gg_git`
219
+
220
+ Which repo depends on which is in `interfaces.uses` of the `index.jsonc`,
221
+ and in `pubspec.yaml` or `package.json`.
222
+
124
223
  ## Keep the publish config up to date
125
224
 
126
225
  Each repo of the ticket has a file `.gg/publish_config.json`. gg offers its
@@ -146,7 +245,8 @@ to change and keep the rest — `commits` is written by gg, never by hand.
146
245
  }
147
246
  ```
148
247
 
149
- - `firstLine`: imperative, at most 60 characters
248
+ - `firstLine`: imperative, at most 60 characters, in the terms of the
249
+ repo itself (see [Describe every repo in its own terms](#describe-every-repo-in-its-own-terms))
150
250
  - `details`: optional, one entry per line
151
251
  - `mergeMessage`: the pull request title and the merge commit message of
152
252
  the repo
@@ -163,6 +263,19 @@ ticket folder reads `nextCommitMessage`; `gg one do commit` does not.
163
263
  gg do commit
164
264
  ```
165
265
 
266
+ Every repo gets its own message. When repos of the ticket depend on each
267
+ other, never commit them with one `-m` for all. Commit each repo on its own
268
+ with its `nextCommitMessage` (see
269
+ [Describe every repo in its own terms](#describe-every-repo-in-its-own-terms)):
270
+
271
+ ```bash
272
+ cd repo1
273
+ gg one do commit -m"<nextCommitMessage of repo1>"
274
+ ```
275
+
276
+ `gg do commit` without `-m` offers the same messages, but in an editor the
277
+ user has to confirm — leave that way to the user.
278
+
166
279
  `gg do commit` and `gg can commit` act on all repos of the ticket. When you
167
280
  are inside a single repo instead of the ticket folder, use the standalone
168
281
  form on that repo:
@@ -180,12 +293,19 @@ gg do push
180
293
 
181
294
  ## Review
182
295
 
183
- Document the change in every repo first, so the documentation lands in
184
- the pull requests and is reviewed with the code:
296
+ Check the diff of every repo of the ticket against its scope first (see
297
+ [Keep every repo in its scope](#keep-every-repo-in-its-scope)) and propose
298
+ a split, a new repo or a move for everything that does not fit.
299
+
300
+ Then document the change in every repo, so the documentation lands in the
301
+ pull requests and is reviewed with the code:
185
302
 
186
303
  - Run `/blog` in every repo of the ticket that has
187
- `doc/guides/blog-guide.md`, the project management repo included
188
- - Update the index.jsonc and README.md
304
+ `doc/guides/blog-guide.md`, the project management repo included. A
305
+ dependency's post describes its own change, without its parents (see
306
+ [Describe every repo in its own terms](#describe-every-repo-in-its-own-terms))
307
+ - Update the README.md, and check once more that every repo has an
308
+ `index.jsonc` and that it matches the code of the ticket
189
309
  - Commit and push again
190
310
 
191
311
  Let the user confirm that the review phase is started.
@@ -157,14 +157,17 @@ function originOf(dir, depth = 0) {
157
157
  /**
158
158
  * The URL of the project management repo [pmRepo] beside the repo cloned
159
159
  * from [origin]: same host, same organization. A full URL is taken as is.
160
+ * The name may end in `.git`: the DNA writes it that way, because helix
161
+ * would re-case a bare name like `my_pm` into `myPm`.
160
162
  */
161
163
  export function pmRepoUrl(pmRepo, origin) {
162
164
  if (!pmRepo) return '';
163
165
  if (/^[a-z][a-z0-9+.-]*:\/\/|^[^/\\\s]+@[^/\\\s]+:/i.test(pmRepo)) {
164
166
  return pmRepo;
165
167
  }
168
+ const name = pmRepo.replace(/\.git$/, '');
166
169
  const match = (origin ?? '').match(/^(.*[/:\\])[^/:\\]+?(\.git)?[/\\]?$/);
167
- return match ? `${match[1]}${pmRepo}${match[2] ?? ''}` : '';
170
+ return match ? `${match[1]}${name}${match[2] ?? ''}` : '';
168
171
  }
169
172
 
170
173
  /**
@@ -20,19 +20,40 @@ whenever you are inside a repo.
20
20
 
21
21
  ## 2. Propose a message
22
22
 
23
- Look at `git status` and `git diff` in the repos of the ticket. Propose one
24
- imperative one-liner that says what the step does, not which files changed.
25
- Start from `nextCommitMessage` in `.gg/publish_config.json` of each repo and
26
- update it there if it no longer matches the diff (see the development
27
- guide). Let the user confirm it.
23
+ Look at `git status` and `git diff` in the repos of the ticket. Propose
24
+ for each repo an imperative one-liner that says what the step does in that
25
+ repo, not which files changed. Start from `nextCommitMessage` in
26
+ `.gg/publish_config.json` of each repo and update it there if it no longer
27
+ matches the diff (see the development guide). Let the user confirm them.
28
+
29
+ A dependency describes its change in its own terms. When a repo of the
30
+ ticket uses another one, the message of the dependency never names the
31
+ parent repo, the goal of the ticket or the use case of the parent — the
32
+ parent may name the dependency. The same holds for the `mergeMessage`.
33
+
34
+ - Wrong in `gg_git`: `Add remote creation for gg do create repo`
35
+ - Right in `gg_git`: `Add a function that creates a remote repository`
36
+ - Right in `gg`: `Create the remote repository with gg_git`
37
+
38
+ Section "Describe every repo in its own terms" of
39
+ `doc/guides/for-ai/ai-dev-guide.md` has the details.
40
+
41
+ Check in the same pass whether the diff changes what the `index.jsonc` of
42
+ the repo says — its `summary`, `domain` or `interfaces` — and update it
43
+ before committing. If the repo has no `index.jsonc`, create it now from
44
+ `doc/templates/index-template.jsonc`, whatever the diff. Section "Keep the
45
+ index.jsonc up to date" of `doc/guides/for-ai/ai-dev-guide.md` has the
46
+ details.
28
47
 
29
48
  If the user runs `gg do commit` in the ticket folder without `-m`, the
30
49
  editor already shows each repo's `nextCommitMessage` — `-m` overrides it
31
- with one message for all repos.
50
+ with one message for all repos. Use `-m` in the ticket folder only when no
51
+ repo of the ticket depends on another; otherwise commit each repo on its
52
+ own with `gg one do commit -m` and its `nextCommitMessage`.
32
53
 
33
54
  ## 3. Commit
34
55
 
35
- From the ticket folder:
56
+ From the ticket folder, when no repo of the ticket depends on another:
36
57
 
37
58
  ```bash
38
59
  gg do commit -m"<message>"
@@ -56,4 +77,5 @@ its source under `dna/` instead.
56
77
  ## Important
57
78
 
58
79
  - Never commit without the confirmed message.
80
+ - Never let a parent repo leak into the message of its dependency.
59
81
  - Never push here — that is `/gg-push`.
@@ -9,19 +9,36 @@ Each repo documents its change first, so the documentation lands in the
9
9
  pull requests and is reviewed with the code. Every commit after
10
10
  `gg do review` voids the review.
11
11
 
12
- ## 1. Document the change in every repo
12
+ ## 1. Check the scope of every repo
13
+
14
+ Every repo covers one fixed scope: the `summary` and `domain` of its
15
+ `index.jsonc`, or its README.md if it has none. Read the diff of every repo
16
+ of the ticket against that scope. For code that does not fit, propose on
17
+ your own a split of the repo, a new repo, an existing repo to add, or a
18
+ move of the code into the repo whose scope it fits — with the reason. Let
19
+ the user decide whether it changes now, within this ticket, or later, as a
20
+ follow-up ticket. Section "Keep every repo in its scope" of
21
+ `doc/guides/for-ai/ai-dev-guide.md` has the details.
22
+
23
+ ## 2. Document the change in every repo
13
24
 
14
25
  Look for `doc/guides/blog-guide.md` in every repo of the ticket, the
15
26
  project management repo included. It comes from the `dna_blog` layer.
16
27
 
17
28
  - Run `/blog` in each repo that has it; skip the others
29
+ - A dependency's post describes its own change only: it never names the
30
+ repos of the ticket that use it, nor their goal — section "Describe
31
+ every repo in its own terms" of `doc/guides/for-ai/ai-dev-guide.md`
18
32
  - `/blog` stops by itself when the post already exists
19
33
 
20
- Update `index.jsonc` and `README.md` of each repo the ticket changed.
34
+ Update `README.md` of each repo the ticket changed. Check once more that
35
+ each of them has an `index.jsonc` — create it from
36
+ `doc/templates/index-template.jsonc` if not — and that it matches the code
37
+ of the ticket.
21
38
 
22
39
  Let the user review the changes, then run `/gg-commit` and `/gg-push`.
23
40
 
24
- ## 2. Open the pull requests
41
+ ## 3. Open the pull requests
25
42
 
26
43
  Let the user confirm that the review phase is started. From the ticket
27
44
  folder:
@@ -33,7 +50,7 @@ gg do review
33
50
  gg creates a pull request for each repo and prints the URLs to the
34
51
  terminal.
35
52
 
36
- ## 3. Review the changes
53
+ ## 4. Review the changes
37
54
 
38
55
  Load the `/review-light` skill and execute it.
39
56
 
@@ -55,10 +55,12 @@ Call it the "project management repo" whenever you write to the user, never
55
55
  Ask the user how the code repos are chosen, as a single question with two
56
56
  options:
57
57
 
58
- - **automatically** — Claude finds the repos. Read the `index.md` of the
59
- candidate repos in `.ocean`. Tell the user which repos the ticket needs
60
- and what you roughly want to change in each one. If a part belongs to a
61
- domain that has no repo yet, say so and ask whether to create one.
58
+ - **automatically** — Claude finds the repos. Read the `index.jsonc` of
59
+ the candidate repos in `.ocean`. Tell the user which repos the ticket
60
+ needs and what you roughly want to change in each one. Check each part
61
+ against the scope of its repo and propose a split, a new repo or a move
62
+ wherever a part does not fit (see
63
+ [Keep every repo in its scope](#keep-every-repo-in-its-scope)).
62
64
  - **manually** — the user names the repos. Ask in a second single input
63
65
  field which repos the ticket needs, e.g. `repo1 repo2`. Check each name
64
66
  against the repos in `.ocean` and ask again for names that do not exist
@@ -93,8 +95,38 @@ confirm it there. Then ask whether the ticket is implemented now or only
93
95
  planned — in the latter case the ticket ends with the project management
94
96
  repo alone.
95
97
 
98
+ While implementing, write the code comments and documentation of a
99
+ dependency in its own terms: never name the repos of the ticket that use
100
+ it, nor their goal (section "Describe every repo in its own terms" of
101
+ `doc/guides/for-ai/ai-dev-guide.md`). Keep every repo in its scope: stop
102
+ and propose a split, a new repo or a move as soon as code does not fit (see
103
+ below). With every code change, check whether the `index.jsonc` of the repo
104
+ still matches and update it in the same step; a repo without one gets it
105
+ with its first change — section "Keep the index.jsonc up to date" of
106
+ `doc/guides/for-ai/ai-dev-guide.md` says when and how.
107
+
108
+ ## Keep every repo in its scope
109
+
110
+ Every repo covers one fixed scope: the `summary` and `domain` of its
111
+ `index.jsonc`, or its README.md as long as it has none. From choosing the
112
+ repos until the review, propose a change on your own as soon as code does
113
+ not fit the repo it is in or is about to land in:
114
+
115
+ - **Split a repo** that has grown a second scope into two repos
116
+ - **Add a new repo** with `gg do create repo` for a domain no repo covers
117
+ - **Add an existing repo** with `gg do add` when the code belongs there
118
+ - **Move code**, existing or just written, into the repo whose scope it fits
119
+
120
+ Name the code, the repo it is in, the repo it should go to and why. Let the
121
+ user decide whether it changes now, within this ticket, or later, as a
122
+ follow-up ticket. After a change of scope, update the `index.jsonc` of each
123
+ repo concerned. Section "Keep every repo in its scope" of
124
+ `doc/guides/for-ai/ai-dev-guide.md` has the details.
125
+
96
126
  ## Important
97
127
 
98
128
  - Never add repos without confirmation — a manually entered list counts as
99
129
  one. Rather too few than too many — more can be added later.
100
130
  - Do not start the implementation unasked.
131
+ - Never split a repo, add or create one, or move code without the user's
132
+ confirmation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggdna/dna-gg",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "DNA layer: gg CLI workflow guides, repo setup scripts and CI check",
5
5
  "keywords": [
6
6
  "dna",