@bleedingdev/modern-js-create 3.2.0-ultramodern.0 → 3.2.0-ultramodern.10
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 +12 -0
- package/dist/index.js +252 -49
- package/dist/types/locale/index.d.ts +2 -111
- package/package.json +5 -2
- package/template/.agents/skills-lock.json +34 -0
- package/template/AGENTS.md +20 -0
- package/template/README.md +6 -5
- package/template/api/effect/index.ts.handlebars +7 -45
- package/template/api/lambda/hello.ts.handlebars +1 -1
- package/template/modern.config.ts.handlebars +21 -25
- package/template/oxfmt.config.ts +8 -0
- package/template/oxlint.config.ts +12 -0
- package/template/package.json.handlebars +41 -26
- package/template/scripts/bootstrap-agent-skills.mjs +95 -0
- package/template/scripts/validate-ultramodern.mjs.handlebars +81 -17
- package/template/shared/effect/api.ts.handlebars +1 -2
- package/template/src/modern.runtime.ts.handlebars +2 -4
- package/template/src/routes/index.css.handlebars +14 -3
- package/template/src/routes/page.tsx.handlebars +35 -18
- package/template/tsconfig.json +106 -2
- package/template-workspace/.agents/rstackjs-agent-skills-LICENSE +21 -0
- package/template-workspace/.agents/skills/rsbuild-best-practices/SKILL.md +57 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/SKILL.md +96 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/command-map.md +113 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/common-analysis-patterns.md +190 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +88 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +138 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +71 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor.md +39 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +103 -0
- package/template-workspace/.agents/skills/rslib-best-practices/SKILL.md +58 -0
- package/template-workspace/.agents/skills/rslib-modern-package/SKILL.md +173 -0
- package/template-workspace/.agents/skills/rspack-best-practices/SKILL.md +70 -0
- package/template-workspace/.agents/skills/rspack-tracing/SKILL.md +75 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/bottlenecks.md +47 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/tracing-guide.md +38 -0
- package/template-workspace/.agents/skills/rspack-tracing/scripts/analyze_trace.js +184 -0
- package/template-workspace/.agents/skills/rstest-best-practices/SKILL.md +133 -0
- package/template-workspace/.agents/skills-lock.json +95 -0
- package/template-workspace/AGENTS.md +45 -0
- package/template-workspace/README.md.handlebars +8 -7
- package/template-workspace/oxfmt.config.ts +7 -0
- package/template-workspace/oxlint.config.ts +12 -0
- package/template-workspace/pnpm-workspace.yaml +12 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +106 -0
- package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +127 -0
- package/template/biome.json +0 -41
|
@@ -1,112 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
declare const
|
|
3
|
-
declare const localeKeys: {
|
|
4
|
-
prompt: {
|
|
5
|
-
projectName: string;
|
|
6
|
-
};
|
|
7
|
-
error: {
|
|
8
|
-
projectNameEmpty: string;
|
|
9
|
-
directoryExists: string;
|
|
10
|
-
invalidRouter: string;
|
|
11
|
-
invalidBffRuntime: string;
|
|
12
|
-
createFailed: string;
|
|
13
|
-
};
|
|
14
|
-
message: {
|
|
15
|
-
welcome: string;
|
|
16
|
-
success: string;
|
|
17
|
-
nextSteps: string;
|
|
18
|
-
step1: string;
|
|
19
|
-
step2: string;
|
|
20
|
-
step3: string;
|
|
21
|
-
};
|
|
22
|
-
help: {
|
|
23
|
-
title: string;
|
|
24
|
-
description: string;
|
|
25
|
-
usage: string;
|
|
26
|
-
usageExample: string;
|
|
27
|
-
options: string;
|
|
28
|
-
optionHelp: string;
|
|
29
|
-
optionVersion: string;
|
|
30
|
-
optionLang: string;
|
|
31
|
-
optionRouter: string;
|
|
32
|
-
optionBff: string;
|
|
33
|
-
optionBffRuntime: string;
|
|
34
|
-
optionTailwind: string;
|
|
35
|
-
optionWorkspace: string;
|
|
36
|
-
optionUltramodernWorkspace: string;
|
|
37
|
-
optionUltramodernPackageSource: string;
|
|
38
|
-
optionUltramodernPackageScope: string;
|
|
39
|
-
optionUltramodernPackageNamePrefix: string;
|
|
40
|
-
optionSub: string;
|
|
41
|
-
examples: string;
|
|
42
|
-
example1: string;
|
|
43
|
-
example2: string;
|
|
44
|
-
example3: string;
|
|
45
|
-
example4: string;
|
|
46
|
-
example5: string;
|
|
47
|
-
example6: string;
|
|
48
|
-
example7: string;
|
|
49
|
-
example8: string;
|
|
50
|
-
example9: string;
|
|
51
|
-
example10: string;
|
|
52
|
-
moreInfo: string;
|
|
53
|
-
};
|
|
54
|
-
version: {
|
|
55
|
-
message: string;
|
|
56
|
-
};
|
|
57
|
-
} | {
|
|
58
|
-
prompt: {
|
|
59
|
-
projectName: string;
|
|
60
|
-
};
|
|
61
|
-
error: {
|
|
62
|
-
projectNameEmpty: string;
|
|
63
|
-
directoryExists: string;
|
|
64
|
-
invalidRouter: string;
|
|
65
|
-
invalidBffRuntime: string;
|
|
66
|
-
createFailed: string;
|
|
67
|
-
};
|
|
68
|
-
message: {
|
|
69
|
-
welcome: string;
|
|
70
|
-
success: string;
|
|
71
|
-
nextSteps: string;
|
|
72
|
-
step1: string;
|
|
73
|
-
step2: string;
|
|
74
|
-
step3: string;
|
|
75
|
-
};
|
|
76
|
-
help: {
|
|
77
|
-
title: string;
|
|
78
|
-
description: string;
|
|
79
|
-
usage: string;
|
|
80
|
-
usageExample: string;
|
|
81
|
-
options: string;
|
|
82
|
-
optionHelp: string;
|
|
83
|
-
optionVersion: string;
|
|
84
|
-
optionLang: string;
|
|
85
|
-
optionRouter: string;
|
|
86
|
-
optionBff: string;
|
|
87
|
-
optionBffRuntime: string;
|
|
88
|
-
optionTailwind: string;
|
|
89
|
-
optionWorkspace: string;
|
|
90
|
-
optionUltramodernWorkspace: string;
|
|
91
|
-
optionUltramodernPackageSource: string;
|
|
92
|
-
optionUltramodernPackageScope: string;
|
|
93
|
-
optionUltramodernPackageNamePrefix: string;
|
|
94
|
-
optionSub: string;
|
|
95
|
-
examples: string;
|
|
96
|
-
example1: string;
|
|
97
|
-
example2: string;
|
|
98
|
-
example3: string;
|
|
99
|
-
example4: string;
|
|
100
|
-
example5: string;
|
|
101
|
-
example6: string;
|
|
102
|
-
example7: string;
|
|
103
|
-
example8: string;
|
|
104
|
-
example9: string;
|
|
105
|
-
example10: string;
|
|
106
|
-
moreInfo: string;
|
|
107
|
-
};
|
|
108
|
-
version: {
|
|
109
|
-
message: string;
|
|
110
|
-
};
|
|
111
|
-
};
|
|
1
|
+
declare const i18n: any;
|
|
2
|
+
declare const localeKeys: any;
|
|
112
3
|
export { i18n, localeKeys };
|
package/package.json
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
24
|
-
"version": "3.2.0-ultramodern.
|
|
24
|
+
"version": "3.2.0-ultramodern.10",
|
|
25
25
|
"types": "./dist/types/index.d.ts",
|
|
26
26
|
"main": "./dist/index.js",
|
|
27
27
|
"bin": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@types/node": "^25.8.0",
|
|
42
42
|
"@typescript/native-preview": "7.0.0-dev.20260516.1",
|
|
43
43
|
"tsx": "^4.22.0",
|
|
44
|
-
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.
|
|
44
|
+
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.10"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -52,5 +52,8 @@
|
|
|
52
52
|
"build": "rslib build && pnpm -w tsgo:dts \"$PWD\"",
|
|
53
53
|
"dev": "rslib build -w",
|
|
54
54
|
"start": "node ./dist/index.js"
|
|
55
|
+
},
|
|
56
|
+
"ultramodern": {
|
|
57
|
+
"frameworkVersion": "3.2.0-ultramodern.10"
|
|
55
58
|
}
|
|
56
59
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"installDir": ".agents/skills",
|
|
4
|
+
"sources": [
|
|
5
|
+
{
|
|
6
|
+
"id": "techsiocz-private",
|
|
7
|
+
"visibility": "private",
|
|
8
|
+
"repository": "https://github.com/TechsioCZ/skills",
|
|
9
|
+
"install": "clone-if-authorized",
|
|
10
|
+
"baseline": [
|
|
11
|
+
{
|
|
12
|
+
"name": "plan-graph",
|
|
13
|
+
"reason": "Build and validate DAGs from .plan.md files"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "dag",
|
|
17
|
+
"reason": "Inspect current plan frontiers and blocked lanes"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "subagent-graph",
|
|
21
|
+
"reason": "Design dependency-aware multi-agent launch graphs"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "helm",
|
|
25
|
+
"reason": "Steer already-running multi-agent work"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "debugger-mode",
|
|
29
|
+
"reason": "Run hypothesis-driven debugging with runtime evidence"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# UltraModern Agent Contract
|
|
2
|
+
|
|
3
|
+
This project is generated for Codex-first UltraModern.js work.
|
|
4
|
+
|
|
5
|
+
## Quality Gates
|
|
6
|
+
|
|
7
|
+
- `pnpm lint` runs Oxlint with the Ultracite preset.
|
|
8
|
+
- `pnpm format` runs oxfmt.
|
|
9
|
+
- `pnpm typecheck` runs effect-tsgo as the TypeScript checker.
|
|
10
|
+
- `pnpm ultramodern:check` verifies the generated contract.
|
|
11
|
+
|
|
12
|
+
## Private Skills
|
|
13
|
+
|
|
14
|
+
Private orchestration skills are not vendored into this template. If you are authorized for `TechsioCZ/skills`, run:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm skills:install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The installer clones that private repository and copies only the allowlisted skills from `.agents/skills-lock.json`.
|
package/template/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# UltraModern.js 3.0 Starter
|
|
2
2
|
|
|
3
3
|
## Setup
|
|
4
4
|
|
|
@@ -64,8 +64,9 @@ Module Federation remote with the same topology, trust, SSR compatibility, and
|
|
|
64
64
|
fallback rules as the vertical remotes. Do not add a second preset or a
|
|
65
65
|
design-system-specific framework mode.
|
|
66
66
|
|
|
67
|
-
The public opinionated entrypoint is `presetUltramodern(...)`.
|
|
68
|
-
|
|
67
|
+
The public opinionated entrypoint is `presetUltramodern(...)`. It is the default
|
|
68
|
+
UltraModern.js SuperApp surface for Effect, TanStack, SSR, BFF, and Micro
|
|
69
|
+
Verticals.
|
|
69
70
|
|
|
70
71
|
Preview the production build locally:
|
|
71
72
|
|
|
@@ -74,5 +75,5 @@ pnpm serve
|
|
|
74
75
|
```
|
|
75
76
|
|
|
76
77
|
For more information, see the
|
|
77
|
-
[UltraModern.js guide](https://
|
|
78
|
-
and the [
|
|
78
|
+
[UltraModern.js guide](https://bleedingdev.github.io/ultramodern.js/guides/get-started/ultramodern.html)
|
|
79
|
+
and the [UltraModern.js documentation](https://bleedingdev.github.io/ultramodern.js/).
|
|
@@ -2,60 +2,22 @@
|
|
|
2
2
|
Effect,
|
|
3
3
|
HttpApiBuilder,
|
|
4
4
|
Layer,
|
|
5
|
-
Schema,
|
|
6
|
-
ServiceMap,
|
|
7
5
|
defineEffectBff,
|
|
8
6
|
} from '@modern-js/plugin-bff/effect-server';
|
|
9
7
|
import { bffEffectApi } from '../../shared/effect/api';
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
'GreetingUnavailableError',
|
|
13
|
-
{
|
|
14
|
-
message: Schema.String,
|
|
15
|
-
},
|
|
16
|
-
) {}
|
|
17
|
-
|
|
18
|
-
class GreetingService extends ServiceMap.Service<GreetingService>()('GreetingService', {
|
|
19
|
-
make: Effect.succeed({
|
|
20
|
-
hello: Effect.fn('GreetingService.hello')(function* () {
|
|
21
|
-
if (Date.now() < 0) {
|
|
22
|
-
return yield* Effect.fail(
|
|
23
|
-
new GreetingUnavailableError({
|
|
24
|
-
message: 'Greeting service is unavailable',
|
|
25
|
-
}),
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
message: 'Hello from Effect HttpApi',
|
|
31
|
-
runtime: 'effect' as const,
|
|
32
|
-
};
|
|
33
|
-
}),
|
|
34
|
-
}),
|
|
35
|
-
}) {
|
|
36
|
-
static readonly layer = Layer.effect(this, this.make);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const greetingsLayer = HttpApiBuilder.group(bffEffectApi, 'greetings', handlers =>
|
|
9
|
+
const greetingsLayer = HttpApiBuilder.group(bffEffectApi, 'greetings', (handlers) =>
|
|
40
10
|
handlers.handle('hello', () =>
|
|
41
|
-
|
|
42
|
-
Effect
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
runtime: 'effect' as const,
|
|
46
|
-
}),
|
|
47
|
-
),
|
|
48
|
-
),
|
|
11
|
+
Effect.succeed({
|
|
12
|
+
message: 'Hello from Effect HttpApi',
|
|
13
|
+
runtime: 'effect' as const,
|
|
14
|
+
}),
|
|
49
15
|
),
|
|
50
16
|
);
|
|
51
17
|
|
|
52
|
-
const layer = HttpApiBuilder.layer(bffEffectApi).pipe(
|
|
53
|
-
Layer.provide(greetingsLayer),
|
|
54
|
-
Layer.provide(GreetingService.layer),
|
|
55
|
-
);
|
|
18
|
+
const layer = HttpApiBuilder.layer(bffEffectApi).pipe(Layer.provide(greetingsLayer));
|
|
56
19
|
|
|
57
20
|
export default defineEffectBff({
|
|
58
21
|
api: bffEffectApi,
|
|
59
22
|
layer,
|
|
60
|
-
});
|
|
61
|
-
{{/if}}
|
|
23
|
+
});{{/if}}
|
|
@@ -1,41 +1,37 @@
|
|
|
1
|
+
// @effect-diagnostics nodeBuiltinImport:off processEnv:off
|
|
1
2
|
import { appTools, defineConfig, presetUltramodern } from '@modern-js/app-tools';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
{{#if enableBff}}import { bffPlugin } from '@modern-js/plugin-bff';
|
|
4
5
|
{{/if}}{{#if isTanstackRouter}}import { tanstackRouterPlugin } from '@modern-js/plugin-tanstack';
|
|
5
6
|
{{/if}}
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
process.env.MODERN_BASELINE_ENABLE_MF_SSR !== 'false';
|
|
10
|
-
const enableBffRequestId =
|
|
11
|
-
process.env.MODERN_BASELINE_ENABLE_BFF_REQUEST_ID !== 'false';
|
|
7
|
+
const appId = process.env['MODERN_BASELINE_APP_ID'] || path.basename(process.cwd());
|
|
8
|
+
const enableModuleFederationSSR = process.env['MODERN_BASELINE_ENABLE_MF_SSR'] !== 'false';
|
|
9
|
+
const enableBffRequestId = process.env['MODERN_BASELINE_ENABLE_BFF_REQUEST_ID'] !== 'false';
|
|
12
10
|
const enableTelemetryExporters =
|
|
13
|
-
process.env
|
|
14
|
-
const telemetryFailLoudStartup =
|
|
15
|
-
|
|
11
|
+
process.env['MODERN_BASELINE_ENABLE_TELEMETRY_EXPORTERS'] !== 'false';
|
|
12
|
+
const telemetryFailLoudStartup = process.env['MODERN_TELEMETRY_FAIL_LOUD_STARTUP'] !== 'false';
|
|
13
|
+
const otlpEndpoint = process.env['MODERN_TELEMETRY_OTLP_ENDPOINT'];
|
|
14
|
+
const victoriaMetricsEndpoint = process.env['MODERN_TELEMETRY_VICTORIA_ENDPOINT'];
|
|
16
15
|
|
|
17
|
-
// https://
|
|
16
|
+
// https://bleedingdev.github.io/ultramodern.js/configure/app/usage.html
|
|
18
17
|
export default defineConfig(
|
|
19
18
|
presetUltramodern(
|
|
20
19
|
{
|
|
21
|
-
|
|
20
|
+
{{#if enableBff}} bff: {
|
|
21
|
+
{{#if useEffectBff}} effect: {
|
|
22
|
+
openapi: true,
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
{{/if}} runtimeFramework: '{{bffRuntime}}',
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
{{/if}} plugins: [
|
|
22
29
|
appTools(),
|
|
23
30
|
{{#if isTanstackRouter}}
|
|
24
31
|
tanstackRouterPlugin(),
|
|
25
32
|
{{/if}}{{#if enableBff}}
|
|
26
33
|
bffPlugin(),
|
|
27
|
-
{{/if}}
|
|
28
|
-
],
|
|
29
|
-
{{#if enableBff}}
|
|
30
|
-
bff: {
|
|
31
|
-
runtimeFramework: '{{bffRuntime}}',
|
|
32
|
-
{{#if useEffectBff}}
|
|
33
|
-
effect: {
|
|
34
|
-
openapi: true,
|
|
35
|
-
},
|
|
36
|
-
{{/if}}
|
|
37
|
-
},
|
|
38
|
-
{{/if}}
|
|
34
|
+
{{/if}} ],
|
|
39
35
|
},
|
|
40
36
|
{
|
|
41
37
|
appId,
|
|
@@ -43,8 +39,8 @@ export default defineConfig(
|
|
|
43
39
|
enableModuleFederationSSR,
|
|
44
40
|
enableTelemetryExporters,
|
|
45
41
|
telemetryFailLoudStartup,
|
|
46
|
-
otlpEndpoint:
|
|
47
|
-
victoriaMetricsEndpoint:
|
|
42
|
+
...(typeof otlpEndpoint === 'string' ? { otlpEndpoint } : {}),
|
|
43
|
+
...(typeof victoriaMetricsEndpoint === 'string' ? { victoriaMetricsEndpoint } : {}),
|
|
48
44
|
},
|
|
49
45
|
),
|
|
50
46
|
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineConfig } from 'oxlint';
|
|
2
|
+
import core from 'ultracite/oxlint/core';
|
|
3
|
+
import react from 'ultracite/oxlint/react';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
env: {
|
|
7
|
+
browser: true,
|
|
8
|
+
node: true,
|
|
9
|
+
},
|
|
10
|
+
extends: [core, react],
|
|
11
|
+
ignorePatterns: ['dist', 'node_modules', '.modern', '.modernjs', '**/routeTree.gen.ts'],
|
|
12
|
+
});
|
|
@@ -1,47 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "{{packageName}}",
|
|
3
3
|
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"scripts": {
|
|
5
6
|
"reset": "npx rimraf node_modules ./**/node_modules",
|
|
6
7
|
"dev": "modern dev",
|
|
7
8
|
"build": "modern build",
|
|
8
9
|
"serve": "modern serve",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
10
|
+
"typecheck": "node -e \"const fs = require('node:fs'); const { execFileSync, spawnSync } = require('node:child_process'); const bin = execFileSync('effect-tsgo', ['get-exe-path'], { encoding: 'utf8' }).trim(); if (process.platform !== 'win32') fs.chmodSync(bin, 0o755); const result = spawnSync(bin, ['--noEmit', '-p', 'tsconfig.json'], { stdio: 'inherit' }); process.exit(result.status ?? 1);\"",
|
|
11
|
+
"skills:install": "node ./scripts/bootstrap-agent-skills.mjs",
|
|
12
|
+
"skills:check": "node ./scripts/bootstrap-agent-skills.mjs --check",
|
|
13
|
+
"ultramodern:check": "{{#unless isSubproject}}pnpm format:check && pnpm lint && {{/unless}}pnpm typecheck{{#unless isSubproject}} && pnpm skills:check{{/unless}} && node ./scripts/validate-ultramodern.mjs"{{#unless isSubproject}},
|
|
14
|
+
"format": "oxfmt .",
|
|
15
|
+
"format:check": "oxfmt --check .",
|
|
16
|
+
"lint": "oxlint .",
|
|
17
|
+
"lint:fix": "oxlint . --fix",
|
|
11
18
|
"prepare": "simple-git-hooks"{{/unless}}
|
|
12
19
|
},
|
|
13
|
-
"engines": {
|
|
14
|
-
"node": ">=20"
|
|
15
|
-
}{{#unless isSubproject}},
|
|
16
|
-
"lint-staged": {
|
|
17
|
-
"*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": [
|
|
18
|
-
"biome check --files-ignore-unknown=true"
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
|
-
"simple-git-hooks": {
|
|
22
|
-
"pre-commit": "npx lint-staged"
|
|
23
|
-
}{{/unless}},
|
|
24
20
|
"dependencies": {
|
|
25
|
-
"@modern-js/
|
|
26
|
-
"@modern-js/
|
|
27
|
-
"@tanstack/react-router": "1.170.1"
|
|
21
|
+
{{#if isTanstackRouter}} "@modern-js/plugin-tanstack": "{{pluginTanstackVersion}}",
|
|
22
|
+
{{/if}} "@modern-js/runtime": "{{runtimeVersion}}",
|
|
23
|
+
{{#if isTanstackRouter}} "@tanstack/react-router": "1.170.1",
|
|
24
|
+
{{/if}}
|
|
28
25
|
"react": "^19.2.3",
|
|
29
26
|
"react-dom": "^19.2.0"
|
|
30
27
|
},
|
|
31
28
|
"devDependencies": {
|
|
32
|
-
"@
|
|
33
|
-
"@modern-js/
|
|
34
|
-
"@modern-js/plugin-bff": "{{
|
|
29
|
+
"@effect/tsgo": "0.7.3",
|
|
30
|
+
"@modern-js/app-tools": "{{appToolsVersion}}",
|
|
31
|
+
{{#if enableBff}} "@modern-js/plugin-bff": "{{pluginBffVersion}}",
|
|
32
|
+
{{/if}} "@modern-js/tsconfig": "{{tsconfigVersion}}",
|
|
33
|
+
{{#if enableTailwind}}
|
|
35
34
|
"@tailwindcss/postcss": "^4.1.18",
|
|
36
|
-
|
|
37
|
-
"tailwindcss": "^4.1.18"{{/if}}{{#unless isSubproject}},
|
|
38
|
-
"@biomejs/biome": "1.9.4"{{/unless}},
|
|
39
|
-
"@typescript/native-preview": "7.0.0-dev.20260516.1",
|
|
35
|
+
{{/if}}
|
|
40
36
|
"@types/node": "^20",
|
|
41
37
|
"@types/react": "^19.1.8",
|
|
42
|
-
"@types/react-dom": "^19.1.6"
|
|
38
|
+
"@types/react-dom": "^19.1.6",
|
|
39
|
+
"@typescript/native-preview": "7.0.0-dev.20260518.1",
|
|
40
|
+
{{#unless isSubproject}}
|
|
43
41
|
"lint-staged": "~15.4.0",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
42
|
+
"oxfmt": "0.50.0",
|
|
43
|
+
"oxlint": "1.65.0",
|
|
44
|
+
{{/unless}}{{#if enableTailwind}} "postcss": "^8.5.6",
|
|
45
|
+
{{/if}} "rimraf": "^6.0.1"{{#unless isSubproject}},
|
|
46
|
+
"simple-git-hooks": "^2.11.1"{{/unless}}{{#if enableTailwind}},
|
|
47
|
+
"tailwindcss": "^4.1.18"{{/if}}{{#unless isSubproject}},
|
|
48
|
+
"ultracite": "7.7.0"{{/unless}}
|
|
49
|
+
}{{#unless isSubproject}},
|
|
50
|
+
"simple-git-hooks": {
|
|
51
|
+
"pre-commit": "npx lint-staged"
|
|
52
|
+
},
|
|
53
|
+
"lint-staged": {
|
|
54
|
+
"*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": [
|
|
55
|
+
"oxfmt --write",
|
|
56
|
+
"oxlint --fix"
|
|
57
|
+
]
|
|
58
|
+
}{{/unless}},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=20"
|
|
46
61
|
}
|
|
47
62
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
const root = process.cwd();
|
|
7
|
+
const lockPath = path.join(root, '.agents/skills-lock.json');
|
|
8
|
+
const checkOnly = process.argv.includes('--check');
|
|
9
|
+
const force = process.argv.includes('--force');
|
|
10
|
+
|
|
11
|
+
const readJson = (filePath) => JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
12
|
+
|
|
13
|
+
const run = (command, args, options = {}) =>
|
|
14
|
+
execFileSync(command, args, {
|
|
15
|
+
cwd: options.cwd ?? root,
|
|
16
|
+
encoding: 'utf-8',
|
|
17
|
+
stdio: options.stdio ?? ['ignore', 'pipe', 'pipe'],
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const cloneSource = (source, targetDir) => {
|
|
21
|
+
const repo = source.repository.replace(/^https:\/\/github.com\//u, '');
|
|
22
|
+
try {
|
|
23
|
+
run('gh', ['repo', 'clone', repo, targetDir, '--', '--depth', '1'], {
|
|
24
|
+
stdio: 'inherit',
|
|
25
|
+
});
|
|
26
|
+
} catch {
|
|
27
|
+
run('git', ['clone', '--depth', '1', source.repository, targetDir], {
|
|
28
|
+
stdio: 'inherit',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const resolveSkillDir = (sourceRoot, skillName) => {
|
|
34
|
+
const candidates = [
|
|
35
|
+
path.join(sourceRoot, skillName),
|
|
36
|
+
path.join(sourceRoot, 'skills', skillName),
|
|
37
|
+
path.join(sourceRoot, 'skills', 'engineering', skillName),
|
|
38
|
+
path.join(sourceRoot, 'skills', 'productivity', skillName),
|
|
39
|
+
];
|
|
40
|
+
return candidates.find((candidate) => fs.existsSync(path.join(candidate, 'SKILL.md')));
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
if (!fs.existsSync(lockPath)) {
|
|
44
|
+
console.error('Missing .agents/skills-lock.json');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const lock = readJson(lockPath);
|
|
49
|
+
const installDir = path.join(root, lock.installDir ?? '.agents/skills');
|
|
50
|
+
const privateSources = (lock.sources ?? []).filter(
|
|
51
|
+
(source) => source.install === 'clone-if-authorized',
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (checkOnly) {
|
|
55
|
+
const missing = privateSources.flatMap((source) =>
|
|
56
|
+
(source.baseline ?? [])
|
|
57
|
+
.map((skill) => skill.name)
|
|
58
|
+
.filter((skillName) => !fs.existsSync(path.join(installDir, skillName, 'SKILL.md'))),
|
|
59
|
+
);
|
|
60
|
+
if (missing.length > 0) {
|
|
61
|
+
console.warn(
|
|
62
|
+
`Private skills not installed: ${missing.join(', ')}. Run pnpm skills:install if you have access.`,
|
|
63
|
+
);
|
|
64
|
+
} else {
|
|
65
|
+
console.log('Agent skills are installed.');
|
|
66
|
+
}
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
71
|
+
|
|
72
|
+
for (const source of privateSources) {
|
|
73
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ultramodern-skills-'));
|
|
74
|
+
try {
|
|
75
|
+
cloneSource(source, tempDir);
|
|
76
|
+
for (const skill of source.baseline ?? []) {
|
|
77
|
+
const sourceSkillDir = resolveSkillDir(tempDir, skill.name);
|
|
78
|
+
if (!sourceSkillDir) {
|
|
79
|
+
throw new Error(`Skill ${skill.name} not found in ${source.repository}`);
|
|
80
|
+
}
|
|
81
|
+
const targetSkillDir = path.join(installDir, skill.name);
|
|
82
|
+
if (fs.existsSync(targetSkillDir)) {
|
|
83
|
+
if (!force) {
|
|
84
|
+
console.log(`Skipping existing ${skill.name}`);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
fs.rmSync(targetSkillDir, { force: true, recursive: true });
|
|
88
|
+
}
|
|
89
|
+
fs.cpSync(sourceSkillDir, targetSkillDir, { recursive: true });
|
|
90
|
+
console.log(`Installed ${skill.name}`);
|
|
91
|
+
}
|
|
92
|
+
} finally {
|
|
93
|
+
fs.rmSync(tempDir, { force: true, recursive: true });
|
|
94
|
+
}
|
|
95
|
+
}
|