anhedral 0.1.10 → 0.4.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/CHANGELOG.md +119 -0
- package/CONTRIBUTING.md +73 -0
- package/LICENSE +196 -17
- package/README.md +202 -145
- package/SECURITY.md +37 -0
- package/SKILL.md +244 -0
- package/bin/anhedral.js +1 -1
- package/dist/architecture/contributions.d.ts +28 -0
- package/dist/architecture/contributions.js +125 -0
- package/dist/architecture/index.d.ts +12 -0
- package/dist/architecture/index.js +6 -0
- package/dist/architecture/manifest.d.ts +53 -0
- package/dist/architecture/manifest.js +283 -0
- package/dist/architecture/modules.d.ts +37 -0
- package/dist/architecture/modules.js +184 -0
- package/dist/architecture/plan.d.ts +58 -0
- package/dist/architecture/plan.js +145 -0
- package/dist/architecture/templates.d.ts +10 -0
- package/dist/architecture/templates.js +23 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +179 -0
- package/dist/cli.d.ts +24 -2
- package/dist/cli.js +189 -21
- package/dist/composers/root.d.ts +6 -0
- package/dist/composers/root.js +35 -0
- package/dist/dependencies.d.ts +31 -9
- package/dist/dependencies.js +227 -60
- package/dist/index.d.ts +8 -2
- package/dist/index.js +5 -31
- package/dist/print.js +15 -0
- package/dist/prompts.d.ts +5 -0
- package/dist/prompts.js +19 -0
- package/dist/render.d.ts +11 -0
- package/dist/render.js +74 -0
- package/dist/scaffold.d.ts +64 -12
- package/dist/scaffold.js +1726 -1150
- package/dist/template-source.d.ts +20 -0
- package/dist/template-source.js +180 -0
- package/dist/templates/api.d.ts +2 -0
- package/dist/templates/api.js +3122 -0
- package/dist/templates/assets-private-proxy.d.ts +3 -0
- package/dist/templates/assets-private-proxy.js +277 -0
- package/dist/templates/desktop.d.ts +2 -0
- package/dist/templates/desktop.js +639 -0
- package/dist/templates/electron-updater.d.ts +3 -0
- package/dist/templates/electron-updater.js +358 -0
- package/dist/templates/extension.d.ts +1 -1
- package/dist/templates/extension.js +322 -248
- package/dist/templates/mobile.d.ts +2 -0
- package/dist/templates/mobile.js +720 -0
- package/dist/templates/shared.d.ts +2 -0
- package/dist/templates/shared.js +520 -0
- package/dist/templates/web.d.ts +2 -0
- package/dist/templates/web.js +412 -0
- package/dist/toolchain.d.ts +0 -8
- package/dist/toolchain.js +0 -21
- package/dist/transaction.d.ts +22 -0
- package/dist/transaction.js +822 -0
- package/dist/ui.d.ts +33 -0
- package/dist/ui.js +199 -0
- package/dist/util.d.ts +1 -5
- package/dist/util.js +70 -159
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/dist/workspace-config.d.ts +11 -0
- package/dist/workspace-config.js +372 -0
- package/docs/conventions.md +92 -0
- package/docs/master-stack-map.md +192 -0
- package/docs/output-tree-contract.md +482 -0
- package/docs/references/manual-scaffolding.md +403 -0
- package/docs/references/provisioning.md +220 -0
- package/package.json +57 -13
- package/templates/api-fastify/apps/api/tsconfig.json +20 -0
- package/templates/catalog.json +23 -0
- package/templates/db-drizzle/packages/db/tsconfig.json +14 -0
- package/templates/desktop-electron/apps/desktop/tsconfig.json +37 -0
- package/templates/extension-wxt/apps/extension/tsconfig.json +41 -0
- package/templates/mobile-expo/apps/mobile/expo-env.d.ts +1 -0
- package/templates/web-next/apps/web/next-env.d.ts +6 -0
- package/dist/branding.d.ts +0 -5
- package/dist/branding.js +0 -17
- package/dist/commands.d.ts +0 -7
- package/dist/commands.js +0 -24
- package/dist/templates/backend.d.ts +0 -2
- package/dist/templates/backend.js +0 -2115
- package/dist/templates/frontend.d.ts +0 -2
- package/dist/templates/frontend.js +0 -1268
package/dist/render.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
const PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
|
|
3
|
+
const MAX_PACKAGE_NAME_LENGTH = 214;
|
|
4
|
+
const RESERVED_PACKAGE_NAMES = new Set(['node_modules', 'favicon.ico']);
|
|
5
|
+
/** Serialize an arbitrary value as a JavaScript/TypeScript string literal. */
|
|
6
|
+
export function jsString(value) {
|
|
7
|
+
return JSON.stringify(value);
|
|
8
|
+
}
|
|
9
|
+
/** Escape text placed directly in HTML rather than in a JS string. */
|
|
10
|
+
export function htmlText(value) {
|
|
11
|
+
return value
|
|
12
|
+
.replace(/&/g, '&')
|
|
13
|
+
.replace(/</g, '<')
|
|
14
|
+
.replace(/>/g, '>')
|
|
15
|
+
.replace(/"/g, '"')
|
|
16
|
+
.replace(/'/g, ''');
|
|
17
|
+
}
|
|
18
|
+
/** Keep generated Markdown headings on one line and prevent heading/code injection. */
|
|
19
|
+
export function markdownHeading(value) {
|
|
20
|
+
const normalized = value.replace(/[\r\n]+/g, ' ').trim() || 'Anhedral App';
|
|
21
|
+
return normalized.replace(/([\\`*_{}\[\]()<>#+.!|~-])/g, '\\$1');
|
|
22
|
+
}
|
|
23
|
+
export function assertPackageName(value) {
|
|
24
|
+
const leafName = value.slice(value.lastIndexOf('/') + 1);
|
|
25
|
+
if (value.length > MAX_PACKAGE_NAME_LENGTH
|
|
26
|
+
|| !PACKAGE_NAME_PATTERN.test(value)
|
|
27
|
+
|| RESERVED_PACKAGE_NAMES.has(leafName)) {
|
|
28
|
+
throw new Error(`Invalid package name: ${value}`);
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
function compactPackageSegment(value, maximumLength) {
|
|
33
|
+
if (value.length <= maximumLength)
|
|
34
|
+
return value;
|
|
35
|
+
if (maximumLength <= 9)
|
|
36
|
+
return value.slice(0, maximumLength).replace(/[._-]+$/g, '') || 'a';
|
|
37
|
+
const digest = createHash('sha256').update(value, 'utf8').digest('hex').slice(0, 8);
|
|
38
|
+
const prefix = value.slice(0, maximumLength - digest.length - 1).replace(/[._-]+$/g, '') || 'app';
|
|
39
|
+
return `${prefix}-${digest}`;
|
|
40
|
+
}
|
|
41
|
+
/** Derive a valid, deterministic unscoped npm package name from arbitrary text. */
|
|
42
|
+
export function packageNameFromText(value) {
|
|
43
|
+
let normalized = value
|
|
44
|
+
.normalize('NFKD')
|
|
45
|
+
.replace(/\p{Mark}+/gu, '')
|
|
46
|
+
.trim()
|
|
47
|
+
.toLowerCase()
|
|
48
|
+
.replace(/[^a-z0-9._-]+/g, '-')
|
|
49
|
+
.replace(/^[._-]+|[._-]+$/g, '');
|
|
50
|
+
if (!normalized)
|
|
51
|
+
normalized = 'anhedral-app';
|
|
52
|
+
if (RESERVED_PACKAGE_NAMES.has(normalized))
|
|
53
|
+
normalized = `anhedral-${normalized}`;
|
|
54
|
+
return assertPackageName(compactPackageSegment(normalized, MAX_PACKAGE_NAME_LENGTH));
|
|
55
|
+
}
|
|
56
|
+
export function childPackageName(projectName, suffix) {
|
|
57
|
+
assertPackageName(projectName);
|
|
58
|
+
const normalizedSuffix = packageNameFromText(suffix);
|
|
59
|
+
const separator = projectName.lastIndexOf('/');
|
|
60
|
+
if (separator >= 0) {
|
|
61
|
+
const scope = projectName.slice(0, separator + 1);
|
|
62
|
+
const leaf = compactPackageSegment(`${projectName.slice(separator + 1)}-${normalizedSuffix}`, MAX_PACKAGE_NAME_LENGTH - scope.length);
|
|
63
|
+
return assertPackageName(`${scope}${leaf}`);
|
|
64
|
+
}
|
|
65
|
+
return assertPackageName(compactPackageSegment(`${projectName}-${normalizedSuffix}`, MAX_PACKAGE_NAME_LENGTH));
|
|
66
|
+
}
|
|
67
|
+
export function identifierSegment(value) {
|
|
68
|
+
const segment = value
|
|
69
|
+
.normalize('NFKD')
|
|
70
|
+
.toLowerCase()
|
|
71
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
72
|
+
.replace(/^-+|-+$/g, '');
|
|
73
|
+
return segment || 'app';
|
|
74
|
+
}
|
package/dist/scaffold.d.ts
CHANGED
|
@@ -1,24 +1,76 @@
|
|
|
1
1
|
import { type ToolchainChannel } from './toolchain.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export type
|
|
2
|
+
import { type ModuleId } from './architecture/index.js';
|
|
3
|
+
import { type NativeStylingLibrary, type UiTarget } from './ui.js';
|
|
4
|
+
export type AppSelections = {
|
|
5
|
+
web: boolean;
|
|
6
|
+
mobile: boolean;
|
|
7
|
+
api: boolean;
|
|
8
|
+
desktop: boolean;
|
|
9
|
+
extension: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type FeatureSelections = {
|
|
12
|
+
database: boolean;
|
|
13
|
+
auth: boolean;
|
|
14
|
+
billing: boolean;
|
|
15
|
+
storage: boolean;
|
|
16
|
+
nativeSubscriptions: boolean;
|
|
17
|
+
electronUpdater: boolean;
|
|
18
|
+
};
|
|
5
19
|
export interface InitOptions {
|
|
6
20
|
projectName: string;
|
|
7
21
|
displayName: string;
|
|
8
|
-
|
|
9
|
-
payments: PaymentsMode;
|
|
10
|
-
db: 'neon';
|
|
11
|
-
orm: 'drizzle';
|
|
12
|
-
storage: 'r2';
|
|
13
|
-
api: 'fastify';
|
|
22
|
+
modules: ModuleId[];
|
|
14
23
|
skipInstall: boolean;
|
|
24
|
+
dryRun: boolean;
|
|
25
|
+
json: boolean;
|
|
15
26
|
toolchainChannel: ToolchainChannel;
|
|
27
|
+
uiComponents?: string[];
|
|
28
|
+
nativeStyling?: NativeStylingLibrary;
|
|
29
|
+
/** Destination root. Omit to scaffold the current working directory. */
|
|
30
|
+
rootDirectory?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface AddOptions {
|
|
33
|
+
modules: ModuleId[];
|
|
34
|
+
skipInstall: boolean;
|
|
35
|
+
dryRun: boolean;
|
|
36
|
+
json: boolean;
|
|
37
|
+
toolchainChannel?: ToolchainChannel;
|
|
38
|
+
}
|
|
39
|
+
export interface UiAddOptions {
|
|
40
|
+
components: string[];
|
|
41
|
+
targets: UiTarget[];
|
|
42
|
+
skipInstall: boolean;
|
|
43
|
+
dryRun: boolean;
|
|
44
|
+
json: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface UpgradeOptions {
|
|
47
|
+
skipInstall: boolean;
|
|
48
|
+
dryRun: boolean;
|
|
49
|
+
json: boolean;
|
|
16
50
|
}
|
|
17
51
|
export interface ProjectOptions {
|
|
18
52
|
projectName: string;
|
|
19
53
|
displayName: string;
|
|
20
|
-
|
|
21
|
-
|
|
54
|
+
apps: AppSelections;
|
|
55
|
+
features: FeatureSelections;
|
|
22
56
|
skipInstall?: boolean;
|
|
57
|
+
nativeStyling?: NativeStylingLibrary;
|
|
23
58
|
}
|
|
24
|
-
export declare function
|
|
59
|
+
export declare function supportsMobileInstallNode(version: string): boolean;
|
|
60
|
+
export type DoctorIssue = {
|
|
61
|
+
path: string;
|
|
62
|
+
severity: 'error' | 'warning';
|
|
63
|
+
message: string;
|
|
64
|
+
};
|
|
65
|
+
export type DoctorReport = {
|
|
66
|
+
ok: boolean;
|
|
67
|
+
schemaVersion: number;
|
|
68
|
+
generatorVersion: string;
|
|
69
|
+
issues: DoctorIssue[];
|
|
70
|
+
};
|
|
71
|
+
export declare function isSupportedProjectUpgrade(fromVersion: string, toVersion: string): boolean;
|
|
72
|
+
export declare function scaffoldProject(inputOptions: InitOptions): Promise<void>;
|
|
73
|
+
export declare function scaffoldUiComponents(uiOptions: UiAddOptions): Promise<void>;
|
|
74
|
+
export declare function scaffoldUpgradeProject(upgradeOptions: UpgradeOptions): Promise<void>;
|
|
75
|
+
export declare function scaffoldAddModules(addOptions: AddOptions): Promise<void>;
|
|
76
|
+
export declare function doctorProject(): DoctorReport;
|