@remix-run/cli 0.1.0 → 0.3.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/README.md +0 -3
- package/dist/lib/bootstrap-project.d.ts.map +1 -1
- package/dist/lib/bootstrap-project.js +32 -9
- package/dist/lib/cli.d.ts +29 -0
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +33 -14
- package/dist/lib/commands/completion.d.ts.map +1 -1
- package/dist/lib/commands/completion.js +5 -1
- package/dist/lib/commands/doctor.js +18 -18
- package/dist/lib/commands/help.d.ts.map +1 -1
- package/dist/lib/commands/help.js +9 -33
- package/dist/lib/commands/routes.js +3 -3
- package/dist/lib/commands/test.d.ts +1 -1
- package/dist/lib/commands/test.d.ts.map +1 -1
- package/dist/lib/commands/test.js +8 -4
- package/dist/lib/completion.d.ts.map +1 -1
- package/dist/lib/completion.js +4 -106
- package/dist/lib/controller-files.d.ts +0 -1
- package/dist/lib/controller-files.d.ts.map +1 -1
- package/dist/lib/controller-files.js +3 -5
- package/dist/lib/controller-ownership.d.ts +9 -9
- package/dist/lib/controller-ownership.d.ts.map +1 -1
- package/dist/lib/controller-ownership.js +56 -91
- package/dist/lib/doctor/controller-findings.d.ts +1 -1
- package/dist/lib/doctor/controller-findings.d.ts.map +1 -1
- package/dist/lib/doctor/controller-findings.js +15 -87
- package/dist/lib/doctor/controller-fix-plans.d.ts.map +1 -1
- package/dist/lib/doctor/controller-fix-plans.js +13 -24
- package/dist/lib/doctor/controller-placeholders.d.ts +2 -3
- package/dist/lib/doctor/controller-placeholders.d.ts.map +1 -1
- package/dist/lib/doctor/controller-placeholders.js +18 -149
- package/dist/lib/doctor/controllers.js +1 -1
- package/dist/lib/doctor/project.js +60 -52
- package/dist/lib/doctor/types.d.ts +2 -2
- package/dist/lib/doctor/types.d.ts.map +1 -1
- package/dist/lib/errors.d.ts +0 -6
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +0 -11
- package/dist/lib/load-route-map-worker.js +17 -9
- package/dist/lib/route-map.d.ts +1 -1
- package/dist/lib/route-map.d.ts.map +1 -1
- package/dist/lib/route-map.js +29 -17
- package/package.json +4 -5
- package/src/lib/bootstrap-project.ts +39 -13
- package/src/lib/cli.ts +46 -15
- package/src/lib/commands/completion.ts +6 -1
- package/src/lib/commands/doctor.ts +18 -21
- package/src/lib/commands/help.ts +9 -43
- package/src/lib/commands/routes.ts +3 -3
- package/src/lib/commands/test.ts +10 -4
- package/src/lib/completion.ts +4 -151
- package/src/lib/controller-files.ts +4 -8
- package/src/lib/controller-ownership.ts +78 -141
- package/src/lib/doctor/controller-findings.ts +20 -97
- package/src/lib/doctor/controller-fix-plans.ts +13 -29
- package/src/lib/doctor/controller-placeholders.ts +17 -189
- package/src/lib/doctor/controllers.ts +1 -1
- package/src/lib/doctor/project.ts +60 -52
- package/src/lib/doctor/types.ts +1 -5
- package/src/lib/errors.ts +0 -12
- package/src/lib/load-route-map-worker.ts +19 -10
- package/src/lib/route-map.ts +61 -16
- package/template/.agents/skills/remix/SKILL.md +588 -0
- package/template/.agents/skills/remix/references/animate-elements.md +195 -0
- package/template/.agents/skills/remix/references/assets-and-browser-modules.md +130 -0
- package/template/.agents/skills/remix/references/auth-and-sessions.md +443 -0
- package/template/.agents/skills/remix/references/component-model.md +282 -0
- package/template/.agents/skills/remix/references/create-mixins.md +158 -0
- package/template/.agents/skills/remix/references/data-and-validation.md +379 -0
- package/template/.agents/skills/remix/references/hydration-frames-navigation.md +297 -0
- package/template/.agents/skills/remix/references/middleware-and-server.md +233 -0
- package/template/.agents/skills/remix/references/mixins-styling-events.md +213 -0
- package/template/.agents/skills/remix/references/routing-and-controllers.md +391 -0
- package/template/.agents/skills/remix/references/testing-patterns.md +172 -0
- package/{bootstrap → template}/AGENTS.md +13 -8
- package/template/README.md +29 -0
- package/template/app/actions/controller.tsx +18 -0
- package/template/app/assets/entry.ts +8 -0
- package/template/app/assets/prompt-button.tsx +163 -0
- package/template/app/assets.ts +20 -0
- package/template/app/middleware/render.tsx +43 -0
- package/template/app/router.ts +20 -0
- package/template/app/routes.ts +6 -0
- package/template/app/ui/document.tsx +33 -0
- package/template/app/ui/scaffold-home-page.tsx +527 -0
- package/template/gitignore +4 -0
- package/{bootstrap → template}/package.json +5 -6
- package/template/public/favicon.svg +11 -0
- package/{bootstrap → template}/server.ts +4 -5
- package/{bootstrap → template}/tsconfig.json +3 -3
- package/bootstrap/README.md +0 -27
- package/bootstrap/app/controllers/auth.tsx +0 -21
- package/bootstrap/app/controllers/home.tsx +0 -26
- package/bootstrap/app/router.ts +0 -10
- package/bootstrap/app/routes.ts +0 -6
- package/bootstrap/app/ui/document.tsx +0 -21
- package/bootstrap/app/ui/layout.tsx +0 -22
- package/bootstrap/app/utils/render.tsx +0 -7
- package/dist/lib/commands/skills.d.ts +0 -6
- package/dist/lib/commands/skills.d.ts.map +0 -1
- package/dist/lib/commands/skills.js +0 -222
- package/dist/lib/skills-cache.d.ts +0 -19
- package/dist/lib/skills-cache.d.ts.map +0 -1
- package/dist/lib/skills-cache.js +0 -89
- package/dist/lib/skills.d.ts +0 -30
- package/dist/lib/skills.d.ts.map +0 -1
- package/dist/lib/skills.js +0 -441
- package/src/lib/commands/skills.ts +0 -306
- package/src/lib/skills-cache.ts +0 -140
- package/src/lib/skills.ts +0 -706
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { BuildAction } from 'remix/fetch-router'
|
|
2
|
-
|
|
3
|
-
import type { routes } from '../routes.ts'
|
|
4
|
-
import { Layout } from '../ui/layout.tsx'
|
|
5
|
-
import { render } from '../utils/render.tsx'
|
|
6
|
-
|
|
7
|
-
const APP_DISPLAY_NAME = decodeURIComponent('%%RMX_APP_DISPLAY_NAME_URI_COMPONENT%%')
|
|
8
|
-
|
|
9
|
-
export const home: BuildAction<'GET', typeof routes.home> = {
|
|
10
|
-
handler() {
|
|
11
|
-
return render(<HomePage />)
|
|
12
|
-
},
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function HomePage() {
|
|
16
|
-
return () => (
|
|
17
|
-
<Layout title="Home">
|
|
18
|
-
<h1>{APP_DISPLAY_NAME}</h1>
|
|
19
|
-
<p>This starter begins with two flat route files so you can start shipping immediately.</p>
|
|
20
|
-
<p>
|
|
21
|
-
Add new routes in <code>app/routes.ts</code>, keep them flat at first, and only split them
|
|
22
|
-
into folders when the route grows.
|
|
23
|
-
</p>
|
|
24
|
-
</Layout>
|
|
25
|
-
)
|
|
26
|
-
}
|
package/bootstrap/app/router.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { createRouter } from 'remix/fetch-router'
|
|
2
|
-
|
|
3
|
-
import { auth } from './controllers/auth.tsx'
|
|
4
|
-
import { home } from './controllers/home.tsx'
|
|
5
|
-
import { routes } from './routes.ts'
|
|
6
|
-
|
|
7
|
-
export const router = createRouter()
|
|
8
|
-
|
|
9
|
-
router.map(routes.home, home)
|
|
10
|
-
router.map(routes.auth, auth)
|
package/bootstrap/app/routes.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { RemixNode } from 'remix/ui'
|
|
2
|
-
|
|
3
|
-
export interface DocumentProps {
|
|
4
|
-
children?: RemixNode
|
|
5
|
-
title?: string
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const DEFAULT_TITLE = decodeURIComponent('%%RMX_APP_DISPLAY_NAME_URI_COMPONENT%%')
|
|
9
|
-
|
|
10
|
-
export function Document() {
|
|
11
|
-
return ({ title = DEFAULT_TITLE, children }: DocumentProps) => (
|
|
12
|
-
<html lang="en">
|
|
13
|
-
<head>
|
|
14
|
-
<meta charSet="utf-8" />
|
|
15
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
16
|
-
<title>{title}</title>
|
|
17
|
-
</head>
|
|
18
|
-
<body>{children}</body>
|
|
19
|
-
</html>
|
|
20
|
-
)
|
|
21
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { RemixNode } from 'remix/ui'
|
|
2
|
-
|
|
3
|
-
import { routes } from '../routes.ts'
|
|
4
|
-
import { Document } from './document.tsx'
|
|
5
|
-
|
|
6
|
-
export interface LayoutProps {
|
|
7
|
-
children?: RemixNode
|
|
8
|
-
title?: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function Layout() {
|
|
12
|
-
return ({ title, children }: LayoutProps) => (
|
|
13
|
-
<Document title={title}>
|
|
14
|
-
<header>
|
|
15
|
-
<nav>
|
|
16
|
-
<a href={routes.home.href()}>Home</a> <a href={routes.auth.href()}>Auth</a>
|
|
17
|
-
</nav>
|
|
18
|
-
</header>
|
|
19
|
-
<main>{children}</main>
|
|
20
|
-
</Document>
|
|
21
|
-
)
|
|
22
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { RemixNode } from 'remix/ui'
|
|
2
|
-
import { renderToStream } from 'remix/ui/server'
|
|
3
|
-
import { createHtmlResponse } from 'remix/response/html'
|
|
4
|
-
|
|
5
|
-
export function render(node: RemixNode, init?: ResponseInit) {
|
|
6
|
-
return createHtmlResponse(renderToStream(node), init)
|
|
7
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { CliContext } from '../cli-context.ts';
|
|
2
|
-
export declare function runSkillsCommand(argv: string[], context: CliContext): Promise<number>;
|
|
3
|
-
export declare function getSkillsCommandHelpText(target?: NodeJS.WriteStream): string;
|
|
4
|
-
export declare function getSkillsInstallCommandHelpText(target?: NodeJS.WriteStream): string;
|
|
5
|
-
export declare function getSkillsListCommandHelpText(target?: NodeJS.WriteStream): string;
|
|
6
|
-
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/skills.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAsBnD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB3F;AAED,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAwB5F;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,GAAE,MAAM,CAAC,WAA4B,GAC1C,MAAM,CAeR;AAED,wBAAgB,4BAA4B,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAqBhG"}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import * as process from 'node:process';
|
|
2
|
-
import { getDisplayPath } from "../display-path.js";
|
|
3
|
-
import { renderCliError, toCliError, unknownSkillsCommand } from "../errors.js";
|
|
4
|
-
import { formatHelpText } from "../help-text.js";
|
|
5
|
-
import { parseArgs } from "../parse-args.js";
|
|
6
|
-
import { getSkillsOverview, installRemixSkills } from "../skills.js";
|
|
7
|
-
import { createCommandReporter, createStepProgressReporter, } from "../reporter.js";
|
|
8
|
-
const SKILLS_PROGRESS_LABELS = {
|
|
9
|
-
'compare-local-skills': 'Compare local skills',
|
|
10
|
-
'download-remix-skills-archive': 'Download Remix skills archive',
|
|
11
|
-
'fetch-remix-skills-metadata': 'Fetch Remix skills metadata from GitHub',
|
|
12
|
-
'read-local-skills-cache': 'Read local skills cache',
|
|
13
|
-
'resolve-project-root': 'Resolve project root',
|
|
14
|
-
'write-updated-skills': 'Write updated skills',
|
|
15
|
-
};
|
|
16
|
-
export async function runSkillsCommand(argv, context) {
|
|
17
|
-
if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
|
|
18
|
-
process.stdout.write(getSkillsCommandHelpText());
|
|
19
|
-
return 0;
|
|
20
|
-
}
|
|
21
|
-
let [subcommand, ...rest] = argv;
|
|
22
|
-
try {
|
|
23
|
-
if (subcommand === 'install') {
|
|
24
|
-
return await runSkillsInstallCommand(rest, context);
|
|
25
|
-
}
|
|
26
|
-
if (subcommand === 'list') {
|
|
27
|
-
return await runSkillsListCommand(rest, context);
|
|
28
|
-
}
|
|
29
|
-
throw unknownSkillsCommand(subcommand);
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
process.stderr.write(renderCliError(toCliError(error), { helpText: getSkillsCommandHelpText(process.stderr) }));
|
|
33
|
-
return 1;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export function getSkillsCommandHelpText(target = process.stdout) {
|
|
37
|
-
return formatHelpText({
|
|
38
|
-
commands: [
|
|
39
|
-
{
|
|
40
|
-
description: 'Install Remix skills into a local directory',
|
|
41
|
-
label: 'install [--dir <path>]',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
description: 'List Remix skills and local status',
|
|
45
|
-
label: 'list [--dir <path>] [--json]',
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
description: 'Manage Remix skills for the current project.',
|
|
49
|
-
examples: [
|
|
50
|
-
'remix skills install',
|
|
51
|
-
'remix skills install --dir custom/skills',
|
|
52
|
-
'remix skills list --dir custom/skills',
|
|
53
|
-
'remix skills list --json',
|
|
54
|
-
],
|
|
55
|
-
usage: ['remix skills <command>'],
|
|
56
|
-
}, target);
|
|
57
|
-
}
|
|
58
|
-
export function getSkillsInstallCommandHelpText(target = process.stdout) {
|
|
59
|
-
return formatHelpText({
|
|
60
|
-
description: 'Install or refresh Remix skills in .agents/skills for the current project.',
|
|
61
|
-
examples: ['remix skills install', 'remix skills install --dir custom/skills'],
|
|
62
|
-
options: [
|
|
63
|
-
{
|
|
64
|
-
description: 'Install skills into a custom directory relative to the project root',
|
|
65
|
-
label: '--dir <path>',
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
usage: ['remix skills install [--dir <path>]'],
|
|
69
|
-
}, target);
|
|
70
|
-
}
|
|
71
|
-
export function getSkillsListCommandHelpText(target = process.stdout) {
|
|
72
|
-
return formatHelpText({
|
|
73
|
-
description: 'List Remix skills and show whether each one is installed, outdated, or missing locally.',
|
|
74
|
-
examples: [
|
|
75
|
-
'remix skills list',
|
|
76
|
-
'remix skills list --dir custom/skills',
|
|
77
|
-
'remix skills list --json',
|
|
78
|
-
],
|
|
79
|
-
options: [
|
|
80
|
-
{
|
|
81
|
-
description: 'Read local skills from a custom directory relative to the project root',
|
|
82
|
-
label: '--dir <path>',
|
|
83
|
-
},
|
|
84
|
-
{ description: 'Print skill state as JSON', label: '--json' },
|
|
85
|
-
],
|
|
86
|
-
usage: ['remix skills list [--dir <path>] [--json]'],
|
|
87
|
-
}, target);
|
|
88
|
-
}
|
|
89
|
-
async function runSkillsInstallCommand(argv, context) {
|
|
90
|
-
if (argv.includes('-h') || argv.includes('--help')) {
|
|
91
|
-
process.stdout.write(getSkillsInstallCommandHelpText());
|
|
92
|
-
return 0;
|
|
93
|
-
}
|
|
94
|
-
let reporter = null;
|
|
95
|
-
let progress = null;
|
|
96
|
-
try {
|
|
97
|
-
let options = parseSkillsInstallCommandArgs(argv);
|
|
98
|
-
reporter = createCommandReporter({ remixVersion: context.remixVersion });
|
|
99
|
-
progress = createSkillsProgressReporter(reporter);
|
|
100
|
-
let cwd = context.cwd;
|
|
101
|
-
await reporter.status.commandHeader('skills install');
|
|
102
|
-
let result = await installRemixSkills(cwd, globalThis.fetch, {
|
|
103
|
-
progress,
|
|
104
|
-
skillsDir: options.dir ?? undefined,
|
|
105
|
-
});
|
|
106
|
-
let skillsDir = getDisplayPath(result.skillsDir, cwd);
|
|
107
|
-
progress.writeSummaryGap();
|
|
108
|
-
if (result.appliedChanges.length === 0) {
|
|
109
|
-
reporter.out.line(`No changes. ${skillsDir} is up to date.`);
|
|
110
|
-
reporter.finish();
|
|
111
|
-
return 0;
|
|
112
|
-
}
|
|
113
|
-
reporter.out.line(`Synced Remix skills into ${skillsDir}:`);
|
|
114
|
-
reporter.out.bullets(formatAppliedChanges(result.appliedChanges));
|
|
115
|
-
reporter.finish();
|
|
116
|
-
return 0;
|
|
117
|
-
}
|
|
118
|
-
catch (error) {
|
|
119
|
-
progress?.writeSummaryGap();
|
|
120
|
-
process.stderr.write(renderCliError(toCliError(error), {
|
|
121
|
-
helpText: getSkillsInstallCommandHelpText(process.stderr),
|
|
122
|
-
}));
|
|
123
|
-
reporter?.finish();
|
|
124
|
-
return 1;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
async function runSkillsListCommand(argv, context) {
|
|
128
|
-
if (argv.includes('-h') || argv.includes('--help')) {
|
|
129
|
-
process.stdout.write(getSkillsListCommandHelpText());
|
|
130
|
-
return 0;
|
|
131
|
-
}
|
|
132
|
-
let reporter = null;
|
|
133
|
-
let progress = null;
|
|
134
|
-
try {
|
|
135
|
-
let options = parseSkillsDirArgs(argv, { allowJson: true });
|
|
136
|
-
let cwd = context.cwd;
|
|
137
|
-
reporter = options.json ? null : createCommandReporter({ remixVersion: context.remixVersion });
|
|
138
|
-
if (reporter != null) {
|
|
139
|
-
progress = createSkillsProgressReporter(reporter);
|
|
140
|
-
await reporter.status.commandHeader('skills list');
|
|
141
|
-
}
|
|
142
|
-
let result = await getSkillsOverview(cwd, globalThis.fetch, {
|
|
143
|
-
progress: progress ?? undefined,
|
|
144
|
-
skillsDir: options.dir ?? undefined,
|
|
145
|
-
});
|
|
146
|
-
if (options.json) {
|
|
147
|
-
process.stdout.write(`${JSON.stringify({
|
|
148
|
-
entries: result.entries,
|
|
149
|
-
projectRoot: result.projectRoot,
|
|
150
|
-
skillsDir: result.skillsDir,
|
|
151
|
-
}, null, 2)}\n`);
|
|
152
|
-
return 0;
|
|
153
|
-
}
|
|
154
|
-
progress?.writeSummaryGap();
|
|
155
|
-
if (reporter == null) {
|
|
156
|
-
return 0;
|
|
157
|
-
}
|
|
158
|
-
let listReporter = reporter;
|
|
159
|
-
listReporter.out.line(formatSkillsListSummary(result.entries, getDisplayPath(result.skillsDir, cwd)));
|
|
160
|
-
listReporter.out.bullets(result.entries.map((entry) => formatSkillListEntry(listReporter, entry)));
|
|
161
|
-
listReporter.finish();
|
|
162
|
-
return 0;
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
progress?.writeSummaryGap();
|
|
166
|
-
process.stderr.write(renderCliError(toCliError(error), { helpText: getSkillsListCommandHelpText(process.stderr) }));
|
|
167
|
-
reporter?.finish();
|
|
168
|
-
return 1;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
function createSkillsProgressReporter(reporter) {
|
|
172
|
-
return createStepProgressReporter(reporter.status, SKILLS_PROGRESS_LABELS);
|
|
173
|
-
}
|
|
174
|
-
function formatAppliedChanges(changes) {
|
|
175
|
-
let showAction = changes.some((change) => change.action !== 'add');
|
|
176
|
-
return changes.map((change) => showAction ? `${toPastTense(change.action)} ${change.name}` : change.name);
|
|
177
|
-
}
|
|
178
|
-
function formatSkillListEntry(reporter, entry) {
|
|
179
|
-
if (entry.state === 'installed') {
|
|
180
|
-
return entry.name;
|
|
181
|
-
}
|
|
182
|
-
let tone = entry.state === 'missing' ? 'error' : 'warn';
|
|
183
|
-
return `${entry.name} ${reporter.out.label(entry.state, '', { tone })}`;
|
|
184
|
-
}
|
|
185
|
-
function formatSkillsListSummary(entries, skillsDir) {
|
|
186
|
-
let installedCount = entries.filter((entry) => entry.state === 'installed').length;
|
|
187
|
-
let outdatedCount = entries.filter((entry) => entry.state === 'outdated').length;
|
|
188
|
-
let missingCount = entries.filter((entry) => entry.state === 'missing').length;
|
|
189
|
-
let detailParts = [
|
|
190
|
-
installedCount > 0 ? `${installedCount} installed` : null,
|
|
191
|
-
outdatedCount > 0 ? `${outdatedCount} outdated` : null,
|
|
192
|
-
missingCount > 0 ? `${missingCount} missing` : null,
|
|
193
|
-
].filter((part) => part != null);
|
|
194
|
-
let detail = detailParts.length === 0 ? '0 installed' : detailParts.join(', ');
|
|
195
|
-
return `Checked Remix skills against ${skillsDir}: ${detail}.`;
|
|
196
|
-
}
|
|
197
|
-
function parseSkillsInstallCommandArgs(argv) {
|
|
198
|
-
let { dir } = parseSkillsDirArgs(argv);
|
|
199
|
-
return { dir };
|
|
200
|
-
}
|
|
201
|
-
function parseSkillsDirArgs(argv, options = {}) {
|
|
202
|
-
if (options.allowJson) {
|
|
203
|
-
let parsed = parseArgs(argv, {
|
|
204
|
-
dir: { flag: '--dir', type: 'string' },
|
|
205
|
-
json: { flag: '--json', type: 'boolean' },
|
|
206
|
-
}, { maxPositionals: 0 });
|
|
207
|
-
return {
|
|
208
|
-
dir: parsed.options.dir ?? null,
|
|
209
|
-
json: parsed.options.json,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
let parsed = parseArgs(argv, {
|
|
213
|
-
dir: { flag: '--dir', type: 'string' },
|
|
214
|
-
}, { maxPositionals: 0 });
|
|
215
|
-
return {
|
|
216
|
-
dir: parsed.options.dir ?? null,
|
|
217
|
-
json: false,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
function toPastTense(action) {
|
|
221
|
-
return action === 'add' ? 'added' : 'replaced';
|
|
222
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export interface SkillsCacheFileEntry {
|
|
2
|
-
localHash: string;
|
|
3
|
-
remoteSha: string;
|
|
4
|
-
}
|
|
5
|
-
export interface SkillsCacheSkillEntry {
|
|
6
|
-
files: Record<string, SkillsCacheFileEntry>;
|
|
7
|
-
}
|
|
8
|
-
export interface SkillsCacheManifest {
|
|
9
|
-
ref: string;
|
|
10
|
-
repo: string;
|
|
11
|
-
skills: Record<string, SkillsCacheSkillEntry>;
|
|
12
|
-
skillsDir: string;
|
|
13
|
-
version: number;
|
|
14
|
-
}
|
|
15
|
-
export declare function createSkillsCacheManifest(skillsDir: string, skills: Record<string, SkillsCacheSkillEntry>): SkillsCacheManifest;
|
|
16
|
-
export declare function getSkillsCacheFilePath(skillsDir: string): string;
|
|
17
|
-
export declare function readSkillsCache(skillsDir: string): Promise<SkillsCacheManifest | null>;
|
|
18
|
-
export declare function writeSkillsCache(skillsDir: string, manifest: SkillsCacheManifest): Promise<void>;
|
|
19
|
-
//# sourceMappingURL=skills-cache.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skills-cache.d.ts","sourceRoot":"","sources":["../../src/lib/skills-cache.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;IAC7C,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAC5C,mBAAmB,CAQrB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAiB5F;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,mBAAmB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
package/dist/lib/skills-cache.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import * as crypto from 'node:crypto';
|
|
2
|
-
import * as fs from 'node:fs/promises';
|
|
3
|
-
import * as os from 'node:os';
|
|
4
|
-
import * as path from 'node:path';
|
|
5
|
-
import * as process from 'node:process';
|
|
6
|
-
const REMIX_SKILLS_CACHE_VERSION = 1;
|
|
7
|
-
const REMIX_SKILLS_CACHE_REPO = 'remix-run/remix';
|
|
8
|
-
const REMIX_SKILLS_CACHE_REF = 'main';
|
|
9
|
-
export function createSkillsCacheManifest(skillsDir, skills) {
|
|
10
|
-
return {
|
|
11
|
-
ref: REMIX_SKILLS_CACHE_REF,
|
|
12
|
-
repo: REMIX_SKILLS_CACHE_REPO,
|
|
13
|
-
skills,
|
|
14
|
-
skillsDir: path.resolve(skillsDir),
|
|
15
|
-
version: REMIX_SKILLS_CACHE_VERSION,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
export function getSkillsCacheFilePath(skillsDir) {
|
|
19
|
-
let cacheKey = crypto.createHash('sha256').update(path.resolve(skillsDir)).digest('hex');
|
|
20
|
-
return path.join(getSkillsCacheDir(), `${cacheKey}.json`);
|
|
21
|
-
}
|
|
22
|
-
export async function readSkillsCache(skillsDir) {
|
|
23
|
-
try {
|
|
24
|
-
let filePath = getSkillsCacheFilePath(skillsDir);
|
|
25
|
-
let raw = JSON.parse(await fs.readFile(filePath, 'utf8'));
|
|
26
|
-
return isSkillsCacheManifest(raw, skillsDir) ? raw : null;
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
if (error instanceof SyntaxError) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
let nodeError = error;
|
|
33
|
-
if (nodeError.code === 'ENOENT') {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export async function writeSkillsCache(skillsDir, manifest) {
|
|
40
|
-
let filePath = getSkillsCacheFilePath(skillsDir);
|
|
41
|
-
let tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
42
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
43
|
-
await fs.writeFile(tempPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
|
44
|
-
await fs.rename(tempPath, filePath);
|
|
45
|
-
}
|
|
46
|
-
function getSkillsCacheDir() {
|
|
47
|
-
if (process.platform === 'win32') {
|
|
48
|
-
let localAppData = process.env.LOCALAPPDATA ?? path.join(os.homedir(), 'AppData', 'Local');
|
|
49
|
-
return path.join(localAppData, 'remix', 'Cache', 'skills');
|
|
50
|
-
}
|
|
51
|
-
if (process.platform === 'darwin') {
|
|
52
|
-
return path.join(process.env.HOME ?? os.homedir(), 'Library', 'Caches', 'remix', 'cli', 'skills');
|
|
53
|
-
}
|
|
54
|
-
let xdgCacheHome = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
|
|
55
|
-
return path.join(xdgCacheHome, 'remix', 'cli', 'skills');
|
|
56
|
-
}
|
|
57
|
-
function isSkillsCacheManifest(value, skillsDir) {
|
|
58
|
-
if (typeof value !== 'object' || value == null) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
if (Reflect.get(value, 'version') !== REMIX_SKILLS_CACHE_VERSION ||
|
|
62
|
-
Reflect.get(value, 'repo') !== REMIX_SKILLS_CACHE_REPO ||
|
|
63
|
-
Reflect.get(value, 'ref') !== REMIX_SKILLS_CACHE_REF ||
|
|
64
|
-
Reflect.get(value, 'skillsDir') !== path.resolve(skillsDir)) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
let skills = Reflect.get(value, 'skills');
|
|
68
|
-
if (typeof skills !== 'object' || skills == null) {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
for (let skillEntry of Object.values(skills)) {
|
|
72
|
-
if (typeof skillEntry !== 'object' || skillEntry == null) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
let files = Reflect.get(skillEntry, 'files');
|
|
76
|
-
if (typeof files !== 'object' || files == null) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
for (let fileEntry of Object.values(files)) {
|
|
80
|
-
if (typeof fileEntry !== 'object' ||
|
|
81
|
-
fileEntry == null ||
|
|
82
|
-
typeof Reflect.get(fileEntry, 'localHash') !== 'string' ||
|
|
83
|
-
typeof Reflect.get(fileEntry, 'remoteSha') !== 'string') {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return true;
|
|
89
|
-
}
|
package/dist/lib/skills.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { type StepProgressReporter } from './reporter.ts';
|
|
2
|
-
export interface SkillChange {
|
|
3
|
-
action: 'add' | 'replace';
|
|
4
|
-
name: string;
|
|
5
|
-
}
|
|
6
|
-
export interface SkillStatusEntry {
|
|
7
|
-
name: string;
|
|
8
|
-
state: 'installed' | 'missing' | 'outdated';
|
|
9
|
-
}
|
|
10
|
-
interface SkillsResult {
|
|
11
|
-
entries: SkillStatusEntry[];
|
|
12
|
-
projectRoot: string;
|
|
13
|
-
skillsDir: string;
|
|
14
|
-
}
|
|
15
|
-
export interface SkillsOverview extends SkillsResult {
|
|
16
|
-
}
|
|
17
|
-
export interface SkillsInstallResult extends SkillsResult {
|
|
18
|
-
appliedChanges: SkillChange[];
|
|
19
|
-
}
|
|
20
|
-
export interface SkillsOptions {
|
|
21
|
-
progress?: SkillsProgressReporter;
|
|
22
|
-
skillsDir?: string;
|
|
23
|
-
}
|
|
24
|
-
export type SkillsInstallPhase = 'resolve-project-root' | 'fetch-remix-skills-metadata' | 'read-local-skills-cache' | 'compare-local-skills' | 'download-remix-skills-archive' | 'write-updated-skills';
|
|
25
|
-
export type SkillsProgressReporter = StepProgressReporter<SkillsInstallPhase>;
|
|
26
|
-
type FetchImpl = typeof fetch;
|
|
27
|
-
export declare function getSkillsOverview(cwd?: string, fetchImpl?: FetchImpl, options?: SkillsOptions): Promise<SkillsOverview>;
|
|
28
|
-
export declare function installRemixSkills(cwd?: string, fetchImpl?: FetchImpl, options?: SkillsOptions): Promise<SkillsInstallResult>;
|
|
29
|
-
export {};
|
|
30
|
-
//# sourceMappingURL=skills.d.ts.map
|
package/dist/lib/skills.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"AASA,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAe1E,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,KAAK,GAAG,SAAS,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAA;CAC5C;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;CAAG;AAEvD,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,cAAc,EAAE,WAAW,EAAE,CAAA;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,sBAAsB,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,kBAAkB,GAC1B,sBAAsB,GACtB,6BAA6B,GAC7B,yBAAyB,GACzB,sBAAsB,GACtB,+BAA+B,GAC/B,sBAAsB,CAAA;AAE1B,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC,kBAAkB,CAAC,CAAA;AA4C7E,KAAK,SAAS,GAAG,OAAO,KAAK,CAAA;AAE7B,wBAAsB,iBAAiB,CACrC,GAAG,GAAE,MAAsB,EAC3B,SAAS,GAAE,SAA4B,EACvC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAOzB;AAED,wBAAsB,kBAAkB,CACtC,GAAG,GAAE,MAAsB,EAC3B,SAAS,GAAE,SAA4B,EACvC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA4C9B"}
|