azcodr 1.0.0 → 1.1.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.
@@ -45,21 +45,37 @@ if [[ -L "${CLAUDE_FILE}" ]]; then
45
45
  else
46
46
  log_fail "CLAUDE.md points to '${TARGET}' instead of 'AGENTS.md'."
47
47
  fi
48
+ elif [[ -f "${CLAUDE_FILE}" ]] && [[ "$(< "${CLAUDE_FILE}")" == "AGENTS.md" ]]; then
49
+ log_pass "CLAUDE.md is a text pointer to AGENTS.md (symlink fallback)."
48
50
  else
49
51
  log_fail "CLAUDE.md is not a symbolic link."
50
52
  fi
51
53
 
52
- # Check agents.md symlink
54
+ # Check agents.md symlink (case-insensitive filesystem aware)
53
55
  AGENTS_LOWER="${WORKSPACE_ROOT}/agents.md"
54
- if [[ -L "${AGENTS_LOWER}" ]]; then
55
- TARGET=$(readlink "${AGENTS_LOWER}")
56
- if [[ "${TARGET}" == "AGENTS.md" ]]; then
57
- log_pass "agents.md is a valid symlink to AGENTS.md."
56
+ IS_CASE_INSENSITIVE=false
57
+ if [[ "$(uname -s)" == "Darwin" ]] || [[ "$(uname -s)" =~ (MINGW|MSYS|CYGWIN) ]]; then
58
+ IS_CASE_INSENSITIVE=true
59
+ elif [[ -f "${AGENTS_FILE}" ]] && [[ -f "${AGENTS_LOWER}" ]] && [[ ! -L "${AGENTS_LOWER}" ]]; then
60
+ IS_CASE_INSENSITIVE=true
61
+ fi
62
+
63
+ if [[ "${IS_CASE_INSENSITIVE}" == "true" ]]; then
64
+ log_pass "agents.md is satisfied natively by AGENTS.md (case-insensitive filesystem)."
65
+ else
66
+ if [[ ! -L "${AGENTS_LOWER}" ]] && [[ ! -e "${AGENTS_LOWER}" ]] && [[ -f "${AGENTS_FILE}" ]]; then
67
+ ln -sf "AGENTS.md" "${AGENTS_LOWER}"
68
+ fi
69
+ if [[ -L "${AGENTS_LOWER}" ]]; then
70
+ TARGET=$(readlink "${AGENTS_LOWER}")
71
+ if [[ "${TARGET}" == "AGENTS.md" ]]; then
72
+ log_pass "agents.md is a valid symlink to AGENTS.md."
73
+ else
74
+ log_fail "agents.md points to '${TARGET}' instead of 'AGENTS.md'."
75
+ fi
58
76
  else
59
- log_fail "agents.md points to '${TARGET}' instead of 'AGENTS.md'."
77
+ log_fail "agents.md is not a symbolic link."
60
78
  fi
61
- else
62
- log_fail "agents.md is not a symbolic link."
63
79
  fi
64
80
 
65
81
  # 2. Checking Progressive Disclosure Rules (docs/rules)
package/.editorconfig ADDED
@@ -0,0 +1,19 @@
1
+ # http://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ indent_style = space
6
+ indent_size = 2
7
+ end_of_line = lf
8
+ charset = utf-8
9
+ trim_trailing_whitespace = true
10
+ insert_final_newline = true
11
+
12
+ [*.md]
13
+ trim_trailing_whitespace = false
14
+
15
+ [Makefile]
16
+ indent_style = tab
17
+
18
+ [*.go]
19
+ indent_style = tab
package/.gitignore CHANGED
@@ -18,3 +18,6 @@ Thumbs.db
18
18
  .env
19
19
  .env.local
20
20
  .env.*.local
21
+
22
+ # Case-insensitive filesystem parity (agents.md is generated/symlinked on Linux, native on macOS/Windows)
23
+ agents.md
package/AGENTS.md CHANGED
@@ -100,7 +100,7 @@ To prevent context bloat and keep prompt overhead minimal, detailed engineering
100
100
  | **Relentless Questioning** | [docs/rules/relentless_questioning.md](./docs/rules/relentless_questioning.md) | Dynamic context-aware interrogation loops, adaptive decision trees. |
101
101
  | **Workspace Isolation** | [docs/rules/workspace_isolation.md](./docs/rules/workspace_isolation.md) | Strict workspace sovereignty, zero global contamination, local ground truth. |
102
102
  | **Continuous Learning** | [docs/rules/continuous_learning.md](./docs/rules/continuous_learning.md) | Automated defect post-mortems, DO's/DONT's logging, dynamic rule updates. |
