@antomanc/aginit 0.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.
Files changed (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +245 -0
  3. package/THIRD_PARTY_NOTICES.md +36 -0
  4. package/bin/aginit.js +8 -0
  5. package/dist/adapters/agents-md.d.ts +8 -0
  6. package/dist/adapters/agents-md.d.ts.map +1 -0
  7. package/dist/adapters/agents-md.js +121 -0
  8. package/dist/adapters/agents-md.js.map +1 -0
  9. package/dist/adapters/browser.d.ts +5 -0
  10. package/dist/adapters/browser.d.ts.map +1 -0
  11. package/dist/adapters/browser.js +42 -0
  12. package/dist/adapters/browser.js.map +1 -0
  13. package/dist/adapters/git.d.ts +5 -0
  14. package/dist/adapters/git.d.ts.map +1 -0
  15. package/dist/adapters/git.js +90 -0
  16. package/dist/adapters/git.js.map +1 -0
  17. package/dist/adapters/graft.d.ts +14 -0
  18. package/dist/adapters/graft.d.ts.map +1 -0
  19. package/dist/adapters/graft.js +56 -0
  20. package/dist/adapters/graft.js.map +1 -0
  21. package/dist/adapters/package-manager.d.ts +20 -0
  22. package/dist/adapters/package-manager.d.ts.map +1 -0
  23. package/dist/adapters/package-manager.js +89 -0
  24. package/dist/adapters/package-manager.js.map +1 -0
  25. package/dist/adapters/skills.d.ts +29 -0
  26. package/dist/adapters/skills.d.ts.map +1 -0
  27. package/dist/adapters/skills.js +80 -0
  28. package/dist/adapters/skills.js.map +1 -0
  29. package/dist/cli/doctor.d.ts +2 -0
  30. package/dist/cli/doctor.d.ts.map +1 -0
  31. package/dist/cli/doctor.js +212 -0
  32. package/dist/cli/doctor.js.map +1 -0
  33. package/dist/cli/init.d.ts +3 -0
  34. package/dist/cli/init.d.ts.map +1 -0
  35. package/dist/cli/init.js +32 -0
  36. package/dist/cli/init.js.map +1 -0
  37. package/dist/cli/main.d.ts +3 -0
  38. package/dist/cli/main.d.ts.map +1 -0
  39. package/dist/cli/main.js +162 -0
  40. package/dist/cli/main.js.map +1 -0
  41. package/dist/cli/new.d.ts +15 -0
  42. package/dist/cli/new.d.ts.map +1 -0
  43. package/dist/cli/new.js +161 -0
  44. package/dist/cli/new.js.map +1 -0
  45. package/dist/cli/wizard.d.ts +31 -0
  46. package/dist/cli/wizard.d.ts.map +1 -0
  47. package/dist/cli/wizard.js +260 -0
  48. package/dist/cli/wizard.js.map +1 -0
  49. package/dist/config/defaults.d.ts +8 -0
  50. package/dist/config/defaults.d.ts.map +1 -0
  51. package/dist/config/defaults.js +122 -0
  52. package/dist/config/defaults.js.map +1 -0
  53. package/dist/config/schema.d.ts +40 -0
  54. package/dist/config/schema.d.ts.map +1 -0
  55. package/dist/config/schema.js +4 -0
  56. package/dist/config/schema.js.map +1 -0
  57. package/dist/config/validation.d.ts +11 -0
  58. package/dist/config/validation.d.ts.map +1 -0
  59. package/dist/config/validation.js +99 -0
  60. package/dist/config/validation.js.map +1 -0
  61. package/dist/index.d.ts +16 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +16 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/presets/adr.d.ts +5 -0
  66. package/dist/presets/adr.d.ts.map +1 -0
  67. package/dist/presets/adr.js +33 -0
  68. package/dist/presets/adr.js.map +1 -0
  69. package/dist/presets/cli.d.ts +3 -0
  70. package/dist/presets/cli.d.ts.map +1 -0
  71. package/dist/presets/cli.js +126 -0
  72. package/dist/presets/cli.js.map +1 -0
  73. package/dist/presets/generic.d.ts +3 -0
  74. package/dist/presets/generic.d.ts.map +1 -0
  75. package/dist/presets/generic.js +29 -0
  76. package/dist/presets/generic.js.map +1 -0
  77. package/dist/presets/registry.d.ts +6 -0
  78. package/dist/presets/registry.d.ts.map +1 -0
  79. package/dist/presets/registry.js +20 -0
  80. package/dist/presets/registry.js.map +1 -0
  81. package/dist/presets/testing.d.ts +6 -0
  82. package/dist/presets/testing.d.ts.map +1 -0
  83. package/dist/presets/testing.js +46 -0
  84. package/dist/presets/testing.js.map +1 -0
  85. package/dist/presets/types.d.ts +14 -0
  86. package/dist/presets/types.d.ts.map +1 -0
  87. package/dist/presets/types.js +2 -0
  88. package/dist/presets/types.js.map +1 -0
  89. package/dist/presets/web.d.ts +3 -0
  90. package/dist/presets/web.d.ts.map +1 -0
  91. package/dist/presets/web.js +84 -0
  92. package/dist/presets/web.js.map +1 -0
  93. package/dist/utils/fs.d.ts +13 -0
  94. package/dist/utils/fs.d.ts.map +1 -0
  95. package/dist/utils/fs.js +60 -0
  96. package/dist/utils/fs.js.map +1 -0
  97. package/dist/utils/logger.d.ts +10 -0
  98. package/dist/utils/logger.d.ts.map +1 -0
  99. package/dist/utils/logger.js +20 -0
  100. package/dist/utils/logger.js.map +1 -0
  101. package/dist/utils/shell.d.ts +17 -0
  102. package/dist/utils/shell.d.ts.map +1 -0
  103. package/dist/utils/shell.js +87 -0
  104. package/dist/utils/shell.js.map +1 -0
  105. package/package.json +71 -0
  106. package/src/adapters/agents-md.ts +143 -0
  107. package/src/adapters/browser.ts +49 -0
  108. package/src/adapters/git.ts +100 -0
  109. package/src/adapters/graft.ts +80 -0
  110. package/src/adapters/package-manager.ts +116 -0
  111. package/src/adapters/skills.ts +117 -0
  112. package/src/cli/doctor.ts +244 -0
  113. package/src/cli/init.ts +34 -0
  114. package/src/cli/main.ts +191 -0
  115. package/src/cli/new.ts +200 -0
  116. package/src/cli/wizard.ts +300 -0
  117. package/src/config/defaults.ts +137 -0
  118. package/src/config/schema.ts +44 -0
  119. package/src/config/validation.ts +96 -0
  120. package/src/index.ts +15 -0
  121. package/src/presets/adr.ts +37 -0
  122. package/src/presets/cli.ts +136 -0
  123. package/src/presets/generic.ts +32 -0
  124. package/src/presets/registry.ts +24 -0
  125. package/src/presets/testing.ts +56 -0
  126. package/src/presets/types.ts +15 -0
  127. package/src/presets/web.ts +99 -0
  128. package/src/utils/fs.ts +79 -0
  129. package/src/utils/logger.ts +20 -0
  130. package/src/utils/shell.ts +116 -0
@@ -0,0 +1,33 @@
1
+ import path from 'node:path';
2
+ import { safeWriteFile } from '../utils/fs.js';
3
+ const ADR_0001_CONTENT = `# 1. Record Architecture Decisions
4
+
5
+ Date: 2026-10-04
6
+
7
+ ## Status
8
+ Accepted
9
+
10
+ ## Context
11
+ We need to record significant architectural, structural, and tooling decisions
12
+ made throughout the lifecycle of this project so humans and AI agents understand
13
+ the rationale behind key choices.
14
+
15
+ ## Decision
16
+ We will use Architecture Decision Records (ADRs) stored in \`docs/adr/\`.
17
+ Each record describes:
18
+ - **Status**: Proposed, Accepted, Rejected, Superseded.
19
+ - **Context**: The problem or requirement prompting the decision.
20
+ - **Decision**: The selected option and why it was chosen.
21
+ - **Consequences**: Positive and negative outcomes or trade-offs.
22
+
23
+ ## Consequences
24
+ - Every major architectural shift is tracked in version control.
25
+ - Agents reading this repository can inspect historical decisions to avoid
26
+ re-proposing already evaluated or superseded designs.
27
+ `;
28
+ export function setupAdr(targetDir, options = {}) {
29
+ const { dryRun = false, silent = false } = options;
30
+ const adrFile = path.join(targetDir, 'docs', 'adr', '0001-record-architecture-decisions.md');
31
+ safeWriteFile(adrFile, ADR_0001_CONTENT, { dryRun, silent });
32
+ }
33
+ //# sourceMappingURL=adr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adr.js","sourceRoot":"","sources":["../../src/presets/adr.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBxB,CAAC;AAEF,MAAM,UAAU,QAAQ,CACtB,SAAiB,EACjB,UAAkD,EAAE;IAEpD,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,uCAAuC,CAAC,CAAC;IAC7F,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { PresetHandler } from './types.js';
2
+ export declare const cliPreset: PresetHandler;
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/presets/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,aAAa,EAAE,MAAM,YAAY,CAAC;AAK1D,eAAO,MAAM,SAAS,EAAE,aAgIvB,CAAC"}
@@ -0,0 +1,126 @@
1
+ import path from 'node:path';
2
+ import { fileExists, safeWriteFile, writeJsonFile } from '../utils/fs.js';
3
+ import { readPackageManifest } from '../config/validation.js';
4
+ import { addTestingDependencies, setupTesting, VITEST_VERSION } from './testing.js';
5
+ import { setupAdr } from './adr.js';
6
+ export const cliPreset = {
7
+ name: 'cli',
8
+ description: 'AI-first TypeScript CLI application with Commander, Picocolors, and Vitest',
9
+ async scaffold(ctx) {
10
+ const { targetDir, projectName, dryRun, silent } = ctx;
11
+ const pm = ctx.config.packageManager || 'pnpm';
12
+ const existing = readPackageManifest(targetDir);
13
+ if (existing) {
14
+ const hadVitestScript = Object.values(existing.scripts || {}).some((script) => typeof script === 'string' && /^vitest(?:\s|$)/.test(script));
15
+ addTestingDependencies(existing);
16
+ writeJsonFile(path.join(targetDir, 'package.json'), existing, {
17
+ overwrite: true,
18
+ dryRun,
19
+ silent
20
+ });
21
+ setupTesting(ctx, hadVitestScript);
22
+ if (ctx.config.docs.adr)
23
+ setupAdr(targetDir, { dryRun, silent });
24
+ return;
25
+ }
26
+ // 1. package.json
27
+ const pkg = {
28
+ name: projectName,
29
+ version: '0.1.0',
30
+ type: 'module',
31
+ bin: {
32
+ [projectName.split('/').pop()]: './bin/cli.js'
33
+ },
34
+ scripts: {
35
+ build: 'tsc',
36
+ test: 'vitest run',
37
+ 'test:watch': 'vitest',
38
+ typecheck: 'tsc --noEmit',
39
+ prepack: 'tsc'
40
+ },
41
+ dependencies: {
42
+ commander: '^12.1.0',
43
+ picocolors: '^1.1.1'
44
+ },
45
+ devDependencies: {
46
+ '@types/node': '^22.8.0',
47
+ typescript: '^5.6.3',
48
+ vitest: VITEST_VERSION
49
+ }
50
+ };
51
+ writeJsonFile(path.join(targetDir, 'package.json'), pkg, { dryRun, silent });
52
+ // pnpm-workspace.yaml generated ONLY for pnpm!
53
+ if (pm === 'pnpm') {
54
+ const workspaceYamlPath = path.join(targetDir, 'pnpm-workspace.yaml');
55
+ if (!fileExists(workspaceYamlPath)) {
56
+ const workspaceYaml = `allowBuilds:\n esbuild: true\n`;
57
+ safeWriteFile(workspaceYamlPath, workspaceYaml, { dryRun, silent });
58
+ }
59
+ }
60
+ // 2. tsconfig.json
61
+ const tsconfig = {
62
+ compilerOptions: {
63
+ target: 'ES2022',
64
+ module: 'NodeNext',
65
+ moduleResolution: 'NodeNext',
66
+ lib: ['ES2022'],
67
+ strict: true,
68
+ skipLibCheck: true,
69
+ outDir: 'dist',
70
+ rootDir: 'src',
71
+ declaration: true
72
+ },
73
+ include: ['src/**/*']
74
+ };
75
+ writeJsonFile(path.join(targetDir, 'tsconfig.json'), tsconfig, { dryRun, silent });
76
+ // 3. vitest.config.ts
77
+ const vitestConfig = `import { defineConfig } from 'vitest/config';
78
+
79
+ export default defineConfig({
80
+ test: {
81
+ include: ['tests/**/*.test.{js,ts}']
82
+ }
83
+ });
84
+ `;
85
+ safeWriteFile(path.join(targetDir, 'vitest.config.ts'), vitestConfig, { dryRun, silent });
86
+ // 4. Executable CLI entrypoint
87
+ const binCli = `#!/usr/bin/env node
88
+ import { run } from '../dist/index.js';
89
+
90
+ run(process.argv.slice(2)).catch((err) => {
91
+ console.error(err);
92
+ process.exit(1);
93
+ });
94
+ `;
95
+ safeWriteFile(path.join(targetDir, 'bin', 'cli.js'), binCli, {
96
+ dryRun,
97
+ silent,
98
+ mode: 0o755
99
+ });
100
+ // 5. Source code
101
+ const srcIndex = `export async function run(args: string[] = []): Promise<void> {\n console.log(${JSON.stringify(projectName + ' ready. Args:')}, args);\n}\n`;
102
+ const createdSource = safeWriteFile(path.join(targetDir, 'src', 'index.ts'), srcIndex, {
103
+ dryRun,
104
+ silent
105
+ });
106
+ // 6. Unit test
107
+ const unitTest = `import { describe, it, expect } from 'vitest';
108
+ import { run } from '../src/index.js';
109
+
110
+ describe('run', () => {
111
+ it('runs with the supplied arguments', async () => {
112
+ await expect(run(['--help'])).resolves.toBeUndefined();
113
+ });
114
+ });
115
+ `;
116
+ if (createdSource)
117
+ safeWriteFile(path.join(targetDir, 'tests', 'index.test.ts'), unitTest, { dryRun, silent });
118
+ else
119
+ setupTesting(ctx);
120
+ // 7. Docs ADR
121
+ if (ctx.config.docs.adr) {
122
+ setupAdr(targetDir, { dryRun, silent });
123
+ }
124
+ }
125
+ };
126
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/presets/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { PresetHandler } from './types.js';
2
+ export declare const genericPreset: PresetHandler;
3
+ //# sourceMappingURL=generic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/presets/generic.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,aAAa,EAAE,MAAM,YAAY,CAAC;AAI1D,eAAO,MAAM,aAAa,EAAE,aAyB3B,CAAC"}
@@ -0,0 +1,29 @@
1
+ import path from 'node:path';
2
+ import { fileExists, writeJsonFile } from '../utils/fs.js';
3
+ import { addTestingDependencies, setupTesting } from './testing.js';
4
+ import { setupAdr } from './adr.js';
5
+ export const genericPreset = {
6
+ name: 'generic',
7
+ description: 'Minimal, unopinionated project skeleton with AI skills, Git, and ADR structure',
8
+ async scaffold(ctx) {
9
+ const { targetDir, projectName, dryRun, silent } = ctx;
10
+ const pkgPath = path.join(targetDir, 'package.json');
11
+ if (!fileExists(pkgPath)) {
12
+ const pkg = {
13
+ name: projectName,
14
+ version: '0.1.0',
15
+ type: 'module',
16
+ scripts: {
17
+ test: 'vitest run'
18
+ }
19
+ };
20
+ addTestingDependencies(pkg);
21
+ writeJsonFile(pkgPath, pkg, { dryRun, silent });
22
+ setupTesting(ctx);
23
+ }
24
+ if (ctx.config.docs.adr) {
25
+ setupAdr(targetDir, { dryRun, silent });
26
+ }
27
+ }
28
+ };
29
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/presets/generic.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,gFAAgF;IAC7F,KAAK,CAAC,QAAQ,CAAC,GAAkB;QAC/B,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;QAEvD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG;gBACV,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE;oBACP,IAAI,EAAE,YAAY;iBACnB;aACF,CAAC;YACF,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC5B,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAChD,YAAY,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { PresetHandler } from './types.js';
2
+ import { PresetType } from '../config/schema.js';
3
+ export declare const presets: Record<PresetType, PresetHandler>;
4
+ export declare function getPreset(name: string): PresetHandler;
5
+ export declare function listPresets(): PresetHandler[];
6
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/presets/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI3C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,aAAa,CAIrD,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAOrD;AAED,wBAAgB,WAAW,IAAI,aAAa,EAAE,CAE7C"}
@@ -0,0 +1,20 @@
1
+ import { webPreset } from './web.js';
2
+ import { cliPreset } from './cli.js';
3
+ import { genericPreset } from './generic.js';
4
+ export const presets = {
5
+ web: webPreset,
6
+ cli: cliPreset,
7
+ generic: genericPreset
8
+ };
9
+ export function getPreset(name) {
10
+ const handler = presets[name];
11
+ if (!handler) {
12
+ const valid = Object.keys(presets).join(', ');
13
+ throw new Error(`Unknown preset: "${name}". Valid presets are: ${valid}`);
14
+ }
15
+ return handler;
16
+ }
17
+ export function listPresets() {
18
+ return Object.values(presets);
19
+ }
20
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/presets/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,CAAC,MAAM,OAAO,GAAsC;IACxD,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,aAAa;CACvB,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAkB,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,yBAAyB,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { PresetContext } from './types.js';
2
+ export declare const VITEST_VERSION = "^4.1.11";
3
+ export declare function addTestingDependencies(pkg: Record<string, any>, playwright?: boolean): void;
4
+ /** A starter harness checks package metadata without assuming application exports. */
5
+ export declare function setupTesting(ctx: PresetContext, preserveViteTestConfig?: boolean): void;
6
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/presets/testing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,cAAc,YAAY,CAAC;AACxC,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,UAAQ,GAAG,IAAI,CAczF;AAED,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,sBAAsB,UAAQ,GAAG,IAAI,CAiCrF"}
@@ -0,0 +1,46 @@
1
+ import path from 'node:path';
2
+ import { safeWriteFile, fileExists } from '../utils/fs.js';
3
+ export const VITEST_VERSION = '^4.1.11';
4
+ export function addTestingDependencies(pkg, playwright = false) {
5
+ pkg.scripts ??= {};
6
+ pkg.devDependencies ??= {};
7
+ if (!pkg.dependencies?.vitest && !pkg.devDependencies.vitest)
8
+ pkg.devDependencies.vitest = VITEST_VERSION;
9
+ const customTest = pkg.scripts.test && !/^vitest(?:\s|$)/.test(pkg.scripts.test);
10
+ const testScript = customTest ? 'test:unit' : 'test';
11
+ pkg.scripts[testScript] ??= 'vitest run';
12
+ pkg.scripts[customTest ? 'test:unit:watch' : 'test:watch'] ??= 'vitest';
13
+ if (playwright) {
14
+ pkg.scripts['test:e2e'] ??= 'playwright test';
15
+ if (!pkg.dependencies?.['@playwright/test'] && !pkg.devDependencies['@playwright/test'])
16
+ pkg.devDependencies['@playwright/test'] = '^1.63.0';
17
+ }
18
+ }
19
+ /** A starter harness checks package metadata without assuming application exports. */
20
+ export function setupTesting(ctx, preserveViteTestConfig = false) {
21
+ const { targetDir, dryRun, silent } = ctx;
22
+ const hasConfig = [
23
+ 'vitest.config.ts',
24
+ 'vitest.config.js',
25
+ 'vitest.config.mts',
26
+ 'vitest.config.mjs',
27
+ 'vitest.config.cts',
28
+ 'vitest.config.cjs',
29
+ ...(preserveViteTestConfig
30
+ ? ['vite.config.ts', 'vite.config.js', 'vite.config.mts', 'vite.config.mjs']
31
+ : [])
32
+ ].some((name) => fileExists(path.join(targetDir, name)));
33
+ if (!hasConfig)
34
+ safeWriteFile(path.join(targetDir, 'vitest.config.mts'), `import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n test: { include: ['tests/**/*.test.{js,ts}'] }\n});\n`, { dryRun, silent });
35
+ safeWriteFile(path.join(targetDir, 'tests', 'aginit.test.js'), `import { it, expect } from 'vitest';
36
+ import { readFileSync } from 'node:fs';
37
+
38
+ // Starter harness: add application behavior tests as the project takes shape.
39
+ it('has a valid project manifest', () => {
40
+ const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
41
+ expect(typeof pkg.name).toBe('string');
42
+ expect(pkg.name.length).toBeGreaterThan(0);
43
+ });
44
+ `, { dryRun, silent });
45
+ }
46
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/presets/testing.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG3D,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC;AACxC,MAAM,UAAU,sBAAsB,CAAC,GAAwB,EAAE,UAAU,GAAG,KAAK;IACjF,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC;IACnB,GAAG,CAAC,eAAe,KAAK,EAAE,CAAC;IAC3B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM;QAC1D,GAAG,CAAC,eAAe,CAAC,MAAM,GAAG,cAAc,CAAC;IAC9C,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;IACrD,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,YAAY,CAAC;IACzC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,QAAQ,CAAC;IACxE,IAAI,UAAU,EAAE,CAAC;QACf,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,iBAAiB,CAAC;QAC9C,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,kBAAkB,CAAC;YACrF,GAAG,CAAC,eAAe,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC;IACxD,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,YAAY,CAAC,GAAkB,EAAE,sBAAsB,GAAG,KAAK;IAC7E,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAC1C,MAAM,SAAS,GAAG;QAChB,kBAAkB;QAClB,kBAAkB;QAClB,mBAAmB;QACnB,mBAAmB;QACnB,mBAAmB;QACnB,mBAAmB;QACnB,GAAG,CAAC,sBAAsB;YACxB,CAAC,CAAC,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC;YAC5E,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACzD,IAAI,CAAC,SAAS;QACZ,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,EACzC,yIAAyI,EACzI,EAAE,MAAM,EAAE,MAAM,EAAE,CACnB,CAAC;IACJ,aAAa,CACX,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,EAC/C;;;;;;;;;CASH,EACG,EAAE,MAAM,EAAE,MAAM,EAAE,CACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { AIProjectConfig, PresetType } from '../config/schema.js';
2
+ export interface PresetContext {
3
+ targetDir: string;
4
+ projectName: string;
5
+ config: AIProjectConfig;
6
+ dryRun?: boolean;
7
+ silent?: boolean;
8
+ }
9
+ export interface PresetHandler {
10
+ name: PresetType;
11
+ description: string;
12
+ scaffold: (ctx: PresetContext) => Promise<void>;
13
+ }
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/presets/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/presets/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { PresetHandler } from './types.js';
2
+ export declare const webPreset: PresetHandler;
3
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/presets/web.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,aAAa,EAAE,MAAM,YAAY,CAAC;AAM1D,eAAO,MAAM,SAAS,EAAE,aAwFvB,CAAC"}
@@ -0,0 +1,84 @@
1
+ import path from 'node:path';
2
+ import { fileExists, safeWriteFile, writeJsonFile } from '../utils/fs.js';
3
+ import { readPackageManifest } from '../config/validation.js';
4
+ import { runExecutable } from '../utils/shell.js';
5
+ import { setupBrowserTesting } from '../adapters/browser.js';
6
+ import { setupAdr } from './adr.js';
7
+ import { scaffoldCommand } from '../adapters/package-manager.js';
8
+ import { addTestingDependencies, setupTesting } from './testing.js';
9
+ export const webPreset = {
10
+ name: 'web',
11
+ description: 'Framework-agnostic web project with upstream scaffolding, Vitest and optional Playwright',
12
+ async scaffold(ctx) {
13
+ const { targetDir, projectName, dryRun, silent, config } = ctx;
14
+ const framework = config.framework || 'none';
15
+ const pkgPath = path.join(targetDir, 'package.json');
16
+ const pm = config.packageManager || 'pnpm';
17
+ let pkg = readPackageManifest(targetDir);
18
+ const fresh = pkg === null;
19
+ if (fresh && framework === 'existing')
20
+ throw new Error('An existing framework requires an existing package.json.');
21
+ if (fresh && (framework === 'vite' || framework === 'next')) {
22
+ const command = scaffoldCommand(pm, framework);
23
+ const result = await runExecutable(command.executable, command.args, {
24
+ cwd: targetDir,
25
+ dryRun,
26
+ silent: true
27
+ });
28
+ if (!result.ok)
29
+ throw new Error(`${framework} scaffolding failed: ${result.stderr || result.stdout}`);
30
+ if (!dryRun) {
31
+ pkg = readPackageManifest(targetDir);
32
+ const expected = framework === 'vite' ? 'index.html' : 'src/app/page.tsx';
33
+ if (!pkg || !fileExists(path.join(targetDir, expected)))
34
+ throw new Error(`${framework} scaffolding did not create a complete project; it may have been cancelled.`);
35
+ }
36
+ }
37
+ if (!pkg) {
38
+ // In a framework dry run the upstream command has only been displayed.
39
+ if (dryRun && (framework === 'vite' || framework === 'next'))
40
+ return;
41
+ pkg = {
42
+ name: projectName,
43
+ version: '0.1.0',
44
+ type: 'module',
45
+ scripts: { build: 'tsc', typecheck: 'tsc --noEmit' },
46
+ devDependencies: { '@types/node': '^22.8.0', typescript: '^5.6.3' }
47
+ };
48
+ }
49
+ const hadVitestScript = Object.values(pkg.scripts || {}).some((script) => typeof script === 'string' && /^vitest(?:\s|$)/.test(script));
50
+ addTestingDependencies(pkg, config.browser.playwright);
51
+ if (fileExists(path.join(targetDir, 'tsconfig.json'))) {
52
+ pkg.scripts.typecheck ??=
53
+ fresh && framework === 'next' ? 'next typegen && tsc --noEmit' : 'tsc --noEmit';
54
+ if (!pkg.dependencies?.typescript && !pkg.devDependencies.typescript)
55
+ pkg.devDependencies.typescript = '^5.6.3';
56
+ }
57
+ // Only scaffold application source and compiler settings for a fresh agnostic project.
58
+ if (fresh && framework === 'none') {
59
+ writeJsonFile(path.join(targetDir, 'tsconfig.json'), {
60
+ compilerOptions: {
61
+ target: 'ES2022',
62
+ module: 'NodeNext',
63
+ moduleResolution: 'NodeNext',
64
+ lib: ['ES2022', 'DOM'],
65
+ strict: true,
66
+ skipLibCheck: true,
67
+ outDir: 'dist',
68
+ rootDir: 'src'
69
+ },
70
+ include: ['src/**/*']
71
+ }, { dryRun, silent });
72
+ safeWriteFile(path.join(targetDir, 'src', 'index.ts'), `export function createApp() {\n return { name: ${JSON.stringify(projectName)}, status: 'ready' };\n}\n`, { dryRun, silent });
73
+ }
74
+ writeJsonFile(pkgPath, pkg, { overwrite: true, dryRun, silent });
75
+ if (pm === 'pnpm')
76
+ safeWriteFile(path.join(targetDir, 'pnpm-workspace.yaml'), 'allowBuilds:\n esbuild: true\n', { dryRun, silent });
77
+ setupTesting(ctx, hadVitestScript);
78
+ if (config.browser.playwright)
79
+ setupBrowserTesting(targetDir, { dryRun, silent });
80
+ if (config.docs.adr)
81
+ setupAdr(targetDir, { dryRun, silent });
82
+ }
83
+ };
84
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/presets/web.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface WriteFileOptions {
2
+ overwrite?: boolean;
3
+ dryRun?: boolean;
4
+ silent?: boolean;
5
+ mode?: number;
6
+ }
7
+ export declare function ensureDir(dirPath: string, dryRun?: boolean): void;
8
+ export declare function fileExists(filePath: string): boolean;
9
+ export declare function safeWriteFile(filePath: string, content: string, options?: WriteFileOptions): boolean;
10
+ export declare function readTextFile(filePath: string): string | null;
11
+ export declare function readJsonFile<T>(filePath: string): T | null;
12
+ export declare function writeJsonFile(filePath: string, data: unknown, options?: WriteFileOptions): boolean;
13
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,IAAI,CAQ/D;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAyBT;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAQ1D;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAGT"}
@@ -0,0 +1,60 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { logger } from './logger.js';
4
+ export function ensureDir(dirPath, dryRun = false) {
5
+ if (dryRun) {
6
+ logger.dim(`[dry-run] Would create directory: ${dirPath}`);
7
+ return;
8
+ }
9
+ if (!fs.existsSync(dirPath)) {
10
+ fs.mkdirSync(dirPath, { recursive: true });
11
+ }
12
+ }
13
+ export function fileExists(filePath) {
14
+ return fs.existsSync(filePath);
15
+ }
16
+ export function safeWriteFile(filePath, content, options = {}) {
17
+ const { overwrite = false, dryRun = false, silent = false, mode } = options;
18
+ if (fileExists(filePath) && !overwrite) {
19
+ if (!silent) {
20
+ logger.dim(`Skipping existing file: ${path.basename(filePath)}`);
21
+ }
22
+ return false;
23
+ }
24
+ if (dryRun) {
25
+ logger.dim(`[dry-run] Would write file: ${filePath}`);
26
+ return true;
27
+ }
28
+ ensureDir(path.dirname(filePath), false);
29
+ fs.writeFileSync(filePath, content, { encoding: 'utf-8', mode });
30
+ if (mode !== undefined && process.platform !== 'win32') {
31
+ try {
32
+ fs.chmodSync(filePath, mode);
33
+ }
34
+ catch {
35
+ // ignore in environments that do not permit chmod
36
+ }
37
+ }
38
+ return true;
39
+ }
40
+ export function readTextFile(filePath) {
41
+ if (!fs.existsSync(filePath))
42
+ return null;
43
+ return fs.readFileSync(filePath, 'utf-8');
44
+ }
45
+ export function readJsonFile(filePath) {
46
+ const text = readTextFile(filePath);
47
+ if (!text)
48
+ return null;
49
+ try {
50
+ return JSON.parse(text);
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ export function writeJsonFile(filePath, data, options = {}) {
57
+ const content = JSON.stringify(data, null, 2) + '\n';
58
+ return safeWriteFile(filePath, content, options);
59
+ }
60
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AASrC,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,MAAM,GAAG,KAAK;IACvD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,GAAG,CAAC,qCAAqC,OAAO,EAAE,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,OAAe,EACf,UAA4B,EAAE;IAE9B,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAE5E,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,GAAG,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;IACzC,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,kDAAkD;QACpD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,YAAY,CAAI,QAAgB;IAC9C,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,IAAa,EACb,UAA4B,EAAE;IAE9B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACrD,OAAO,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare const logger: {
2
+ info: (msg: string) => void;
3
+ success: (msg: string) => void;
4
+ warn: (msg: string) => void;
5
+ error: (msg: string) => void;
6
+ dim: (msg: string) => void;
7
+ step: (step: number, total: number, msg: string) => void;
8
+ banner: (title: string, subtitle?: string) => void;
9
+ };
10
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;gBACL,MAAM;mBACH,MAAM;gBACT,MAAM;iBACL,MAAM;eACR,MAAM;iBACJ,MAAM,SAAS,MAAM,OAAO,MAAM;oBAG/B,MAAM,aAAa,MAAM;CAQ1C,CAAC"}
@@ -0,0 +1,20 @@
1
+ import pc from 'picocolors';
2
+ export const logger = {
3
+ info: (msg) => console.log(pc.cyan('ℹ ') + msg),
4
+ success: (msg) => console.log(pc.green('✓ ') + msg),
5
+ warn: (msg) => console.log(pc.yellow('⚠ ') + msg),
6
+ error: (msg) => console.error(pc.red('✖ ') + msg),
7
+ dim: (msg) => console.log(pc.dim(msg)),
8
+ step: (step, total, msg) => {
9
+ console.log(pc.bold(pc.magenta(`[${step}/${total}] `)) + pc.bold(msg));
10
+ },
11
+ banner: (title, subtitle) => {
12
+ console.log();
13
+ console.log(pc.bold(pc.cyan(title)));
14
+ if (subtitle) {
15
+ console.log(pc.dim(subtitle));
16
+ }
17
+ console.log();
18
+ }
19
+ };
20
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IACvD,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IAC3D,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IACzD,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IACzD,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,EAAE,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW,EAAE,EAAE;QACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,EAAE,CAAC,KAAa,EAAE,QAAiB,EAAE,EAAE;QAC3C,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;CACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface ShellResult {
2
+ stdout: string;
3
+ stderr: string;
4
+ exitCode: number;
5
+ ok: boolean;
6
+ }
7
+ export interface RunOptions {
8
+ cwd?: string;
9
+ env?: NodeJS.ProcessEnv;
10
+ dryRun?: boolean;
11
+ silent?: boolean;
12
+ timeout?: number;
13
+ }
14
+ /** Execute a program with literal arguments. No shell expansion or interpolation. */
15
+ export declare function runExecutable(executable: string, args?: string[], options?: RunOptions): Promise<ShellResult>;
16
+ export declare function commandExists(binName: string): Promise<boolean>;
17
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4BD,qFAAqF;AACrF,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,WAAW,CAAC,CAmCtB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAwBrE"}