@ggdna/dna-gg 0.3.0 → 0.4.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/dna/_generated.json +12 -24
- package/dna/doc/guides/for-ai/ai-dev-guide.md +7 -2
- package/dna/dot-claude/skills/cleanup/SKILL.md +22 -4
- package/dna/dot-claude/skills/ticket/SKILL.md +5 -1
- package/package.json +4 -4
- package/dna/scripts/delete-feature-branch.js +0 -97
- package/dna/scripts/functions/colors.js +0 -27
- package/dna/scripts/functions/run-command.js +0 -22
package/dna/_generated.json
CHANGED
|
@@ -5,23 +5,23 @@
|
|
|
5
5
|
"name": "base",
|
|
6
6
|
"package": "helix",
|
|
7
7
|
"ecosystem": null,
|
|
8
|
-
"resolvedVersion": "1.
|
|
8
|
+
"resolvedVersion": "1.8.0",
|
|
9
9
|
"via": null,
|
|
10
10
|
"hash": "0x6883da335b415f9d"
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"name": "dna-install",
|
|
14
|
-
"package": "
|
|
15
|
-
"ecosystem": "
|
|
16
|
-
"resolvedVersion": "0.1.
|
|
14
|
+
"package": "@ggdna/dna-install",
|
|
15
|
+
"ecosystem": "node",
|
|
16
|
+
"resolvedVersion": "0.1.1",
|
|
17
17
|
"via": null,
|
|
18
18
|
"hash": "0xbe88eb4256745ee1"
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"name": "dna-index",
|
|
22
|
-
"package": "
|
|
23
|
-
"ecosystem": "
|
|
24
|
-
"resolvedVersion": "0.1.
|
|
22
|
+
"package": "@ggdna/dna-index",
|
|
23
|
+
"ecosystem": "node",
|
|
24
|
+
"resolvedVersion": "0.1.1",
|
|
25
25
|
"via": null,
|
|
26
26
|
"hash": "0x1d92b0add37a1ac7"
|
|
27
27
|
},
|
|
@@ -31,19 +31,19 @@
|
|
|
31
31
|
"ecosystem": null,
|
|
32
32
|
"resolvedVersion": null,
|
|
33
33
|
"via": null,
|
|
34
|
-
"hash": "
|
|
34
|
+
"hash": "0x5b707abead2f6ae7"
|
|
35
35
|
}
|
|
36
36
|
],
|
|
37
37
|
"claude": {
|
|
38
38
|
"claudeMdInclude": null,
|
|
39
39
|
"claudeMdFromDna": true
|
|
40
40
|
},
|
|
41
|
-
"baseVersion": "1.
|
|
41
|
+
"baseVersion": "1.8.0",
|
|
42
42
|
"baseHash": "0x6883da335b415f9d",
|
|
43
43
|
"instances": [
|
|
44
44
|
{
|
|
45
45
|
"path": ".claude/skills/cleanup/SKILL.md",
|
|
46
|
-
"hash": "
|
|
46
|
+
"hash": "0xeaa18dbc86a24731"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"path": ".claude/skills/commit/SKILL.md",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
69
|
"path": ".claude/skills/ticket/SKILL.md",
|
|
70
|
-
"hash": "
|
|
70
|
+
"hash": "0x1c257bb5b8471026"
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
"path": ".github/workflows/quick_check.yaml",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
"path": "doc/guides/for-ai/ai-dev-guide.md",
|
|
86
|
-
"hash": "
|
|
86
|
+
"hash": "0x5e0118ec27bc8d6a"
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
"path": "doc/guides/index-guide.md",
|
|
@@ -140,18 +140,6 @@
|
|
|
140
140
|
{
|
|
141
141
|
"path": "doc/templates/index-template.jsonc",
|
|
142
142
|
"hash": "0x16c3a8d50c72ed6d"
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
"path": "scripts/delete-feature-branch.js",
|
|
146
|
-
"hash": "0x219ac0a3635ee644"
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
"path": "scripts/functions/colors.js",
|
|
150
|
-
"hash": "0xdfd97f3804665811"
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
"path": "scripts/functions/run-command.js",
|
|
154
|
-
"hash": "0x085b390fcb9256ab"
|
|
155
143
|
}
|
|
156
144
|
]
|
|
157
145
|
}
|
|
@@ -46,6 +46,10 @@ other repo:
|
|
|
46
46
|
gg do add pm_repo
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
If the PM repo has `doc/guides/pm-repo-guide.md`, read it: it describes how
|
|
50
|
+
the PM repo is structured and how planning works there. If the file does not
|
|
51
|
+
exist, follow the guides the PM repo has.
|
|
52
|
+
|
|
49
53
|
## Add git repositories
|
|
50
54
|
|
|
51
55
|
Look at the `index.jsonc` of each repo in .ocean and decide which repos need to
|
|
@@ -76,8 +80,9 @@ gg do code
|
|
|
76
80
|
|
|
77
81
|
Ask the user whether the ticket is planned before it is implemented.
|
|
78
82
|
|
|
79
|
-
If yes, write the plan into the PM repo, following
|
|
80
|
-
|
|
83
|
+
If yes, write the plan into the PM repo, following its
|
|
84
|
+
`doc/guides/pm-repo-guide.md` if present, otherwise its other guides: the
|
|
85
|
+
goal, the affected repos, the rough steps and open questions. Let the user
|
|
81
86
|
review the plan and revise it until they confirm it.
|
|
82
87
|
|
|
83
88
|
## Implement (optional)
|
|
@@ -22,14 +22,32 @@ Stop and report if a repo still holds uncommitted or unmerged work.
|
|
|
22
22
|
|
|
23
23
|
## 2. Delete the feature branches
|
|
24
24
|
|
|
25
|
-
In every repo that still sits on its feature branch:
|
|
25
|
+
In every repo that still sits on its feature branch (never on `main`):
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
|
|
28
|
+
git rev-parse --abbrev-ref @{u} >/dev/null && git rev-list --count @{u}..HEAD
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
Stop and ask the user to push first if that count is not `0`.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git fetch
|
|
35
|
+
git checkout main
|
|
36
|
+
git pull origin main
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
A plain `git branch -d` refuses a squash-merged branch even though it is
|
|
40
|
+
fully in `main` — test it with a merge instead:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git merge --no-commit --no-ff <branch>
|
|
44
|
+
git status --porcelain
|
|
45
|
+
git merge --abort
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Empty status → the branch is fully in `main`: `git branch -d <branch>`.
|
|
49
|
+
- Non-empty status → not merged yet: `git checkout <branch>` and tell the
|
|
50
|
+
user to (create and) merge a pull request first.
|
|
33
51
|
|
|
34
52
|
## 3. Remove the ticket folder
|
|
35
53
|
|
|
@@ -34,6 +34,9 @@ After the confirmation, add it **before** any other repo:
|
|
|
34
34
|
gg do add pm_repo
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
Read `doc/guides/pm-repo-guide.md` of the PM repo if it exists: it says how
|
|
38
|
+
the PM repo is structured and how planning works there.
|
|
39
|
+
|
|
37
40
|
## 4. Choose the code repos
|
|
38
41
|
|
|
39
42
|
Read the `index.md` of the candidate repos in `.ocean`. Tell the user which
|
|
@@ -56,7 +59,8 @@ gg do code
|
|
|
56
59
|
## 6. Plan or implement
|
|
57
60
|
|
|
58
61
|
Ask the user whether the ticket is planned first. If yes, write the plan into
|
|
59
|
-
the PM repo
|
|
62
|
+
the PM repo as its `pm-repo-guide.md` describes (or as its other guides do)
|
|
63
|
+
and let the user confirm it. Then ask whether the ticket is
|
|
60
64
|
implemented now or only planned — in the latter case the ticket ends with
|
|
61
65
|
the PM repo alone.
|
|
62
66
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggdna/dna-gg",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "DNA layer: gg CLI workflow guides, repo setup scripts and CI check",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dna",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@ggdna/dna-index": "^0.1.
|
|
32
|
-
"@ggdna/dna-install": "^0.1.
|
|
31
|
+
"@ggdna/dna-index": "^0.1.1",
|
|
32
|
+
"@ggdna/dna-install": "^0.1.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/node": "^26.
|
|
35
|
+
"@types/node": "^26.6.1",
|
|
36
36
|
"prettier": "^3.9.6"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) dnaCopyrightHolder
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by terms that can be
|
|
6
|
-
* found in the LICENSE file in the root of this package.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { gray, green, red, yellow } from './functions/colors.js';
|
|
10
|
-
import { runCommand } from './functions/run-command.js';
|
|
11
|
-
|
|
12
|
-
// Check for uncommitted changes
|
|
13
|
-
function hasUncommittedChanges() {
|
|
14
|
-
console.log(gray('Check for uncommitted changes'));
|
|
15
|
-
const status = runCommand('git status --porcelain');
|
|
16
|
-
return status.length > 0;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Check for unpushed commits
|
|
20
|
-
function hasUnpushedCommits(branch) {
|
|
21
|
-
try {
|
|
22
|
-
console.log(gray('Check for unpushed commits'));
|
|
23
|
-
runCommand(`git rev-parse --abbrev-ref ${branch}@{u}`);
|
|
24
|
-
const ahead = runCommand(`git rev-list --count ${branch}@{u}..${branch}`);
|
|
25
|
-
return parseInt(ahead, 10) > 0;
|
|
26
|
-
} catch {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Try a test merge into main and check if it introduces changes
|
|
32
|
-
function isBranchEffectivelyMerged(featureBranch) {
|
|
33
|
-
console.log(gray('Check if feature was fully merged'));
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
runCommand(`git merge --no-commit --no-ff ${featureBranch}`);
|
|
37
|
-
const changed = hasUncommittedChanges();
|
|
38
|
-
runCommand('git merge --abort');
|
|
39
|
-
return !changed;
|
|
40
|
-
} catch {
|
|
41
|
-
try {
|
|
42
|
-
runCommand('git merge --abort');
|
|
43
|
-
} catch {}
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
console.log(gray('Get current branch name'));
|
|
50
|
-
const currentBranch = runCommand('git rev-parse --abbrev-ref HEAD');
|
|
51
|
-
|
|
52
|
-
if (currentBranch === 'main') {
|
|
53
|
-
console.log(yellow('Please call this script from a feature branch.'));
|
|
54
|
-
process.exit(0);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (hasUncommittedChanges()) {
|
|
58
|
-
console.error(red('❌ You have uncommitted changes.'));
|
|
59
|
-
console.error(
|
|
60
|
-
yellow('Please commit or stash your changes before continuing.'),
|
|
61
|
-
);
|
|
62
|
-
process.exit(1);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (hasUnpushedCommits(currentBranch)) {
|
|
66
|
-
console.error(red('❌ You have unpushed commits.'));
|
|
67
|
-
console.error(yellow('Please push your branch before continuing.'));
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
console.log(gray(`Fetching and pulling 'main'...`));
|
|
72
|
-
runCommand('git fetch');
|
|
73
|
-
runCommand('git checkout main');
|
|
74
|
-
runCommand('git pull origin main');
|
|
75
|
-
|
|
76
|
-
const isMerged = isBranchEffectivelyMerged(currentBranch);
|
|
77
|
-
|
|
78
|
-
if (isMerged) {
|
|
79
|
-
runCommand(`git branch -d ${currentBranch}`);
|
|
80
|
-
console.log(green(`✅ Branch '${currentBranch}' has been deleted.`));
|
|
81
|
-
} else {
|
|
82
|
-
console.error(
|
|
83
|
-
red(`❌ Branch '${currentBranch}' is not merged into 'main'.`),
|
|
84
|
-
);
|
|
85
|
-
console.log(
|
|
86
|
-
yellow(`Please (create and) merge a pull request and try again.`),
|
|
87
|
-
);
|
|
88
|
-
runCommand(`git checkout ${currentBranch}`);
|
|
89
|
-
console.log(gray(`Switched back to '${currentBranch}'.`));
|
|
90
|
-
}
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error(red(`Error: ${error.message}`));
|
|
93
|
-
try {
|
|
94
|
-
runCommand('git merge --abort');
|
|
95
|
-
} catch {}
|
|
96
|
-
process.exit(1);
|
|
97
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) dnaCopyrightHolder
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by terms that can be
|
|
6
|
-
* found in the LICENSE file in the root of this package.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export const red = (str) => `\x1b[31m${str}\x1b[0m`;
|
|
10
|
-
export const green = (str) => `\x1b[32m${str}\x1b[0m`;
|
|
11
|
-
export const yellow = (str) => `\x1b[33m${str}\x1b[0m`;
|
|
12
|
-
export const blue = (str) => `\x1b[34m${str}\x1b[0m`;
|
|
13
|
-
export const magenta = (str) => `\x1b[35m${str}\x1b[0m`;
|
|
14
|
-
export const cyan = (str) => `\x1b[36m${str}\x1b[0m`;
|
|
15
|
-
export const white = (str) => `\x1b[37m${str}\x1b[0m`;
|
|
16
|
-
export const black = (str) => `\x1b[30m${str}\x1b[0m`;
|
|
17
|
-
export const bgRed = (str) => `\x1b[41m${str}\x1b[0m`;
|
|
18
|
-
export const bgGreen = (str) => `\x1b[42m${str}\x1b[0m`;
|
|
19
|
-
export const bgYellow = (str) => `\x1b[43m${str}\x1b[0m`;
|
|
20
|
-
export const bgBlue = (str) => `\x1b[44m${str}\x1b[0m`;
|
|
21
|
-
export const bgMagenta = (str) => `\x1b[45m${str}\x1b[0m`;
|
|
22
|
-
export const bgCyan = (str) => `\x1b[46m${str}\x1b[0m`;
|
|
23
|
-
export const bgWhite = (str) => `\x1b[47m${str}\x1b[0m`;
|
|
24
|
-
export const bgBlack = (str) => `\x1b[40m${str}\x1b[0m`;
|
|
25
|
-
export const gray = (str) => `\x1b[90m${str}\x1b[0m`;
|
|
26
|
-
export const lightGray = (str) => `\x1b[37m${str}\x1b[0m`;
|
|
27
|
-
export const reset = (str) => `\x1b[0m${str}\x1b[0m`;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) dnaCopyrightHolder
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by terms that can be
|
|
6
|
-
* found in the LICENSE file in the root of this package.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { execSync } from 'child_process';
|
|
10
|
-
import { gray } from './colors.js';
|
|
11
|
-
|
|
12
|
-
// Execute a shell command and return trimmed output
|
|
13
|
-
// Execute a shell command and return trimmed output
|
|
14
|
-
export function runCommand(command, silent = true, logCommand = true) {
|
|
15
|
-
if (logCommand) {
|
|
16
|
-
console.log(gray(`${command}`));
|
|
17
|
-
}
|
|
18
|
-
return execSync(command, {
|
|
19
|
-
encoding: 'utf-8',
|
|
20
|
-
stdio: silent ? ['pipe', 'pipe', 'pipe'] : undefined,
|
|
21
|
-
}).trim();
|
|
22
|
-
}
|