103
- | **Upstream Sync** | [docs/rules/upstream_synchronization.md](./docs/rules/upstream_synchronization.md) | Syncing generic AI knowledge to upstream baselines; zero domain contamination. |
103
+ | **Upstream Sync** | [docs/rules/upstream_synchronization.md](./docs/rules/upstream_synchronization.md) | Logging generic architecture improvements to changes.md; zero baseline pollution. |
104
104
  ---
105
105
 
106
106
  ## 4. Agent Configuration & Workspace Architecture
@@ -113,7 +113,6 @@ To prevent context bloat and keep prompt overhead minimal, detailed engineering
113
113
  - [`clean-code-refactor`](.agents/skills/clean-code-refactor/SKILL.md): Refactoring code smells with Clean Code, SOLID, and design patterns.
114
114
  - [`lets-build`](.agents/skills/lets-build/SKILL.md): Conducting architecture interviews to finalize stack, frameworks, package managers, and bootstrapping projects.
115
115
  - [`relentless-questioner`](.agents/skills/relentless-questioner/SKILL.md): Dynamic context-aware interrogation loops before planning and coding.
116
- - [`merge-ai`](.agents/skills/merge-ai/SKILL.md): Auditing, filtering, and merging generic rules and skills to upstream baseline.
117
116
  - **Relentless Skill Architecture Inquiry:** Never author or update skills on assumptions. Interrogate all 7 inquiry branches (placement, trigger intent, domain truth, gotchas/anti-patterns, determinism, progressive bloat, verification loop) defined in [docs/rules/agentic_configuration.md](./docs/rules/agentic_configuration.md) before writing `SKILL.md`.
118
117
  - **Workspace Memory & Knowledge Hub:** Consult [`memory.md`](./memory.md) for ADRs, and [`docs/knowledge/`](./docs/knowledge/knowledge_graph.md) for system topologies, issue logs, and DO's/DONT's.
119
118
  - **Harness Parity & Symlinks:** `AGENTS.md`, `CLAUDE.md`, and `agents.md` must remain identical via filesystem symbolic links to eliminate configuration divergence across different agent harnesses.
package/README.md CHANGED
@@ -31,7 +31,6 @@
31
31
  │ ├── clean-code-refactor/ # Refactoring code smells with GoF & Clean Code
32
32
  │ ├── compliance-audit/ # SOC 2, ISO 27001 & OWASP open-source audits
33
33
  │ ├── lets-build/ # Architecture interview & project bootstrapper
34
- │ ├── merge-ai/ # Auditing & merging generic AI knowledge to upstream
35
34
  │ ├── product-analyst/ # INVEST user stories & Gherkin criteria
36
35
  │ └── relentless-questioner/ # Context-aware dynamic interrogation loop
37
36
  ├── docs/
@@ -45,6 +44,7 @@
45
44
  ├── AGENTS.md # Lean root agentic configuration (< 120 lines)
46
45
  ├── CLAUDE.md -> AGENTS.md # Filesystem symlink for harness parity
47
46
  ├── agents.md -> AGENTS.md # Filesystem symlink for harness parity
47
+ ├── changes.md # Upstream changes ledger
48
48
  ├── memory.md # Master memory hub & Lightweight ADR ledger
49
49
  └── README.md # Project documentation
