anhedral 0.4.2 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -265
- package/assets/anhedral-cli-init-technical.svg +322 -0
- package/assets/anhedral-cli-init.svg +257 -173
- package/dist/bin.js +28 -191
- package/dist/dependencies.d.ts +7 -57
- package/dist/dependencies.js +96 -308
- package/dist/index.d.ts +2 -7
- package/dist/index.js +1 -4
- package/dist/platforms/desktop.js +401 -0
- package/dist/platforms/extension.js +401 -0
- package/dist/platforms/mobile.js +232 -0
- package/dist/project.d.ts +0 -26
- package/dist/standard-products.d.ts +2 -0
- package/dist/standard-products.js +6 -0
- package/dist/standard.d.ts +18 -0
- package/dist/standard.js +595 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/application-stack-standard.md +700 -0
- package/package.json +29 -51
- package/CHANGELOG.md +0 -178
- package/CONTRIBUTING.md +0 -77
- package/SECURITY.md +0 -37
- package/SKILL.md +0 -339
- package/assets/images/svg/ably-symbol-color.svg +0 -8
- package/bin/anhedral.js +0 -2
- package/dist/architecture/contributions.d.ts +0 -28
- package/dist/architecture/contributions.js +0 -125
- package/dist/architecture/index.d.ts +0 -12
- package/dist/architecture/index.js +0 -6
- package/dist/architecture/manifest.d.ts +0 -53
- package/dist/architecture/manifest.js +0 -283
- package/dist/architecture/modules.d.ts +0 -41
- package/dist/architecture/modules.js +0 -187
- package/dist/architecture/plan.d.ts +0 -58
- package/dist/architecture/plan.js +0 -145
- package/dist/architecture/templates.d.ts +0 -10
- package/dist/architecture/templates.js +0 -23
- package/dist/cli.d.ts +0 -32
- package/dist/cli.js +0 -281
- package/dist/composers/root.d.ts +0 -6
- package/dist/composers/root.js +0 -35
- package/dist/print.d.ts +0 -8
- package/dist/print.js +0 -48
- package/dist/prompts.d.ts +0 -6
- package/dist/prompts.js +0 -41
- package/dist/scaffold.d.ts +0 -64
- package/dist/scaffold.js +0 -2102
- package/dist/template-source.d.ts +0 -20
- package/dist/template-source.js +0 -180
- package/dist/templates/api.d.ts +0 -2
- package/dist/templates/api.js +0 -3187
- package/dist/templates/assets-private-proxy.d.ts +0 -3
- package/dist/templates/assets-private-proxy.js +0 -277
- package/dist/templates/desktop.js +0 -792
- package/dist/templates/electron-updater.d.ts +0 -3
- package/dist/templates/electron-updater.js +0 -358
- package/dist/templates/extension.js +0 -856
- package/dist/templates/first-run.d.ts +0 -2
- package/dist/templates/first-run.js +0 -167
- package/dist/templates/mobile.js +0 -861
- package/dist/templates/shared.d.ts +0 -2
- package/dist/templates/shared.js +0 -577
- package/dist/templates/web.d.ts +0 -2
- package/dist/templates/web.js +0 -569
- package/dist/toolchain.d.ts +0 -3
- package/dist/toolchain.js +0 -8
- package/dist/ui.d.ts +0 -33
- package/dist/ui.js +0 -199
- package/dist/workspace-config.d.ts +0 -11
- package/dist/workspace-config.js +0 -372
- package/docs/NORTHSTAR.md +0 -114
- package/docs/conventions.md +0 -94
- package/docs/engineering-principles.md +0 -88
- package/docs/master-stack-map.md +0 -199
- package/docs/output-tree-contract.md +0 -493
- package/docs/references/manual-scaffolding.md +0 -421
- package/docs/references/provisioning.md +0 -577
- package/scripts/render-master-stack-map.mjs +0 -510
- package/templates/api-fastify/apps/api/tsconfig.json +0 -20
- package/templates/catalog.json +0 -23
- package/templates/db-drizzle/packages/db/tsconfig.json +0 -14
- package/templates/desktop-electron/apps/desktop/tsconfig.json +0 -37
- package/templates/extension-wxt/apps/extension/tsconfig.json +0 -41
- package/templates/mobile-expo/apps/mobile/expo-env.d.ts +0 -1
- package/templates/web-next/apps/web/next-env.d.ts +0 -6
- /package/dist/{templates → platforms}/desktop.d.ts +0 -0
- /package/dist/{templates → platforms}/extension.d.ts +0 -0
- /package/dist/{templates → platforms}/mobile.d.ts +0 -0
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
function environmentFiles(options) {
|
|
2
|
-
return [
|
|
3
|
-
options.apps.api ? {
|
|
4
|
-
example: 'apps/api/.env.example',
|
|
5
|
-
target: 'apps/api/.env',
|
|
6
|
-
optional: options.features.storage ? ['CLOUDFLARE_API_TOKEN'] : [],
|
|
7
|
-
} : null,
|
|
8
|
-
options.features.database ? {
|
|
9
|
-
example: 'packages/db/.env.example',
|
|
10
|
-
target: 'packages/db/.env',
|
|
11
|
-
optional: [],
|
|
12
|
-
} : null,
|
|
13
|
-
options.apps.web ? {
|
|
14
|
-
example: 'apps/web/.env.example',
|
|
15
|
-
target: 'apps/web/.env.local',
|
|
16
|
-
optional: [],
|
|
17
|
-
} : null,
|
|
18
|
-
options.apps.mobile ? {
|
|
19
|
-
example: 'apps/mobile/.env.example',
|
|
20
|
-
target: 'apps/mobile/.env',
|
|
21
|
-
optional: [],
|
|
22
|
-
} : null,
|
|
23
|
-
options.apps.desktop ? {
|
|
24
|
-
example: 'apps/desktop/.env.example',
|
|
25
|
-
target: 'apps/desktop/.env',
|
|
26
|
-
optional: [],
|
|
27
|
-
} : null,
|
|
28
|
-
options.features.electronUpdater ? {
|
|
29
|
-
example: 'apps/desktop/electron-builder.env.example',
|
|
30
|
-
target: 'apps/desktop/electron-builder.env',
|
|
31
|
-
optional: [],
|
|
32
|
-
} : null,
|
|
33
|
-
options.apps.extension ? {
|
|
34
|
-
example: 'apps/extension/.env.example',
|
|
35
|
-
target: 'apps/extension/.env',
|
|
36
|
-
optional: [
|
|
37
|
-
...(options.features.auth ? ['VITE_CLERK_SYNC_HOST'] : []),
|
|
38
|
-
'VITE_CRX_PUBLIC_KEY',
|
|
39
|
-
],
|
|
40
|
-
} : null,
|
|
41
|
-
].filter((entry) => entry !== null);
|
|
42
|
-
}
|
|
43
|
-
function nextCommands(options) {
|
|
44
|
-
return [
|
|
45
|
-
'pnpm ready',
|
|
46
|
-
options.features.database ? 'pnpm db:generate' : null,
|
|
47
|
-
options.features.database ? 'git add packages/db/migrations' : null,
|
|
48
|
-
'pnpm verify',
|
|
49
|
-
options.features.database ? 'pnpm db:migrate' : null,
|
|
50
|
-
'pnpm dev',
|
|
51
|
-
].filter((entry) => entry !== null);
|
|
52
|
-
}
|
|
53
|
-
export function generatedFirstRunScript(options) {
|
|
54
|
-
return `import { copyFileSync, existsSync, readFileSync } from 'node:fs';
|
|
55
|
-
|
|
56
|
-
const environmentFiles = ${JSON.stringify(environmentFiles(options), null, 2)};
|
|
57
|
-
const args = new Set(process.argv.slice(2));
|
|
58
|
-
const supportedArgs = new Set(['--check', '--json']);
|
|
59
|
-
const unknownArgs = [...args].filter((arg) => !supportedArgs.has(arg));
|
|
60
|
-
if (unknownArgs.length > 0) {
|
|
61
|
-
console.error(\`Unknown first-run option: \${unknownArgs[0]}. Use --check and/or --json.\`);
|
|
62
|
-
process.exit(2);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const checkOnly = args.has('--check');
|
|
66
|
-
const json = args.has('--json');
|
|
67
|
-
const created = [];
|
|
68
|
-
const kept = [];
|
|
69
|
-
const missing = [];
|
|
70
|
-
const unresolved = [];
|
|
71
|
-
|
|
72
|
-
function unquote(value) {
|
|
73
|
-
const trimmed = value.trim();
|
|
74
|
-
if (trimmed.length >= 2) {
|
|
75
|
-
const first = trimmed[0];
|
|
76
|
-
const last = trimmed[trimmed.length - 1];
|
|
77
|
-
if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
|
|
78
|
-
return trimmed.slice(1, -1).trim();
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return trimmed;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function isPlaceholder(value) {
|
|
85
|
-
const normalized = unquote(value).toLowerCase();
|
|
86
|
-
return normalized.includes('***')
|
|
87
|
-
|| normalized.includes('your_')
|
|
88
|
-
|| normalized.includes('your-')
|
|
89
|
-
|| normalized.includes('example.com')
|
|
90
|
-
|| /^(?:change|replace)(?:[-_ ]?me)?(?:[-_ ].*)?$/.test(normalized)
|
|
91
|
-
|| /^(?:placeholder|your value|your-value|your_value)$/.test(normalized);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function environmentValues(source) {
|
|
95
|
-
const values = new Map();
|
|
96
|
-
for (const line of source.split(/\\r?\\n/)) {
|
|
97
|
-
const match = /^(?:export\\s+)?([A-Z][A-Z0-9_]*)=(.*)$/.exec(line.trim());
|
|
98
|
-
if (match) values.set(match[1], unquote(match[2]));
|
|
99
|
-
}
|
|
100
|
-
return values;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
for (const { example, target, optional } of environmentFiles) {
|
|
104
|
-
if (!existsSync(target)) {
|
|
105
|
-
if (checkOnly) {
|
|
106
|
-
missing.push(target);
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
copyFileSync(example, target);
|
|
110
|
-
created.push(target);
|
|
111
|
-
} else {
|
|
112
|
-
kept.push(target);
|
|
113
|
-
}
|
|
114
|
-
const optionalNames = new Set(optional);
|
|
115
|
-
const expected = environmentValues(readFileSync(example, 'utf8'));
|
|
116
|
-
const actual = environmentValues(readFileSync(target, 'utf8'));
|
|
117
|
-
for (const name of expected.keys()) {
|
|
118
|
-
if (!optionalNames.has(name)) {
|
|
119
|
-
const value = actual.get(name);
|
|
120
|
-
if (value === undefined || !value || isPlaceholder(value)) {
|
|
121
|
-
unresolved.push(\`\${target}: \${name}\`);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const blockers = [
|
|
128
|
-
...missing.map((target) => \`\${target}: file is missing\`),
|
|
129
|
-
...unresolved,
|
|
130
|
-
];
|
|
131
|
-
const result = {
|
|
132
|
-
operation: checkOnly ? 'ready' : 'first-run',
|
|
133
|
-
ok: blockers.length === 0,
|
|
134
|
-
created,
|
|
135
|
-
kept,
|
|
136
|
-
missing,
|
|
137
|
-
unresolved,
|
|
138
|
-
nextCommands: ${JSON.stringify(nextCommands(options))},
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
if (json) {
|
|
142
|
-
console.log(JSON.stringify(result, null, 2));
|
|
143
|
-
} else {
|
|
144
|
-
for (const target of created) console.log(\`created \${target}\`);
|
|
145
|
-
for (const target of kept) console.log(\`kept \${target}\`);
|
|
146
|
-
|
|
147
|
-
if (blockers.length > 0) {
|
|
148
|
-
console.log('\\nConfiguration is not ready:');
|
|
149
|
-
for (const item of blockers) console.log(\` - \${item}\`);
|
|
150
|
-
console.log(checkOnly
|
|
151
|
-
? '\\nRun pnpm first-run to create missing files, configure the listed values, then run pnpm ready again.'
|
|
152
|
-
: '\\nConfigure the listed values, then run pnpm ready.');
|
|
153
|
-
} else {
|
|
154
|
-
console.log('\\nConfiguration is ready.');
|
|
155
|
-
${options.features.database
|
|
156
|
-
? "console.log('Before verification, review the SQL created by pnpm db:generate before staging it.');"
|
|
157
|
-
: ''}
|
|
158
|
-
console.log('\\nNext:');
|
|
159
|
-
for (const command of result.nextCommands.filter((command) => command !== 'pnpm ready')) {
|
|
160
|
-
console.log(\` \${command}\`);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (checkOnly && blockers.length > 0) process.exitCode = 1;
|
|
166
|
-
`;
|
|
167
|
-
}
|