@produck/agent-toolkit 0.6.0 → 0.8.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 +74 -43
- package/bin/agent-toolkit.mjs +26 -33
- package/bin/build-publish-assets.mjs +54 -5
- package/bin/command/enforce-node-baseline/help.txt +12 -10
- package/bin/command/enforce-node-baseline/index.mjs +23 -15
- package/bin/command/main/help.txt +6 -5
- package/bin/command/preflight/help.txt +1 -1
- package/bin/command/preflight/index.mjs +1 -1
- package/bin/command/{sync-coverage-script → sync-coverage}/help.txt +2 -1
- package/bin/command/{sync-coverage-script → sync-coverage}/index.mjs +116 -19
- package/bin/command/sync-editorconfig/index.mjs +10 -153
- package/bin/command/{sync-prettier-config → sync-format}/help.txt +4 -2
- package/bin/command/sync-format/index.mjs +222 -0
- package/bin/command/{sync-workspace-config → sync-git}/help.txt +10 -6
- package/bin/command/sync-git/index.mjs +424 -0
- package/bin/command/sync-install/help.txt +14 -0
- package/bin/command/{sync-prettier-config → sync-install}/index.mjs +26 -50
- package/bin/command/sync-instructions/index.mjs +2 -22
- package/bin/command/{sync-eslint-config → sync-lint}/help.txt +2 -2
- package/bin/command/{sync-eslint-config → sync-lint}/index.mjs +3 -4
- package/bin/command/sync-publish/help.txt +18 -0
- package/bin/command/sync-publish/index.mjs +157 -0
- package/bin/command/validate-commit-msg/index.mjs +30 -2
- package/package.json +3 -5
- package/publish-assets/gitattributes +5 -0
- package/publish-assets/gitignore +137 -0
- package/publish-assets/instructions/produck/00-produck-base.instructions.md +44 -58
- package/publish-assets/instructions/produck/10-produck-node.instructions.md +59 -82
- package/publish-assets/instructions/produck/12-produck-test.instructions.md +94 -0
- package/publish-assets/instructions/produck/15-produck-workspace.instructions.md +17 -50
- package/publish-assets/instructions/produck/20-produck-commit.instructions.md +2 -2
- package/publish-assets/instructions/produck/tooling-version-baseline.json +14 -2
- package/publish-assets/prettierignore +2 -0
- package/bin/command/sync-husky-hooks/help.txt +0 -14
- package/bin/command/sync-husky-hooks/index.mjs +0 -89
- package/bin/command/sync-workspace-config/index.mjs +0 -290
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
import { getSingle, hasFlag } from '../shared/args.mjs';
|
|
6
|
+
import { printTextResource } from '../shared/text-resource.mjs';
|
|
7
|
+
|
|
8
|
+
const COMMAND_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const HELP_FILE = path.resolve(COMMAND_DIR, 'help.txt');
|
|
10
|
+
const LERNA_CONFIG_FILE = 'lerna.json';
|
|
11
|
+
|
|
12
|
+
const REQUIRED_PUBLISH_CHECK_SCRIPT_KEY = 'produck:publish:check';
|
|
13
|
+
const REQUIRED_PUBLISH_CHECK_SCRIPT_VALUE =
|
|
14
|
+
'npm run produck:install && npm run produck:format && npm run produck:lint && npm run produck:coverage';
|
|
15
|
+
const USER_PUBLISH_SCRIPT_KEY = 'publish';
|
|
16
|
+
const REQUIRED_PUBLISH_SCRIPT_KEY = 'produck:publish';
|
|
17
|
+
const REQUIRED_PUBLISH_SCRIPT_FALLBACK_VALUE = 'npm run produck:publish:check && lerna publish';
|
|
18
|
+
|
|
19
|
+
const REQUIRED_LERNA_DEFAULT_CONFIG = `${JSON.stringify(
|
|
20
|
+
{
|
|
21
|
+
$schema: 'node_modules/lerna/schemas/lerna-schema.json',
|
|
22
|
+
version: 'independent',
|
|
23
|
+
},
|
|
24
|
+
null,
|
|
25
|
+
2,
|
|
26
|
+
)}\n`;
|
|
27
|
+
|
|
28
|
+
export function printSyncPublishHelp() {
|
|
29
|
+
printTextResource(HELP_FILE);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function parseJsonFile(filePath, label) {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
35
|
+
} catch {
|
|
36
|
+
console.error(`${label} is not valid JSON: ${filePath}`);
|
|
37
|
+
process.exit(2);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildRequiredPublishScriptValue(hasUserPublishScript) {
|
|
42
|
+
if (hasUserPublishScript) {
|
|
43
|
+
return 'npm run produck:publish:check && npm run publish --';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return REQUIRED_PUBLISH_SCRIPT_FALLBACK_VALUE;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function runSyncPublish(options) {
|
|
50
|
+
const cwd = path.resolve(getSingle(options, '--cwd', process.cwd()));
|
|
51
|
+
const check = hasFlag(options, '--check');
|
|
52
|
+
const dryRun = hasFlag(options, '--dry-run') && !check;
|
|
53
|
+
const jsonFile = getSingle(options, '--json', '');
|
|
54
|
+
const mode = check ? 'check' : dryRun ? 'dry-run' : 'sync';
|
|
55
|
+
|
|
56
|
+
if (!fs.existsSync(cwd)) {
|
|
57
|
+
console.error(`CWD does not exist: ${cwd}`);
|
|
58
|
+
process.exit(2);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const lernaConfigPath = path.resolve(cwd, LERNA_CONFIG_FILE);
|
|
62
|
+
const lernaExistedBefore = fs.existsSync(lernaConfigPath);
|
|
63
|
+
let lernaDefaultCreated = false;
|
|
64
|
+
|
|
65
|
+
if (!lernaExistedBefore) {
|
|
66
|
+
if (mode === 'sync') {
|
|
67
|
+
fs.writeFileSync(lernaConfigPath, REQUIRED_LERNA_DEFAULT_CONFIG, 'utf8');
|
|
68
|
+
lernaDefaultCreated = true;
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
const lernaConfig = parseJsonFile(lernaConfigPath, 'lerna.json');
|
|
72
|
+
|
|
73
|
+
if (typeof lernaConfig.version !== 'string') {
|
|
74
|
+
console.error(`lerna.json must have a "version" field: ${lernaConfigPath}`);
|
|
75
|
+
process.exit(2);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const rootPackageJsonPath = path.resolve(cwd, 'package.json');
|
|
80
|
+
if (!fs.existsSync(rootPackageJsonPath)) {
|
|
81
|
+
console.error(`Root package.json does not exist: ${rootPackageJsonPath}`);
|
|
82
|
+
process.exit(2);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const pkg = parseJsonFile(rootPackageJsonPath, 'Root package.json');
|
|
86
|
+
const scripts =
|
|
87
|
+
pkg.scripts && typeof pkg.scripts === 'object' && !Array.isArray(pkg.scripts)
|
|
88
|
+
? { ...pkg.scripts }
|
|
89
|
+
: {};
|
|
90
|
+
const hasUserPublishScript =
|
|
91
|
+
typeof scripts[USER_PUBLISH_SCRIPT_KEY] === 'string' &&
|
|
92
|
+
scripts[USER_PUBLISH_SCRIPT_KEY].trim() !== '';
|
|
93
|
+
const requiredPublishScriptValue = buildRequiredPublishScriptValue(hasUserPublishScript);
|
|
94
|
+
|
|
95
|
+
const previousPublishCheck =
|
|
96
|
+
typeof scripts[REQUIRED_PUBLISH_CHECK_SCRIPT_KEY] === 'string'
|
|
97
|
+
? scripts[REQUIRED_PUBLISH_CHECK_SCRIPT_KEY]
|
|
98
|
+
: null;
|
|
99
|
+
const previousPublish =
|
|
100
|
+
typeof scripts[REQUIRED_PUBLISH_SCRIPT_KEY] === 'string'
|
|
101
|
+
? scripts[REQUIRED_PUBLISH_SCRIPT_KEY]
|
|
102
|
+
: null;
|
|
103
|
+
|
|
104
|
+
const matchesRequiredPublishCheck = previousPublishCheck === REQUIRED_PUBLISH_CHECK_SCRIPT_VALUE;
|
|
105
|
+
const matchesRequiredPublish = previousPublish === requiredPublishScriptValue;
|
|
106
|
+
const lernaRequiresCreation = !lernaExistedBefore && !lernaDefaultCreated;
|
|
107
|
+
const requiresUpdate =
|
|
108
|
+
!matchesRequiredPublishCheck || !matchesRequiredPublish || lernaRequiresCreation;
|
|
109
|
+
|
|
110
|
+
if (mode === 'sync' && (!matchesRequiredPublishCheck || !matchesRequiredPublish)) {
|
|
111
|
+
scripts[REQUIRED_PUBLISH_CHECK_SCRIPT_KEY] = REQUIRED_PUBLISH_CHECK_SCRIPT_VALUE;
|
|
112
|
+
scripts[REQUIRED_PUBLISH_SCRIPT_KEY] = requiredPublishScriptValue;
|
|
113
|
+
pkg.scripts = scripts;
|
|
114
|
+
fs.writeFileSync(rootPackageJsonPath, `${JSON.stringify(pkg, null, 2)}\n`, 'utf8');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const report = {
|
|
118
|
+
cwd,
|
|
119
|
+
mode,
|
|
120
|
+
ok: true,
|
|
121
|
+
lernaConfigPath,
|
|
122
|
+
rootPackageJsonPath,
|
|
123
|
+
required: {
|
|
124
|
+
publishCheckScriptKey: REQUIRED_PUBLISH_CHECK_SCRIPT_KEY,
|
|
125
|
+
publishCheckScriptValue: REQUIRED_PUBLISH_CHECK_SCRIPT_VALUE,
|
|
126
|
+
publishScriptKey: REQUIRED_PUBLISH_SCRIPT_KEY,
|
|
127
|
+
publishScriptValue: requiredPublishScriptValue,
|
|
128
|
+
},
|
|
129
|
+
status: {
|
|
130
|
+
hasUserPublishScript,
|
|
131
|
+
lernaExistedBefore,
|
|
132
|
+
lernaDefaultCreated,
|
|
133
|
+
matchesRequiredPublishCheckBefore: matchesRequiredPublishCheck,
|
|
134
|
+
matchesRequiredPublishCheckAfter:
|
|
135
|
+
!matchesRequiredPublishCheck && mode === 'sync' ? true : matchesRequiredPublishCheck,
|
|
136
|
+
matchesRequiredPublishBefore: matchesRequiredPublish,
|
|
137
|
+
matchesRequiredPublishAfter:
|
|
138
|
+
!matchesRequiredPublish && mode === 'sync' ? true : matchesRequiredPublish,
|
|
139
|
+
updated: requiresUpdate && mode === 'sync',
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
if (mode === 'check' && requiresUpdate) {
|
|
144
|
+
report.ok = false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (jsonFile) {
|
|
148
|
+
const outPath = path.resolve(cwd, jsonFile);
|
|
149
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
150
|
+
fs.writeFileSync(outPath, `${JSON.stringify(report, null, 2)}\n`, 'utf8');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
154
|
+
if (!report.ok) {
|
|
155
|
+
process.exit(2);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -13,6 +13,7 @@ const HELP_FILE = path.resolve(COMMAND_DIR, 'help.txt');
|
|
|
13
13
|
const ROOT_PACKAGE_FILE = path.resolve(COMMAND_DIR, '../../../../../package.json');
|
|
14
14
|
const WORKSPACE_SCOPE = 'workspace';
|
|
15
15
|
const WILDCARD_SCOPE = '*';
|
|
16
|
+
const DEFAULT_COMMENT_CHAR = '#';
|
|
16
17
|
|
|
17
18
|
export function printValidateCommitMsgHelp() {
|
|
18
19
|
printTextResource(HELP_FILE);
|
|
@@ -170,6 +171,33 @@ function validateSectionFormat(lines, allowedSectionScopes = null) {
|
|
|
170
171
|
return errors;
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
function getCommentCharFromConfig() {
|
|
175
|
+
const configured = String(process.env.GIT_COMMENT_CHAR || '').trim();
|
|
176
|
+
return configured || DEFAULT_COMMENT_CHAR;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function normalizeCommitMessageLines(raw, commentChar = DEFAULT_COMMENT_CHAR) {
|
|
180
|
+
const normalizedRaw = raw.replace(/\r\n/g, '\n');
|
|
181
|
+
const rawLines = normalizedRaw.split('\n');
|
|
182
|
+
const lines = [];
|
|
183
|
+
|
|
184
|
+
for (const line of rawLines) {
|
|
185
|
+
if (commentChar && line.startsWith(commentChar)) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
lines.push(line);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
while (lines.length > 0 && lines[0].trim() === '') {
|
|
192
|
+
lines.shift();
|
|
193
|
+
}
|
|
194
|
+
while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
|
|
195
|
+
lines.pop();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return lines;
|
|
199
|
+
}
|
|
200
|
+
|
|
173
201
|
export function runValidateCommitMsg(options) {
|
|
174
202
|
const file = getSingle(options, '--file', '');
|
|
175
203
|
if (!file) {
|
|
@@ -183,8 +211,8 @@ export function runValidateCommitMsg(options) {
|
|
|
183
211
|
process.exit(2);
|
|
184
212
|
}
|
|
185
213
|
|
|
186
|
-
const raw = fs.readFileSync(filePath, 'utf8')
|
|
187
|
-
const lines =
|
|
214
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
215
|
+
const lines = normalizeCommitMessageLines(raw, getCommentCharFromConfig());
|
|
188
216
|
|
|
189
217
|
if (lines.length === 0 || (lines.length === 1 && lines[0].trim() === '')) {
|
|
190
218
|
console.error('Commit message is empty');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@produck/agent-toolkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Central CLI toolkit for organization AI execution workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -13,9 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"prepack": "node ./bin/build-publish-assets.mjs",
|
|
16
|
-
"test": "node
|
|
17
|
-
"verify": "node ./bin/agent-toolkit.mjs --help && node ./bin/agent-toolkit.mjs preflight --cwd . --require package.json",
|
|
18
|
-
"pack:check": "npm pack --dry-run",
|
|
16
|
+
"test": "node test/index.mjs",
|
|
19
17
|
"produck:coverage": "c8 --reporter=lcov --reporter=html --reporter=text-summary npm test"
|
|
20
18
|
},
|
|
21
19
|
"files": [
|
|
@@ -32,5 +30,5 @@
|
|
|
32
30
|
"devDependencies": {
|
|
33
31
|
"c8": "11.0.0"
|
|
34
32
|
},
|
|
35
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "a9e160249f664b28fa5971246e61d9e641c16586"
|
|
36
34
|
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
lerna-debug.log*
|
|
8
|
+
.pnpm-debug.log*
|
|
9
|
+
|
|
10
|
+
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
11
|
+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
12
|
+
|
|
13
|
+
# Runtime data
|
|
14
|
+
pids
|
|
15
|
+
*.pid
|
|
16
|
+
*.seed
|
|
17
|
+
*.pid.lock
|
|
18
|
+
|
|
19
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
20
|
+
lib-cov
|
|
21
|
+
|
|
22
|
+
# Coverage directory used by tools like istanbul
|
|
23
|
+
coverage
|
|
24
|
+
*.lcov
|
|
25
|
+
|
|
26
|
+
# nyc test coverage
|
|
27
|
+
.nyc_output
|
|
28
|
+
|
|
29
|
+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
30
|
+
.grunt
|
|
31
|
+
|
|
32
|
+
# Bower dependency directory (https://bower.io/)
|
|
33
|
+
bower_components
|
|
34
|
+
|
|
35
|
+
# node-waf configuration
|
|
36
|
+
.lock-wscript
|
|
37
|
+
|
|
38
|
+
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
39
|
+
build/Release
|
|
40
|
+
|
|
41
|
+
# Dependency directories
|
|
42
|
+
node_modules/
|
|
43
|
+
jspm_packages/
|
|
44
|
+
|
|
45
|
+
# Snowpack dependency directory (https://snowpack.dev/)
|
|
46
|
+
web_modules/
|
|
47
|
+
|
|
48
|
+
# TypeScript cache
|
|
49
|
+
*.tsbuildinfo
|
|
50
|
+
|
|
51
|
+
# Optional npm cache directory
|
|
52
|
+
.npm
|
|
53
|
+
|
|
54
|
+
# Optional eslint cache
|
|
55
|
+
.eslintcache
|
|
56
|
+
|
|
57
|
+
# Optional stylelint cache
|
|
58
|
+
.stylelintcache
|
|
59
|
+
|
|
60
|
+
# Microbundle cache
|
|
61
|
+
.rpt2_cache/
|
|
62
|
+
.rts2_cache_cjs/
|
|
63
|
+
.rts2_cache_es/
|
|
64
|
+
.rts2_cache_umd/
|
|
65
|
+
|
|
66
|
+
# Optional REPL history
|
|
67
|
+
.node_repl_history
|
|
68
|
+
|
|
69
|
+
# Output of 'npm pack'
|
|
70
|
+
*.tgz
|
|
71
|
+
|
|
72
|
+
# Yarn Integrity file
|
|
73
|
+
.yarn-integrity
|
|
74
|
+
|
|
75
|
+
# dotenv environment variable files
|
|
76
|
+
.env
|
|
77
|
+
.env.development.local
|
|
78
|
+
.env.test.local
|
|
79
|
+
.env.production.local
|
|
80
|
+
.env.local
|
|
81
|
+
|
|
82
|
+
# parcel-bundler cache (https://parceljs.org/)
|
|
83
|
+
.cache
|
|
84
|
+
.parcel-cache
|
|
85
|
+
|
|
86
|
+
# Next.js build output
|
|
87
|
+
.next
|
|
88
|
+
out
|
|
89
|
+
|
|
90
|
+
# Nuxt.js build / generate output
|
|
91
|
+
.nuxt
|
|
92
|
+
dist
|
|
93
|
+
|
|
94
|
+
# Gatsby files
|
|
95
|
+
.cache/
|
|
96
|
+
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
97
|
+
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
98
|
+
# public
|
|
99
|
+
|
|
100
|
+
# vuepress build output
|
|
101
|
+
.vuepress/dist
|
|
102
|
+
|
|
103
|
+
# vuepress v2.x temp and cache directory
|
|
104
|
+
.temp
|
|
105
|
+
.cache
|
|
106
|
+
|
|
107
|
+
# Docusaurus cache and generated files
|
|
108
|
+
.docusaurus
|
|
109
|
+
|
|
110
|
+
# Serverless directories
|
|
111
|
+
.serverless/
|
|
112
|
+
|
|
113
|
+
# FuseBox cache
|
|
114
|
+
.fusebox/
|
|
115
|
+
|
|
116
|
+
# DynamoDB Local files
|
|
117
|
+
.dynamodb/
|
|
118
|
+
|
|
119
|
+
# TernJS port file
|
|
120
|
+
.tern-port
|
|
121
|
+
|
|
122
|
+
# Stores VSCode versions used for testing VSCode extensions
|
|
123
|
+
.vscode-test
|
|
124
|
+
|
|
125
|
+
# yarn v2
|
|
126
|
+
.yarn/cache
|
|
127
|
+
.yarn/unplugged
|
|
128
|
+
.yarn/build-state.yml
|
|
129
|
+
.yarn/install-state.gz
|
|
130
|
+
.pnp.*
|
|
131
|
+
|
|
132
|
+
# Vscode
|
|
133
|
+
.vscode
|
|
134
|
+
|
|
135
|
+
# Specific ignored / generated.
|
|
136
|
+
*.ign*
|
|
137
|
+
*.gen*
|
|
@@ -18,20 +18,26 @@ in the `produck` organization.
|
|
|
18
18
|
|
|
19
19
|
## Instruction source split
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
`.github/distribution/produck/*.instructions.md`
|
|
26
|
-
|
|
27
|
-
`.github/instructions/produck/*.instructions.md`
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
Path semantics differ between the upstream policy repository and downstream
|
|
22
|
+
repositories:
|
|
23
|
+
|
|
24
|
+
- Upstream policy repository (this `produck/.github` repo):
|
|
25
|
+
- `.github/distribution/produck/*.instructions.md` — canonical baseline,
|
|
26
|
+
distributed to downstream repositories.
|
|
27
|
+
- `.github/instructions/produck/*.instructions.md` — reserved for
|
|
28
|
+
organization-only governance that should NOT be distributed.
|
|
29
|
+
- Downstream repositories (consumers of the baseline):
|
|
30
|
+
- `.github/instructions/produck/*.instructions.md` — synced copy of the
|
|
31
|
+
upstream canonical baseline (managed by `agent-toolkit sync-instructions`).
|
|
32
|
+
- `.github/copilot-instructions.md` — repository-specific exceptions and
|
|
33
|
+
stricter local constraints.
|
|
34
|
+
|
|
35
|
+
Editing rule (upstream only):
|
|
30
36
|
|
|
31
37
|
- Update downstream baseline rules directly in
|
|
32
38
|
`.github/distribution/produck/*.instructions.md`.
|
|
33
|
-
-
|
|
34
|
-
`.github/instructions/produck
|
|
39
|
+
- Add organization-only governance under
|
|
40
|
+
`.github/instructions/produck/` only when it must not be distributed.
|
|
35
41
|
|
|
36
42
|
## Default expectations
|
|
37
43
|
|
|
@@ -134,27 +140,15 @@ max_line_length = 80
|
|
|
134
140
|
|
|
135
141
|
## Commit and PR conventions
|
|
136
142
|
|
|
137
|
-
- Commit
|
|
138
|
-
- Every non-empty commit message line must start with `[TAG]`.
|
|
139
|
-
- Empty lines are not allowed between commit message lines.
|
|
140
|
-
- Do not use untagged bullet lines in commit message body.
|
|
141
|
-
- If details are needed, use additional tagged lines.
|
|
142
|
-
- Do not keep summary as an untagged standalone line.
|
|
143
|
-
- Recommended local validation:
|
|
144
|
-
`npm exec -- agent-toolkit validate-commit-msg --file <message-file>`.
|
|
145
|
-
- Commit precheck policy follows
|
|
143
|
+
- Commit and commit-precheck rules are defined in
|
|
146
144
|
`.github/distribution/produck/20-produck-commit.instructions.md`.
|
|
147
|
-
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- PR title format is repository-defined; no organization-level title format
|
|
155
|
-
restriction
|
|
156
|
-
- In PR descriptions, summarize what changed, why it changed, how it was
|
|
157
|
-
validated, and any known risks or follow-up work
|
|
145
|
+
- Use commit message validator before commit and amend:
|
|
146
|
+
`npm exec -- agent-toolkit validate-commit-msg --file <message-file>`.
|
|
147
|
+
- Do not redefine commit tag, target, or monorepo section rules outside
|
|
148
|
+
`20-produck-commit.instructions.md`.
|
|
149
|
+
- PR title format is repository-defined (no organization-level restriction).
|
|
150
|
+
- PR descriptions should summarize what changed, why, validation, and known
|
|
151
|
+
risks or follow-up work.
|
|
158
152
|
|
|
159
153
|
## Terminal long-output protocol
|
|
160
154
|
|
|
@@ -255,7 +249,8 @@ locally in downstream repositories at a fixed version managed by the
|
|
|
255
249
|
organization baseline.
|
|
256
250
|
|
|
257
251
|
- Local install and pinned version are deployed by
|
|
258
|
-
`agent-toolkit sync-
|
|
252
|
+
`agent-toolkit sync-git` (root devDependency pinning) and
|
|
253
|
+
`agent-toolkit sync-install` (root install script baseline).
|
|
259
254
|
- Invocation uses the locally installed copy:
|
|
260
255
|
`npm exec -- <bin> ...`.
|
|
261
256
|
- Do not use `npm exec --package=<pkg>@latest` for routine invocations.
|
|
@@ -294,31 +289,21 @@ Rollback runbook (minimum):
|
|
|
294
289
|
|
|
295
290
|
### Recommended organization AI instruction template
|
|
296
291
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
- Every non-empty commit message line must start with `[TAG]`.
|
|
313
|
-
- Empty lines are not allowed between commit message lines.
|
|
314
|
-
- Use only allowed tags: `[INIT]`, `[ADD]`, `[REMOVE]`, `[FIX]`,
|
|
315
|
-
`[REFACTOR]`, `[UPGRADE]`.
|
|
316
|
-
- Optional target syntax is `[TAG] <target>: <summary>` with target in:
|
|
317
|
-
`docs`, `test`, `ci`, `deps`, `api`, `schema`, `infra`, `fmt`.
|
|
318
|
-
- Do not assume scripts from organization `.github` repository exist in target
|
|
319
|
-
repositories.
|
|
320
|
-
- If a repository provides stricter rules, repository rules override
|
|
321
|
-
organization defaults.
|
|
292
|
+
When authoring organization-level AI instruction text (for example in
|
|
293
|
+
organization settings), reference the canonical sources in this baseline
|
|
294
|
+
instead of duplicating their content:
|
|
295
|
+
|
|
296
|
+
- Language and default expectations: see `Default expectations` and
|
|
297
|
+
`Language conventions` sections above.
|
|
298
|
+
- Node-first execution policy: see `Terminal long-output protocol` above.
|
|
299
|
+
- Central package policy: see `Central package execution policy` above.
|
|
300
|
+
- Commit message policy: see
|
|
301
|
+
[Commit Convention](20-produck-commit.instructions.md) (canonical source
|
|
302
|
+
for tag whitelist, target whitelist, and validator usage).
|
|
303
|
+
- Cross-repository assumptions: do not assume scripts from the organization
|
|
304
|
+
`.github` repository exist in target repositories.
|
|
305
|
+
- Precedence: repository-specific stricter rules override organization
|
|
306
|
+
defaults.
|
|
322
307
|
|
|
323
308
|
## Precedence
|
|
324
309
|
|
|
@@ -326,4 +311,5 @@ If a repository provides more specific instructions, follow the repository
|
|
|
326
311
|
instructions over this organization baseline.
|
|
327
312
|
|
|
328
313
|
For Node.js repositories, also follow [Node.js Initialization
|
|
329
|
-
Baseline](10-produck-node.instructions.md)
|
|
314
|
+
Baseline](10-produck-node.instructions.md) and [Test Authoring
|
|
315
|
+
Baseline](12-produck-test.instructions.md).
|