50
50
  ```
@@ -103,7 +103,7 @@ The architecture enforces 47 atomic, single-responsibility domain rules. Read on
103
103
  | **Relentless Questioning** | [`relentless_questioning.md`](./docs/rules/relentless_questioning.md) | Dynamic context-aware interrogation loops, adaptive decision trees. |
104
104
  | **Workspace Isolation** | [`workspace_isolation.md`](./docs/rules/workspace_isolation.md) | Strict workspace sovereignty, zero global contamination, local ground truth. |
105
105
  | **Continuous Learning** | [`continuous_learning.md`](./docs/rules/continuous_learning.md) | Automated defect post-mortems, DO's/DONT's logging, dynamic rule updates. |
106
- | **Upstream Sync** | [`upstream_synchronization.md`](./docs/rules/upstream_synchronization.md) | Syncing generic AI knowledge to upstream baselines; zero domain contamination. |
106
+ | **Upstream Sync** | [`upstream_synchronization.md`](./docs/rules/upstream_synchronization.md) | Logging generic architecture improvements to changes.md; zero baseline pollution. |
107
107
 
108
108
  ---
109
109
 
@@ -113,7 +113,6 @@ The architecture enforces 47 atomic, single-responsibility domain rules. Read on
113
113
  - [`clean-code-refactor`](.agents/skills/clean-code-refactor/SKILL.md): Refactoring code smells with Clean Code, SOLID, and modern design patterns.
114
114
  - [`compliance-audit`](.agents/skills/compliance-audit/SKILL.md): Conducting SOC 2, ISO 27001, and OWASP audits using open-source scanners.
115
115
  - [`lets-build`](.agents/skills/lets-build/SKILL.md): Conducting architecture interviews to finalize stack, frameworks, package managers, and bootstrapping projects.
116
- - [`merge-ai`](.agents/skills/merge-ai/SKILL.md): Auditing, filtering, and merging generic rules and skills to upstream baseline.
117
116
  - [`product-analyst`](.agents/skills/product-analyst/SKILL.md): Aligning OKRs, backlog ordering (Kano/MoSCoW/RICE), INVEST stories, and Gherkin criteria.
118
117
  - [`relentless-questioner`](.agents/skills/relentless-questioner/SKILL.md): Dynamic context-aware interrogation loops before planning and coding.
119
118
 
@@ -182,3 +181,4 @@ Once confirmed, the agent automatically executes:
182
181
  - 🐛 **[Coding Issue Log](./docs/knowledge/issue_log.md)**: Defect post-mortems and preventative rules.
183
182
  - 💡 **[Institutional Lessons Learned](./docs/knowledge/lessons_learned.md)**: Strategic engineering insights.
184
183
  - 📜 **[Lightweight ADR Ledger](./memory.md)**: Formal Architectural Decision Records.
184
+ - 📝 **[Upstream Changes Ledger](./changes.md)**: Record candidate improvements and generic patterns for the upstream azcodr template.
package/bin/azcodr.js CHANGED
@@ -3,149 +3,300 @@
3
3
 
4
4
  const path = require('node:path');
5
5
  const readline = require('node:readline');
6
- const { scaffold, getTemplateDir } = require('../lib/scaffold.js');
6
+ const fs = require('node:fs');
7
+ const { scaffold, logChange, getTemplateDir } = require('../lib/scaffold.js');
7
8
  const pkg = require('../package.json');
8
9
 
9
- const args = process.argv.slice(2);
10
-
11
- function printHelp() {
12
- console.log(`
10
+ function printHelp(out = console.log) {
11
+ out(`
13
12
  azcodr v${pkg.version}
14
13
  Enterprise Multi-Tenant Architecture & Agentic Engineering Starter Template
15
14
 
16
15
  Usage:
17
16
  npx azcodr [directory] [options]
17
+ npx azcodr change <title> [options]
18
18
 
19
- Arguments:
20
- directory Target directory to scaffold (default: current directory)
19
+ Commands:
20
+ [directory] Scaffold azcodr template into directory (default: current directory)
21
+ change <title> Log a generic architectural change to changes.md
21
22
 
22
- Options:
23
+ Scaffold Options:
24
+ -d, --dry-run Simulate scaffolding without modifying filesystem
25
+ -s, --silent Suppress console output messages
23
26
  -f, --force Overwrite existing files in target directory without confirmation
24
27
  --no-git Do not initialize a git repository
25
28
  -v, --version Display version number
26
29
  -h, --help Display this help message
27
30
 
31
+ Change Options:
32
+ -c, --category Category (Architecture | Rule | Skill | Infrastructure | CLI | Knowledge Hub)
33
+ -f, --files Target file(s) affected (e.g. "docs/rules/caching.md")
34
+ -r, --rationale Rationale for upstream template incorporation
35
+ -d, --desc Detailed description of the change
36
+
28
37
  Examples:
29
38
  npx azcodr my-project
39
+ npx azcodr . --dry-run
30
40
  npx azcodr . --force
41
+ npx azcodr change "Add Wasm plugin interface" -c Architecture
31
42
  `);
32
43
  }
33
44
 
