azcodr 2.0.0 → 2.2.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/.agents/hooks.json +3 -3
- package/.github/workflows/ci.yml +1 -0
- package/.github/workflows/publish.yml +0 -4
- package/AGENTS.md +1 -1
- package/bin/azcodr.js +11 -4
- package/lib/cli-parse.d.ts +32 -0
- package/lib/cli-parse.d.ts.map +1 -0
- package/lib/cli-parse.js +45 -41
- package/lib/cli-parse.js.map +1 -0
- package/lib/cli-target.d.ts +66 -0
- package/lib/cli-target.d.ts.map +1 -0
- package/lib/cli-target.js +89 -96
- package/lib/cli-target.js.map +1 -0
- package/lib/cli.d.ts +40 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +122 -136
- package/lib/cli.js.map +1 -0
- package/lib/errors.d.ts +54 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +25 -18
- package/lib/errors.js.map +1 -0
- package/lib/git.d.ts +23 -0
- package/lib/git.d.ts.map +1 -0
- package/lib/git.js +33 -22
- package/lib/git.js.map +1 -0
- package/lib/guards.d.ts +50 -0
- package/lib/guards.d.ts.map +1 -0
- package/lib/guards.js +75 -64
- package/lib/guards.js.map +1 -0
- package/lib/index.d.ts +14 -188
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +17 -5
- package/lib/index.js.map +1 -0
- package/lib/links.d.ts +42 -0
- package/lib/links.d.ts.map +1 -0
- package/lib/links.js +116 -99
- package/lib/links.js.map +1 -0
- package/lib/permissions.d.ts +13 -0
- package/lib/permissions.d.ts.map +1 -0
- package/lib/permissions.js +40 -36
- package/lib/permissions.js.map +1 -0
- package/lib/repo.d.ts +30 -0
- package/lib/repo.d.ts.map +1 -0
- package/lib/repo.js +80 -71
- package/lib/repo.js.map +1 -0
- package/lib/scaffold.d.ts +109 -0
- package/lib/scaffold.d.ts.map +1 -0
- package/lib/scaffold.js +165 -197
- package/lib/scaffold.js.map +1 -0
- package/memory.md +24 -0
- package/package.json +14 -5
- package/scripts/validate/adr.js +11 -7
- package/scripts/validate/io.js +7 -9
- package/scripts/validate/links.js +6 -7
- package/scripts/validate/parity.js +5 -7
- package/scripts/validate/root.js +6 -7
- package/scripts/validate/rules.js +7 -9
- package/scripts/validate/skills.js +8 -10
- package/scripts/validate/text.js +3 -5
- package/scripts/validate-cli.js +1 -2
- package/scripts/validate.js +37 -19
- package/src/cli-parse.ts +77 -0
- package/src/cli-target.ts +167 -0
- package/src/cli.ts +240 -0
- package/src/errors.ts +50 -0
- package/src/git.ts +42 -0
- package/src/guards.ts +116 -0
- package/src/index.ts +60 -0
- package/src/links.ts +153 -0
- package/src/permissions.ts +46 -0
- package/src/repo.ts +104 -0
- package/src/scaffold.ts +282 -0
- package/scripts/test_coverage.js +0 -66
package/lib/guards.js
CHANGED
|
@@ -1,71 +1,77 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import { ScaffoldError, ERROR_CODES } from './errors.js';
|
|
6
|
+
import { getTemplateDir } from './scaffold.js';
|
|
8
7
|
/**
|
|
9
8
|
* Filesystem scope guard (Supply Chain: filesystem access).
|
|
10
|
-
* Constrains all reads/writes to targetDir / templateDir.
|
|
9
|
+
* Constrains all reads/writes to targetDir / templateDir, throwing if candidate escapes root.
|
|
10
|
+
*
|
|
11
|
+
* @param root - Absolute base directory.
|
|
12
|
+
* @param candidate - Candidate file or directory path to check.
|
|
13
|
+
* @param message - Optional custom error message.
|
|
14
|
+
* @throws {ScaffoldError} When candidate path escapes root directory.
|
|
11
15
|
*/
|
|
12
|
-
function assertInside(root, candidate, message) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
export function assertInside(root, candidate, message) {
|
|
17
|
+
const resolvedRoot = path.resolve(root);
|
|
18
|
+
const resolvedCandidate = path.resolve(root, candidate);
|
|
19
|
+
const relative = path.relative(resolvedRoot, resolvedCandidate);
|
|
20
|
+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
21
|
+
throw new ScaffoldError('E_PATH_ESCAPE', message || `${ERROR_CODES.E_PATH_ESCAPE}: ${candidate}`);
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
|
-
|
|
21
24
|
/**
|
|
22
25
|
* Normalizes a path for protected-target comparison. On Windows the filesystem
|
|
23
26
|
* is case-insensitive, so `C:\Users\Name` and `c:\users\name` are the same
|
|
24
27
|
* directory and must compare equal.
|
|
28
|
+
*
|
|
29
|
+
* @param p - File or directory path to normalize.
|
|
30
|
+
* @returns Normalized path string.
|
|
25
31
|
*/
|
|
26
|
-
function normalizeForComparison(p) {
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
export function normalizeForComparison(p) {
|
|
33
|
+
const resolved = path.resolve(p);
|
|
34
|
+
return process.platform === 'win32' ? resolved.toLowerCase() : resolved;
|
|
29
35
|
}
|
|
30
|
-
|
|
31
36
|
function readHomeDir() {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
try {
|
|
38
|
+
return os.homedir();
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
|
-
|
|
39
44
|
function isFilesystemRoot(resolvedTarget) {
|
|
40
|
-
|
|
45
|
+
return resolvedTarget === path.parse(resolvedTarget).root;
|
|
41
46
|
}
|
|
42
|
-
|
|
43
47
|
function isHomeOrParent(normalizedTarget, home) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
if (!home)
|
|
49
|
+
return false;
|
|
50
|
+
if (normalizedTarget === normalizeForComparison(home))
|
|
51
|
+
return true;
|
|
52
|
+
const parent = path.dirname(path.resolve(home));
|
|
53
|
+
return normalizedTarget === normalizeForComparison(parent);
|
|
48
54
|
}
|
|
49
|
-
|
|
50
55
|
function isTemplateAncestor(resolvedTarget, templateDir) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
const resolvedTemplate = path.resolve(templateDir);
|
|
57
|
+
const relative = path.relative(resolvedTarget, resolvedTemplate);
|
|
58
|
+
return relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative);
|
|
54
59
|
}
|
|
55
|
-
|
|
56
60
|
function resolvesToProtectedLocation(resolvedTarget, home) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
// Symlink alias: a symlink to / or ~ must not bypass the lexical checks.
|
|
62
|
+
let real = '';
|
|
63
|
+
try {
|
|
64
|
+
if (!fs.existsSync(resolvedTarget))
|
|
65
|
+
return false;
|
|
66
|
+
real = fs.realpathSync(resolvedTarget);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (real === path.parse(real).root)
|
|
72
|
+
return true;
|
|
73
|
+
return Boolean(home) && normalizeForComparison(real) === normalizeForComparison(home);
|
|
67
74
|
}
|
|
68
|
-
|
|
69
75
|
/**
|
|
70
76
|
* Returns true when `targetDir` is a location the scaffolder must never write
|
|
71
77
|
* into: the filesystem root, the user's home directory, the home directory's
|
|
@@ -75,22 +81,27 @@ function resolvesToProtectedLocation(resolvedTarget, home) {
|
|
|
75
81
|
*
|
|
76
82
|
* Lexical comparison is not enough: a symlink pointing at home must also be
|
|
77
83
|
* caught, so an existing target is resolved with realpath before comparing.
|
|
84
|
+
*
|
|
85
|
+
* @param targetDir - The target directory path to evaluate.
|
|
86
|
+
* @param options - Optional configuration for protected target evaluation.
|
|
87
|
+
* @returns True if target is a protected location, false otherwise.
|
|
78
88
|
*/
|
|
79
|
-
function isProtectedTarget(targetDir, options = {}) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
export function isProtectedTarget(targetDir, options = {}) {
|
|
90
|
+
const resolvedTarget = path.resolve(targetDir);
|
|
91
|
+
const normalizedTarget = normalizeForComparison(resolvedTarget);
|
|
92
|
+
if (isFilesystemRoot(resolvedTarget))
|
|
93
|
+
return true;
|
|
94
|
+
const home = readHomeDir();
|
|
95
|
+
if (isHomeOrParent(normalizedTarget, home))
|
|
96
|
+
return true;
|
|
97
|
+
const { templateDir = getTemplateDir() } = options;
|
|
98
|
+
if (isTemplateAncestor(resolvedTarget, templateDir))
|
|
99
|
+
return true;
|
|
100
|
+
return resolvesToProtectedLocation(resolvedTarget, home);
|
|
90
101
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
isProtectedTarget
|
|
102
|
+
export default {
|
|
103
|
+
assertInside,
|
|
104
|
+
normalizeForComparison,
|
|
105
|
+
isProtectedTarget
|
|
96
106
|
};
|
|
107
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,199 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface ScaffoldOptions {
|
|
7
|
-
/** Target directory path where template should be scaffolded (default: process.cwd()) */
|
|
8
|
-
targetDir?: string;
|
|
9
|
-
/** Force overwrite if target directory is non-empty (default: false) */
|
|
10
|
-
force?: boolean;
|
|
11
|
-
/** Skip git repository initialization (default: false) */
|
|
12
|
-
noGit?: boolean;
|
|
13
|
-
/** Custom template root directory (default: azcodr root) */
|
|
14
|
-
templateDir?: string;
|
|
15
|
-
/** Simulate scaffolding without writing files or running git (default: false) */
|
|
16
|
-
dryRun?: boolean;
|
|
17
|
-
/** Suppress console output messages (default: false) */
|
|
18
|
-
silent?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface ScaffoldResult {
|
|
22
|
-
/** Whether the scaffolding succeeded */
|
|
23
|
-
success: boolean;
|
|
24
|
-
/** Absolute resolved path of the target directory */
|
|
25
|
-
targetDir: string;
|
|
26
|
-
/** Whether git init was successfully executed */
|
|
27
|
-
gitInitialized: boolean;
|
|
28
|
-
/** Whether execution ran in dry-run simulation mode */
|
|
29
|
-
dryRun: boolean;
|
|
30
|
-
/** List of files, directories, and symlinks created or simulated */
|
|
31
|
-
actions: string[];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface ValidateTargetOptions {
|
|
35
|
-
/** Custom template root directory */
|
|
36
|
-
templateDir?: string;
|
|
37
|
-
/** Force allow non-empty directory */
|
|
38
|
-
force?: boolean;
|
|
39
|
-
/**
|
|
40
|
-
* Bypass the protected-target guard (filesystem root, home, home's parent,
|
|
41
|
-
* template ancestors). The CLI never passes this. Programmatic use only.
|
|
42
|
-
*/
|
|
43
|
-
allowProtected?: boolean;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface InitGitOptions {
|
|
47
|
-
/** If true, skips git initialization */
|
|
48
|
-
noGit?: boolean;
|
|
49
|
-
/** If true, simulates git initialization without executing */
|
|
50
|
-
dryRun?: boolean;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export interface CopyTemplateOptions {
|
|
54
|
-
/** If true, simulates copy without writing to disk */
|
|
55
|
-
dryRun?: boolean;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Machine-readable failure codes thrown by this library.
|
|
2
|
+
* @module @azcodr/azcodr
|
|
3
|
+
* Enterprise Architecture & Agentic Engineering Starter Template.
|
|
60
4
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*/
|
|
64
|
-
export type ScaffoldErrorCode =
|
|
65
|
-
| 'E_TARGET_IS_TEMPLATE'
|
|
66
|
-
| 'E_TARGET_NOT_EMPTY'
|
|
67
|
-
| 'E_TARGET_IS_PROTECTED'
|
|
68
|
-
| 'E_GIT_ARGS_INVALID'
|
|
69
|
-
| 'E_GIT_BLOCKED'
|
|
70
|
-
| 'E_PATH_ESCAPE';
|
|
71
|
-
|
|
72
|
-
/** Error type thrown by every azcodr API. Always carries a `code`. */
|
|
73
|
-
export interface ScaffoldErrorShape extends Error {
|
|
74
|
-
name: 'ScaffoldError';
|
|
75
|
-
code: ScaffoldErrorCode;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export declare class ScaffoldError extends Error implements ScaffoldErrorShape {
|
|
79
|
-
constructor(code: ScaffoldErrorCode, message: string);
|
|
80
|
-
name: 'ScaffoldError';
|
|
81
|
-
code: ScaffoldErrorCode;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** Human-readable prefix for each code, as thrown. */
|
|
85
|
-
export declare const ERROR_CODES: Readonly<Record<ScaffoldErrorCode, string>>;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* High-level orchestration function to scaffold the azcodr workspace into targetDir.
|
|
89
|
-
*/
|
|
90
|
-
export function scaffold(options?: ScaffoldOptions): ScaffoldResult;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Validates the target directory to ensure it is suitable for scaffolding.
|
|
94
|
-
*/
|
|
95
|
-
export function validateTarget(targetDir: string, options?: ValidateTargetOptions): void;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Copies template items into target directory and sets up symlinks and permissions.
|
|
99
|
-
*/
|
|
100
|
-
export function copyTemplate(
|
|
101
|
-
targetDir: string,
|
|
102
|
-
templateDir?: string,
|
|
103
|
-
options?: CopyTemplateOptions
|
|
104
|
-
): string[];
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Safely creates or updates a symbolic link, falling back to a file copy if symlinks are unsupported.
|
|
108
|
-
*/
|
|
109
|
-
export function ensureSymlink(options: {
|
|
110
|
-
targetDir: string;
|
|
111
|
-
linkName: string;
|
|
112
|
-
targetFileName: string;
|
|
113
|
-
dryRun?: boolean;
|
|
114
|
-
}): boolean;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Creates a symlink, falling back to a text pointer (not a full copy).
|
|
118
|
-
*/
|
|
119
|
-
export function ensureSymlinkOrPointer(options: {
|
|
120
|
-
targetDir: string;
|
|
121
|
-
linkName: string;
|
|
122
|
-
targetFileName: string;
|
|
123
|
-
dryRun?: boolean;
|
|
124
|
-
}): boolean;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Detects whether linkName and targetFileName refer to the same entry on a case-insensitive filesystem.
|
|
128
|
-
*/
|
|
129
|
-
export function isSameCaseInsensitiveFile(
|
|
130
|
-
targetDir: string,
|
|
131
|
-
linkName: string,
|
|
132
|
-
targetFileName: string
|
|
133
|
-
): boolean;
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Ensures all bash scripts in skill directories have executable permissions (0o755).
|
|
137
|
-
*/
|
|
138
|
-
export function makeScriptsExecutable(targetDir: string, dryRun?: boolean): string[];
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Initializes a git repository in the target directory if not already inside one.
|
|
142
|
-
*/
|
|
143
|
-
export function initGit(targetDir: string, options?: InitGitOptions): boolean;
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Detects whether targetDir is already inside an existing Git worktree.
|
|
147
|
-
* Shell access is limited to `git rev-parse` via a shell-free allowlisted spawn.
|
|
148
|
-
*/
|
|
149
|
-
export function isInsideGitWorkTree(targetDir: string): boolean;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Spawns `git` with argv (never a shell string) through an explicit
|
|
153
|
-
* subcommand allowlist. @throws ScaffoldError with E_GIT_ARGS_INVALID or E_GIT_BLOCKED.
|
|
5
|
+
* Provides problem-first, topology-aligned project scaffolding with strict systemic atomicity,
|
|
6
|
+
* filesystem scope guards, git worktree initialization, and multi-agent harness parity.
|
|
154
7
|
*/
|
|
155
|
-
export function runGit(args: string[], options?: Record<string, unknown>): string;
|
|
156
|
-
|
|
157
8
|
/**
|
|
158
|
-
*
|
|
159
|
-
* @throws ScaffoldError with E_PATH_ESCAPE.
|
|
9
|
+
* Union type of all valid machine-readable error codes.
|
|
160
10
|
*/
|
|
161
|
-
export
|
|
162
|
-
|
|
11
|
+
export type ScaffoldErrorCode = 'E_TARGET_IS_TEMPLATE' | 'E_TARGET_NOT_EMPTY' | 'E_TARGET_IS_PROTECTED' | 'E_GIT_ARGS_INVALID' | 'E_GIT_BLOCKED' | 'E_PATH_ESCAPE';
|
|
163
12
|
/**
|
|
164
|
-
*
|
|
165
|
-
* must never write into (filesystem root, home, home's parent, template
|
|
166
|
-
* ancestors, symlink aliases). @throws never; pure predicate.
|
|
13
|
+
* Core scaffolding functions, guards, utilities, error classes, and constants.
|
|
167
14
|
*/
|
|
168
|
-
export
|
|
169
|
-
|
|
15
|
+
export { scaffold, validateTarget, copyTemplate, ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile, makeScriptsExecutable, initGit, isInsideGitWorkTree, runGit, assertInside, isProtectedTarget, getTemplateDir, TEMPLATE_ITEMS, ScaffoldError, ERROR_CODES } from './scaffold.js';
|
|
170
16
|
/**
|
|
171
|
-
*
|
|
17
|
+
* Type definitions and option interfaces for scaffolding operations.
|
|
172
18
|
*/
|
|
173
|
-
export
|
|
174
|
-
|
|
19
|
+
export type { ScaffoldOptions, ScaffoldResult, ValidateTargetOptions, CopyTemplateOptions, EnsureSymlinkOptions, InitGitOptions, ScaffoldErrorShape } from './scaffold.js';
|
|
20
|
+
import scaffoldModule from './scaffold.js';
|
|
175
21
|
/**
|
|
176
|
-
*
|
|
22
|
+
* Default export providing the unified azcodr scaffolding module.
|
|
177
23
|
*/
|
|
178
|
-
export
|
|
179
|
-
|
|
180
|
-
declare const defaultExport: {
|
|
181
|
-
scaffold: typeof scaffold;
|
|
182
|
-
validateTarget: typeof validateTarget;
|
|
183
|
-
copyTemplate: typeof copyTemplate;
|
|
184
|
-
ensureSymlink: typeof ensureSymlink;
|
|
185
|
-
ensureSymlinkOrPointer: typeof ensureSymlinkOrPointer;
|
|
186
|
-
isSameCaseInsensitiveFile: typeof isSameCaseInsensitiveFile;
|
|
187
|
-
makeScriptsExecutable: typeof makeScriptsExecutable;
|
|
188
|
-
initGit: typeof initGit;
|
|
189
|
-
isInsideGitWorkTree: typeof isInsideGitWorkTree;
|
|
190
|
-
runGit: typeof runGit;
|
|
191
|
-
assertInside: typeof assertInside;
|
|
192
|
-
isProtectedTarget: typeof isProtectedTarget;
|
|
193
|
-
getTemplateDir: typeof getTemplateDir;
|
|
194
|
-
TEMPLATE_ITEMS: typeof TEMPLATE_ITEMS;
|
|
195
|
-
ScaffoldError: typeof ScaffoldError;
|
|
196
|
-
ERROR_CODES: typeof ERROR_CODES;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
export default defaultExport;
|
|
24
|
+
export default scaffoldModule;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,sBAAsB,GACtB,oBAAoB,GACpB,uBAAuB,GACvB,oBAAoB,GACpB,eAAe,GACf,eAAe,CAAC;AAEpB;;GAEG;AACH,OAAO,EACL,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,OAAO,EACP,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,aAAa,EACb,WAAW,EACZ,MAAM,eAAe,CAAC;AAEvB;;GAEG;AACH,YAAY,EACV,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,cAAc,MAAM,eAAe,CAAC;AAE3C;;GAEG;AACH,eAAe,cAAc,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module @azcodr/azcodr
|
|
3
|
+
* Enterprise Architecture & Agentic Engineering Starter Template.
|
|
4
|
+
*
|
|
5
|
+
* Provides problem-first, topology-aligned project scaffolding with strict systemic atomicity,
|
|
6
|
+
* filesystem scope guards, git worktree initialization, and multi-agent harness parity.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Core scaffolding functions, guards, utilities, error classes, and constants.
|
|
10
|
+
*/
|
|
11
|
+
export { scaffold, validateTarget, copyTemplate, ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile, makeScriptsExecutable, initGit, isInsideGitWorkTree, runGit, assertInside, isProtectedTarget, getTemplateDir, TEMPLATE_ITEMS, ScaffoldError, ERROR_CODES } from './scaffold.js';
|
|
12
|
+
import scaffoldModule from './scaffold.js';
|
|
13
|
+
/**
|
|
14
|
+
* Default export providing the unified azcodr scaffolding module.
|
|
15
|
+
*/
|
|
16
|
+
export default scaffoldModule;
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;GAEG;AACH,OAAO,EACL,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,OAAO,EACP,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,aAAa,EACb,WAAW,EACZ,MAAM,eAAe,CAAC;AAevB,OAAO,cAAc,MAAM,eAAe,CAAC;AAE3C;;GAEG;AACH,eAAe,cAAc,CAAC"}
|
package/lib/links.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for symlink and pointer creation.
|
|
3
|
+
*/
|
|
4
|
+
export interface EnsureSymlinkOptions {
|
|
5
|
+
targetDir: string;
|
|
6
|
+
linkName: string;
|
|
7
|
+
targetFileName: string;
|
|
8
|
+
dryRun?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Detects whether linkName and targetFileName refer to the same entry on a case-insensitive filesystem.
|
|
12
|
+
* Uses exact directory listing (not existsSync, which lies on case-insensitive systems).
|
|
13
|
+
*
|
|
14
|
+
* @param targetDir - Directory containing the file entries.
|
|
15
|
+
* @param linkName - Name of the proposed symlink or alias entry.
|
|
16
|
+
* @param targetFileName - Target file name to match against.
|
|
17
|
+
* @returns True if both names resolve to the same disk file on a case-insensitive filesystem.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isSameCaseInsensitiveFile(targetDir: string, linkName: string, targetFileName: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Safely creates or updates a symbolic link, falling back to a file copy if symlinks are unsupported.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Options specifying target directory, link name, target file name, and dry-run mode.
|
|
24
|
+
* @returns True if the symlink or copy fallback was successfully established.
|
|
25
|
+
*/
|
|
26
|
+
export declare function ensureSymlink(options: EnsureSymlinkOptions): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a symlink, falling back to a text pointer (not a full copy).
|
|
29
|
+
* Used for .github/copilot-instructions.md where a full AGENTS.md copy would
|
|
30
|
+
* break relative markdown links (they resolve from .github/, not root).
|
|
31
|
+
*
|
|
32
|
+
* @param options - Options specifying target directory, link name, target file name, and dry-run mode.
|
|
33
|
+
* @returns True if the symlink or pointer fallback was successfully established.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ensureSymlinkOrPointer(options: EnsureSymlinkOptions): boolean;
|
|
36
|
+
declare const _default: {
|
|
37
|
+
isSameCaseInsensitiveFile: typeof isSameCaseInsensitiveFile;
|
|
38
|
+
ensureSymlink: typeof ensureSymlink;
|
|
39
|
+
ensureSymlinkOrPointer: typeof ensureSymlinkOrPointer;
|
|
40
|
+
};
|
|
41
|
+
export default _default;
|
|
42
|
+
//# sourceMappingURL=links.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA6DD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,OAAO,CAWT;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAapE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAmB7E;;;;;;AAED,wBAIE"}
|