34
- function printVersion() {
35
- console.log(pkg.version);
45
+ function printVersion(out = console.log) {
46
+ out(pkg.version);
36
47
  }
37
48
 
38
- function askQuestion(query) {
39
- const rl = readline.createInterface({
40
- input: process.stdin,
41
- output: process.stdout
42
- });
49
+ function askQuestion(query, { input = process.stdin, output = process.stdout } = {}) {
50
+ const rl = readline.createInterface({ input, output });
43
51
 
44
52
  return new Promise((resolve) => {
53
+ let resolved = false;
45
54
  rl.question(query, (answer) => {
46
- rl.close();
47
- resolve(answer.trim());
55
+ if (!resolved) {
56
+ resolved = true;
57
+ rl.close();
58
+ resolve(answer.trim());
59
+ }
60
+ });
61
+ rl.on('close', () => {
62
+ if (!resolved) {
63
+ resolved = true;
64
+ resolve('');
65
+ }
48
66
  });
49
67
  });
50
68
  }
51
69
 
52
- async function main() {
70
+ async function handleLogChange(rawArgs = process.argv.slice(2), io = {}) {
71
+ const {
72
+ out = console.log,
73
+ err = console.error,
74
+ exit = process.exit,
75
+ stdin = process.stdin,
76
+ stdout = process.stdout,
77
+ cwd = process.cwd(),
78
+ logChange: logChangeFn = logChange
79
+ } = io;
80
+
81
+ let title = null;
82
+ let category = 'Architecture';
83
+ let targetFiles = 'docs/rules/';
84
+ let rationale = 'Generic architectural enhancement';
85
+ let description = '';
86
+
87
+ for (let i = 1; i < rawArgs.length; i++) {
88
+ const a = rawArgs[i];
89
+ if (a === '-c' || a === '--category') {
90
+ category = rawArgs[++i] || category;
91
+ } else if (a === '-f' || a === '--files') {
92
+ targetFiles = rawArgs[++i] || targetFiles;
93
+ } else if (a === '-r' || a === '--rationale') {
94
+ rationale = rawArgs[++i] || rationale;
95
+ } else if (a === '-d' || a === '--desc' || a === '--description') {
96
+ description = rawArgs[++i] || description;
97
+ } else if (a.startsWith('-')) {
98
+ err(`❌ Error: Unknown argument '${a}'. Run 'npx azcodr --help' for available options.`);
99
+ return exit(1);
100
+ } else if (!title) {
101
+ title = a;
102
+ }
103
+ }
104
+
105
+ if (!title) {
106
+ if (stdin.isTTY) {
107
+ title = await askQuestion('? Change title: ', { input: stdin, output: stdout });
108
+ }
109
+ }
110
+
111
+ if (!title) {
112
+ err('❌ Error: A title is required to log an upstream change.');
113
+ err('Usage: npx azcodr change "<title>" [-c Category] [-f Files] [-r Rationale] [-d Description]');
114
+ return exit(1);
115
+ }
116
+
117
+ try {
118
+ const res = logChangeFn({
119
+ title,
120
+ category,
121
+ targetFiles,
122
+ rationale,
123
+ description,
124
+ targetDir: cwd
125
+ });
126
+ out(`\n✅ Upstream change logged to ${res.filePath}\n`);
127
+ return exit(0);
128
+ } catch (error) {
129
+ err(`\n❌ Failed to log change: ${error.message}\n`);
130
+ return exit(1);
131
+ }
132
+ }
133
+
134
+ async function runCli(rawArgs = process.argv.slice(2), io = {}) {
135
+ const {
136
+ out = console.log,
137
+ err = console.error,
138
+ exit = process.exit,
139
+ stdin = process.stdin,
140
+ stdout = process.stdout,
141
+ cwd = process.cwd(),
142
+ templateDir = getTemplateDir(),
143
+ scaffold: scaffoldFn = scaffold
144
+ } = io;
145
+
146
+ if (rawArgs[0] === 'change' || rawArgs[0] === 'log-change') {
147
+ return handleLogChange(rawArgs, io);
148
+ }
149
+
53
150
  let targetDir = null;
54
151
  let force = false;
55
152
  let noGit = false;
153
+ let dryRun = false;
154
+ let silent = false;
56
155
 
57
- for (let i = 0; i < args.length; i++) {
58
- const arg = args[i];
156
+ for (let i = 0; i < rawArgs.length; i++) {
157
+ const arg = rawArgs[i];
59
158
  if (arg === '-h' || arg === '--help') {
60
- printHelp();
61
- process.exit(0);
159
+ printHelp(out);
160
+ return exit(0);
62
161
  } else if (arg === '-v' || arg === '--version') {
63
- printVersion();
64
- process.exit(0);
162
+ printVersion(out);
163
+ return exit(0);
65
164
  } else if (arg === '-f' || arg === '--force') {
66
165
  force = true;
67
166
  } else if (arg === '--no-git') {
68
167
  noGit = true;
69
- } else if (!arg.startsWith('-')) {
70
- if (!targetDir) {
71
- targetDir = arg;
72
- }
168
+ } else if (arg === '-d' || arg === '--dry-run') {
169
+ dryRun = true;
170
+ } else if (arg === '-s' || arg === '--silent') {
171
+ silent = true;
172
+ } else if (arg.startsWith('-')) {
173
+ err(`❌ Error: Unknown argument '${arg}'. Run 'npx azcodr --help' for available options.`);
174
+ return exit(1);
175
+ } else if (!targetDir) {
176
+ targetDir = arg;
73
177
  }
74
178
  }
75
179
 
76
- console.log('\n🚀 azcodr - Enterprise Multi-Tenant Architecture & Agentic Engineering\n');
180
+ if (!silent) {
181
+ out('\n🚀 azcodr - Enterprise Multi-Tenant Architecture & Agentic Engineering\n');
182
+ }
77
183
 
78
184
  if (!targetDir) {
79
- if (process.stdin.isTTY) {
80
- const answer = await askQuestion('? Where would you like to initialize your project? (./) ');
185
+ if (stdin.isTTY) {
186
+ const answer = await askQuestion('? Where would you like to initialize your project? (./) ', {
187
+ input: stdin,
188
+ output: stdout
189
+ });
81
190
  targetDir = answer || '.';
82
191
  } else {
83
192
  targetDir = '.';
84
193
  }
85
194
  }
86
195
 
87
- const resolvedTarget = path.resolve(process.cwd(), targetDir);
88
- const templateDir = getTemplateDir();
196
+ const resolvedTarget = path.resolve(cwd, targetDir);
89
197
 
90
198
  if (resolvedTarget === templateDir) {
91
- console.error(`❌ Error: Cannot scaffold into the template directory itself: ${resolvedTarget}`);
92
- process.exit(1);
199
+ err(`❌ Error: Cannot scaffold into the template directory itself: ${resolvedTarget}`);
200
+ return exit(1);
93
201
  }
94
202
 
95
- const fs = require('node:fs');
96
203
  if (fs.existsSync(resolvedTarget)) {
204
+ const stat = fs.statSync(resolvedTarget);
205
+ if (!stat.isDirectory()) {
206
+ err(`❌ Error: Target '${resolvedTarget}' already exists and is not a directory.`);
207
+ return exit(1);
208
+ }
97
209
  const entries = fs.readdirSync(resolvedTarget);
98
210
  if (entries.length > 0 && !force) {
99
- if (process.stdin.isTTY) {
211
+ if (stdin.isTTY) {
100
212
  const confirm = await askQuestion(
101
- `⚠️ Target directory '${targetDir}' is not empty (${entries.length} items). Continue? (y/N) `
213
+ `⚠️ Target directory '${targetDir}' is not empty (${entries.length} items). Continue? (y/N) `,
214
+ { input: stdin, output: stdout }
102
215
  );
103
216
  if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
104
- console.log('Scaffolding aborted.');
105
- process.exit(0);
217
+ out('Scaffolding aborted.');
218
+ return exit(0);
106
219
  }
107
220
  force = true;
108
221
  } else {
109
- console.error(
110
- `❌ Error: Target directory '${resolvedTarget}' is not empty. Use --force to proceed.`
111
- );
112
- process.exit(1);
222
+ err(`❌ Error: Target directory '${resolvedTarget}' is not empty. Use --force to proceed.`);
223
+ return exit(1);
113
224
  }
114
225
  }
115
226
  }
116
227
 
117
- console.log(`📦 Scaffolding azcodr into: ${resolvedTarget}`);
228
+ if (dryRun) {
229
+ if (!silent) {
230
+ out(`🔍 DRY RUN: Simulating azcodr scaffolding into: ${resolvedTarget}\n`);
231
+ }
232
+ } else if (!silent) {
233
+ out(`📦 Scaffolding azcodr into: ${resolvedTarget}`);
234
+ }
118
235
 
119
236
  try {
120
- const result = scaffold({
237
+ const result = scaffoldFn({
121
238
  targetDir: resolvedTarget,
122
239
  force,
123
240
  noGit,
124
- templateDir
241
+ templateDir,
242
+ dryRun,
243
+ silent
125
244
  });
126
245
 
127
- console.log(' ✅ Progressive disclosure rules copied (docs/rules/)');
128
- console.log(' ✅ Workspace knowledge hub and ADR ledger copied (docs/knowledge/, memory.md)');
129
- console.log(' ✅ Specialized agentic skills copied (.agents/skills/)');
130
- console.log(' ✅ Agent directives and harness symlinks established (AGENTS.md, CLAUDE.md, agents.md)');
131
- if (result.gitInitialized) {
132
- console.log(' ✅ Git repository initialized');
246
+ if (dryRun) {
247
+ if (!silent) {
248
+ for (const action of result.actions) {
249
+ out(` [preview] ${action}`);
250
+ }
251
+ out('\n🎉 Dry run completed. 0 files modified on disk.\n');
252
+ }
253
+ return exit(0);
133
254
  }
134
255
 
135
- console.log('\n🎉 azcodr initialized successfully!\n');
136
- console.log('Next steps:');
137
- if (targetDir !== '.' && targetDir !== './') {
138
- console.log(` 1. cd ${targetDir}`);
256
+ if (!silent) {
257
+ out(' ✅ Progressive disclosure rules copied (docs/rules/)');
258
+ out(' ✅ Workspace knowledge hub and ADR ledger copied (docs/knowledge/, memory.md)');
259
+ out(' ✅ Specialized agentic skills copied (.agents/skills/)');
260
+ out(' ✅ Upstream changes ledger initialized (changes.md)');
261
+ out(' ✅ Editor formatting standards initialized (.editorconfig)');
262
+ out(' ✅ Agent directives and harness symlinks established (AGENTS.md, CLAUDE.md, agents.md)');
263
+ if (result.gitInitialized) {
264
+ out(' ✅ Git repository initialized');
265
+ }
266
+
267
+ out('\n🎉 azcodr initialized successfully!\n');
268
+ out('Next steps:');
269
+ if (targetDir !== '.' && targetDir !== './') {
270
+ out(` 1. cd ${targetDir}`);
271
+ }
272
+ out(' 2. Open the project in your AI coding assistant (Antigravity, Claude Code, Cursor, OpenHands)');
273
+ out(' 3. Run /lets-build to start the architectural interview and scaffold your application stack!\n');
139
274
  }
140
- console.log(' 2. Open the project in your AI coding assistant (Antigravity, Claude Code, Cursor, OpenHands)');
141
- console.log(' 3. Run /lets-build to start the architectural interview and scaffold your application stack!\n');
275
+ return exit(0);
276
+ } catch (error) {
277
+ err(`\n❌ Scaffolding failed: ${error.message}\n`);
278
+ return exit(1);
279
+ }
280
+ }
281
+
282
+ async function main() {
283
+ try {
284
+ await runCli(process.argv.slice(2));
142
285
  } catch (err) {
143
- console.error(`\n❌ Scaffolding failed: ${err.message}\n`);
286
+ console.error('Unexpected error:', err);
144
287
  process.exit(1);
145
288
  }
146
289
  }
147
290
 
148
- main().catch((err) => {
149
- console.error('Unexpected error:', err);
150
- process.exit(1);
151
- });
291
+ if (require.main === module) {
292
+ main();
293
+ }
294
+
295
+ module.exports = {
296
+ runCli,
297
+ handleLogChange,
298
+ askQuestion,
299
+ printHelp,
300
+ printVersion,
301
+ main
302
+ };
package/changes.md ADDED
@@ -0,0 +1,50 @@
1
+ # Upstream Changes Ledger (`changes.md`)
2
+
3
+ > **Core Purpose:** Record candidate improvements, generic architectural updates, defect post-mortems, and rule enhancements discovered in this workspace that should be incorporated into the upstream `azcodr` baseline template. No automated git merging or external repo mutation is performed.
4
+
5
+ ---
6
+
7
+ ## 1. Specification & Protocol
8
+
9
+ When an AI agent or engineer discovers a generic architectural improvement, bug fix, or rule refinement during project development, append an entry below using this atomic format:
10
+
11
+ ```markdown
12
+ ### [YYYY-MM-DD] <Title of Change>
13
+ - **Category:** Rule | Skill | Infrastructure | CLI | Knowledge Hub
14
+ - **Target File(s):** `docs/rules/...`, `.agents/skills/...`, etc.
15
+ - **Rationale:** Why this improvement is necessary or valuable across all enterprise projects.
16
+ - **Description:** Concise summary of the mutation or invariant added.
17
+ - **Domain Filter Verification:** Verified 100% generic; purged of all project-specific business entities and models.
18
+ ```
19
+
20
+ ---
21
+
22
+ ## 2. Upstream Changes Log
23
+
24
+ ### [2026-09-25] Initialized npx Scaffolder CLI and npm Package
25
+ - **Category:** CLI & Infrastructure
26
+ - **Target File(s):** `bin/azcodr.js`, `lib/scaffold.js`, `package.json`, `tests/`
27
+ - **Rationale:** Eliminate manual `cp -r` copying; enable anyone to pull and scaffold the azcodr architecture template via `npx azcodr`.
28
+ - **Description:** Implemented zero-dependency Node.js CLI executable with Outside-In TDD, harness parity symlink generation, script execution bit setting, and full test suite passing with 100% agentic config validation.
29
+ - **Domain Filter Verification:** Verified 100% generic; no project-specific business models.
30
+
31
+ ### [2026-09-25] Streamlined Upstream Sync Protocol to changes.md Ledger
32
+ - **Category:** Rule & Process
33
+ - **Target File(s):** `docs/rules/upstream_synchronization.md`, `changes.md`, `AGENTS.md`
34
+ - **Rationale:** Remove fragile git repo resolution and merge scripts; replace with atomic change logging in `changes.md`.
35
+ - **Description:** Retired `merge-ai` skill and removed machine-specific hardcoded paths. All upstream improvements are now recorded atomically in `changes.md`.
36
+ - **Domain Filter Verification:** Verified 100% generic.
37
+
38
+ ### [2026-09-25] Harden CLI, achieve 100% test coverage gates, add multi-OS CI workflow, and TypeScript declarations
39
+ - **Category:** CLI
40
+ - **Target File(s):** bin/azcodr.js, lib/scaffold.js, lib/index.d.ts, .github/workflows/ci.yml
41
+ - **Rationale:** Fulfill 100.00% test coverage mandate, cross-platform CI matrix, and library type safety
42
+ - **Description:** Remediate gap assessment findings: add --dry-run and --silent flags, enforce 100.00% line/branch/function coverage gates, add GitHub Actions CI matrix across Node 18/20/22/24 and Linux/macOS/Windows, add .editorconfig template item, and export ambient TypeScript typings.
43
+ - **Domain Filter Verification:** Verified 100% generic; purged of all project-specific business entities and models.
44
+
45
+ ### [2026-09-25] Resolve macOS/Windows Git Case-Collision and Cross-Version CI Matrix Coverage
46
+ - **Category:** Infrastructure & CI
47
+ - **Target File(s):** .gitignore, lib/scaffold.js, scripts/test_coverage.js, validate_agentic_configs.sh
48
+ - **Rationale:** Ensure flawless cross-platform and multi-version Node execution across macOS, Windows, and Linux on Node 18, 20, 22, 24.
49
+ - **Description:** Untracked agents.md from Git to prevent cyclic symlink overwrite on case-insensitive filesystems; hardened ensureSymlink with isSameCaseInsensitiveFile check; added cross-version test coverage runner script; updated npm test runner to use native discovery.
50
+ - **Domain Filter Verification:** Verified 100% generic; purged of all project-specific business entities and models.
@@ -1,40 +1,37 @@
1
- # Upstream Baseline Synchronization & AI Knowledge Merging
1
+ # Upstream Baseline Synchronization & changes.md Ledger
2
2
 
3
- > **Core Mandate:** Upstream template/baseline workspaces (`azcodr`) must remain strictly untouched until the user explicitly requests merging. When merging via `/merge-ai`, strictly filter out all domain-specific entities, stacks, and models, keeping the baseline 100% generic.
3
+ > **Core Mandate:** Upstream template/baseline workspaces (`azcodr`) must remain strictly untouched during project development. When generic architectural improvements, rule refinements, or post-mortems are identified, record them solely into the `changes.md` ledger with zero automated repo merging or baseline contamination.
4
4
 
5
5
  ---
6
6
 
7
7
  ## 1. The Baseline-Project Decoupling Principle
8
8
 
9
- Workspaces operate under a strict unidirectional and on-demand bidirectional flow:
9
+ Workspaces operate under a clean, decoupled flow:
10
10
 
11
11
  ```
12
12
  [Upstream Generic Baseline: azcodr]
13
13
  │
14
- ▼ (One-time fork / clone at project inception)
14
+ ▼ (Scaffolded via npx azcodr)
15
15
  [Derived Project Workspace: my-app / others]
16
16
  │
17
17
  │ (Accumulates project code, specificities, and institutional lessons)
18
18
  │
19
- ▼ (ONLY when user explicitly triggers /merge-ai)
20
- [Distillation & Filter: Purge Domain Specificities, Colocate DOs/DONTs]
21
- │
22
- ▼
23
- [Clean Merge into Upstream Baseline: azcodr]
19
+ ▼ (Record reusable improvements)
20
+ [Upstream Changes Ledger: changes.md]
24
21
  ```
25
22
 
26
- - **Pristine Upstream Mandate:** Never edit, commit, or push changes to an upstream baseline repository (`azcodr`) during routine project development, feature implementation, or bug fixes.
27
- - **Explicit Trigger Requirement:** Synchronization into the baseline template may occur **only and exclusively** when the user explicitly issues the `/merge-ai` slash command or direct merge directive.
23
+ - **Pristine Upstream Mandate:** Never edit, commit, or attempt automated git merges to an upstream baseline repository during routine project development, feature implementation, or bug fixes.
24
+ - **Ledger-Only Synchronization:** When generic architectural discoveries or defect post-mortems occur, document them cleanly in `changes.md` at the workspace root. No automated merge AI or remote repo synchronization is executed.
28
25
 
29
26
  ---
30
27
 
31
28
  ## 2. Zero-Contamination Invariant (Generic vs. Specific)
32
29
 
33
- When merging knowledge, rules, or skills back to the baseline, enforce strict domain filtering:
30
+ When logging proposed changes into `changes.md`, enforce strict domain filtering:
34
31
 
35
- | Element Category | Keep in Specific Project Workspace | Allow in Generic Baseline (`azcodr`) |
32
+ | Element Category | Keep in Specific Project Workspace | Allow in changes.md for Upstream (`azcodr`) |
36
33
  |---|---|---|
37
- | **Domain Entities** | Concrete business models (`Order`, `Customer`, `Invoice`, `Account`, etc.) | Abstract archetypes (`Entity`, `Aggregate`, `ValueObject`, `Resource`) |
34
+ | **Domain Entities** | Concrete business models (`Order`, `Customer`, `Invoice`, etc.) | Abstract archetypes (`Entity`, `Aggregate`, `ValueObject`, `Resource`) |
38
35
  | **Tech Stack / Adapters** | Concrete choices (Prisma, SQLite dev, PostgreSQL prod, Vite React) | Hexagonal Ports, abstract repository contracts, polyglot adapter guidance |
39
36
  | **Architectural Rules** | Specific entity validation, specific route paths | Universal invariants (5-Phase Agile Lifecycle, SemVer trigger matrix, FK dropdowns) |
40
37
  | **ADRs** | Stack decisions (`ADR-006: Target Tech Stack for Project`) | Generic architecture patterns (`ADR-007` to `ADR-010`) |
@@ -42,25 +39,30 @@ When merging knowledge, rules, or skills back to the baseline, enforce strict do
42
39
 
43
40
  ---
44
41
 
45
- ## 3. Direct Rule Colocation Protocol
42
+ ## 3. Atomic changes.md Entry Protocol
43
+
44
+ Every upstream-bound proposal logged to `changes.md` must follow the standardized format:
46
45
 
47
- To prevent token bloat and documentation rot:
48
- 1. **Never Duplicate in a Consolidated List:** Never dump merged rules into a monolithic `dos_and_donts.md`.
49
- 2. **Colocate at Source:** Embed DO's and DONT's directly into the relevant atomic rule (`docs/rules/<domain>.md`) and skill (`.agents/skills/<skill>/SKILL.md`).
50
- 3. **Index-Only Directory:** Maintain `docs/knowledge/dos_and_donts.md` strictly as a clean reference table pointing to atomic rules.
46
+ ```markdown
47
+ ### [YYYY-MM-DD] <Title of Change>
48
+ - **Category:** Rule | Skill | Infrastructure | CLI | Knowledge Hub
49
+ - **Target File(s):** `docs/rules/...`, `.agents/skills/...`, etc.
50
+ - **Rationale:** Why this improvement is necessary or valuable across all enterprise projects.
51
+ - **Description:** Concise summary of the mutation or invariant added.
52
+ - **Domain Filter Verification:** Verified 100% generic; purged of all project-specific business entities and models.
53
+ ```
51
54
 
52
55
  ---
53
56
 
54
57
  ## 4. Invariants, DO's & DONT's
55
58
 
56
59
  ### DO's:
57
- - **DO:** Leave the upstream baseline repository (`azcodr`) completely alone during regular development.
58
- - **DO:** Require an explicit `/merge-ai` command before proposing or executing any upstream synchronization.
59
- - **DO:** Distill all lessons and post-mortems into generic, domain-agnostic language before merging.
60
+ - **DO:** Record candidate generic architectural improvements in `changes.md`.
61
+ - **DO:** Distill all lessons and post-mortems into generic, domain-agnostic language before logging.
60
62
  - **DO:** Colocate DOs and DONTs directly inside the relevant atomic rules and skills.
61
- - **DO:** Run `validate_agentic_configs.sh` on the upstream baseline before and after any merge.
63
+ - **DO:** Verify that all entries in `changes.md` are 100% stack- and domain-agnostic.
62
64
 
63
65
  ### DONT's:
64
- - **DONT:** Never touch or edit the upstream baseline template automatically without explicit user command.
65
- - **DONT:** Never contaminate the baseline template with project-specific domain models, entity names, or framework setups.
66
- - **DONT:** Never overwrite upstream baseline files with raw project copies; merge generic concepts surgically.
66
+ - **DONT:** Never execute automated upstream git cloning or merge AI workflows during project work.
67
+ - **DONT:** Never contaminate `changes.md` with project-specific business logic, schemas, or customer requirements.
68
+ - **DONT:** Never leave machine-specific or absolute user paths in scripts or documentation.