@autono/open-pages 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.
- package/LICENSE +23 -0
- package/README.md +108 -0
- package/bin.js +2 -0
- package/dist/build-TP72kiw7.js +35 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +100 -0
- package/dist/config-C9or4m4J.d.ts +23 -0
- package/dist/config-L0IbktJ0.js +3135 -0
- package/dist/design-C13iz9_4.js +35 -0
- package/dist/dev-I2IyEh5W.js +97 -0
- package/dist/export-B-kBRWB1.js +4 -0
- package/dist/export-ic28osQP.js +131 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +3 -0
- package/dist/locale/index.d.ts +24 -0
- package/dist/locale/index.js +881 -0
- package/dist/open-pages-plugin-D_DN_zjh.js +632 -0
- package/dist/preview-BrDuvgAN.js +21 -0
- package/dist/sync-Be_hxSOF.js +139 -0
- package/dist/sync-lKEXyPOh.js +3 -0
- package/dist/types-C5NCdDT-.d.ts +219 -0
- package/dist/update-CV62NhBT.js +37 -0
- package/dist/update-package-Cxt57pz7.js +152 -0
- package/dist/version-B6AiiGvT.js +26 -0
- package/dist/version-CeffgdfZ.js +3 -0
- package/dist/vite/index.d.ts +14 -0
- package/dist/vite/index.js +7 -0
- package/env.d.ts +59 -0
- package/package.json +106 -0
- package/skills/apply-comments/SKILL.md +86 -0
- package/skills/create-page/SKILL.md +92 -0
- package/skills/create-theme/SKILL.md +223 -0
- package/skills/current-page/SKILL.md +106 -0
- package/skills/page-authoring/SKILL.md +148 -0
- package/skills/page-authoring/references/assets-and-fonts.md +85 -0
- package/skills/page-authoring/references/html-pages.md +65 -0
- package/skills/page-authoring/references/interactivity.md +77 -0
- package/skills/page-authoring/references/layout-and-responsive.md +71 -0
- package/skills/page-authoring/references/typography-and-color.md +60 -0
- package/src/app/app.tsx +45 -0
- package/src/app/components/asset-view.tsx +1665 -0
- package/src/app/components/command/command-menu.tsx +227 -0
- package/src/app/components/command/command.tsx +142 -0
- package/src/app/components/command/home-command-menu.tsx +96 -0
- package/src/app/components/icon-tooltip.tsx +34 -0
- package/src/app/components/language-toggle.tsx +46 -0
- package/src/app/components/sidebar/folder-item.tsx +269 -0
- package/src/app/components/sidebar/icon-picker.tsx +61 -0
- package/src/app/components/sidebar/sidebar-footer.tsx +139 -0
- package/src/app/components/sidebar/sidebar.tsx +302 -0
- package/src/app/components/theme-toggle.tsx +66 -0
- package/src/app/components/themes/theme-detail.tsx +226 -0
- package/src/app/components/themes/themes-gallery.tsx +104 -0
- package/src/app/components/ui/badge.tsx +48 -0
- package/src/app/components/ui/button.tsx +93 -0
- package/src/app/components/ui/card.tsx +92 -0
- package/src/app/components/ui/context-menu.tsx +247 -0
- package/src/app/components/ui/dialog.tsx +155 -0
- package/src/app/components/ui/dropdown-menu.tsx +267 -0
- package/src/app/components/ui/input.tsx +25 -0
- package/src/app/components/ui/label.tsx +21 -0
- package/src/app/components/ui/popover.tsx +82 -0
- package/src/app/components/ui/progress.tsx +33 -0
- package/src/app/components/ui/scroll-area.tsx +53 -0
- package/src/app/components/ui/select.tsx +195 -0
- package/src/app/components/ui/separator.tsx +26 -0
- package/src/app/components/ui/slider.tsx +68 -0
- package/src/app/components/ui/sonner.tsx +48 -0
- package/src/app/components/ui/tabs.tsx +79 -0
- package/src/app/components/ui/textarea.tsx +22 -0
- package/src/app/components/ui/toggle-group.tsx +84 -0
- package/src/app/components/ui/toggle.tsx +45 -0
- package/src/app/components/ui/tooltip.tsx +75 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/frame/inspect.ts +140 -0
- package/src/app/frame/main.tsx +91 -0
- package/src/app/frame.html +12 -0
- package/src/app/index.html +13 -0
- package/src/app/lib/asset-filter.test.ts +176 -0
- package/src/app/lib/asset-filter.ts +80 -0
- package/src/app/lib/assets.ts +257 -0
- package/src/app/lib/design.ts +58 -0
- package/src/app/lib/folders.ts +239 -0
- package/src/app/lib/frame.ts +38 -0
- package/src/app/lib/locale-store.ts +67 -0
- package/src/app/lib/page-thumb.tsx +46 -0
- package/src/app/lib/pages.ts +28 -0
- package/src/app/lib/sdk.ts +43 -0
- package/src/app/lib/themes.ts +22 -0
- package/src/app/lib/use-locale.ts +8 -0
- package/src/app/lib/use-page-module.ts +48 -0
- package/src/app/lib/use-page-titles.ts +29 -0
- package/src/app/lib/use-restart-server.ts +78 -0
- package/src/app/lib/utils.test.ts +25 -0
- package/src/app/lib/utils.ts +6 -0
- package/src/app/main.tsx +14 -0
- package/src/app/routes/assets.tsx +9 -0
- package/src/app/routes/home-shell.tsx +252 -0
- package/src/app/routes/home.tsx +846 -0
- package/src/app/routes/page.tsx +329 -0
- package/src/app/routes/themes.tsx +34 -0
- package/src/app/styles.css +405 -0
- package/src/app/virtual.d.ts +53 -0
- package/src/locale/en.ts +218 -0
- package/src/locale/format.ts +12 -0
- package/src/locale/index.ts +6 -0
- package/src/locale/ja.ts +221 -0
- package/src/locale/types.ts +215 -0
- package/src/locale/zh-cn.ts +218 -0
- package/src/locale/zh-tw.ts +218 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { cp, lstat, mkdir, readFile, readdir, readlink, rm, symlink } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
|
|
7
|
+
//#region src/cli/sync.ts
|
|
8
|
+
async function detectSkillsDrift(skillsDir) {
|
|
9
|
+
if (!existsSync(skillsDir)) return [];
|
|
10
|
+
const cwd = process.cwd();
|
|
11
|
+
const agentsSkillsDir = path.join(cwd, ".agents", "skills");
|
|
12
|
+
const skillNames = (await readdir(skillsDir, { withFileTypes: true })).filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
13
|
+
const results = [];
|
|
14
|
+
for (const name of skillNames) {
|
|
15
|
+
const src = path.join(skillsDir, name);
|
|
16
|
+
const dst = path.join(agentsSkillsDir, name);
|
|
17
|
+
const srcHash = await hashDir(src);
|
|
18
|
+
const dstHash = existsSync(dst) ? await hashDir(dst) : null;
|
|
19
|
+
let status;
|
|
20
|
+
if (dstHash === null) status = "added";
|
|
21
|
+
else if (dstHash !== srcHash) status = "updated";
|
|
22
|
+
else status = "unchanged";
|
|
23
|
+
results.push({
|
|
24
|
+
name,
|
|
25
|
+
status
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return results;
|
|
29
|
+
}
|
|
30
|
+
async function syncSkills(skillsDir, opts = {}) {
|
|
31
|
+
const { dryRun = false } = opts;
|
|
32
|
+
if (!existsSync(skillsDir)) throw new Error(`Built-in skills directory missing at ${skillsDir}. The @autono/open-pages package may be corrupt — try reinstalling.`);
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
const agentsSkillsDir = path.join(cwd, ".agents", "skills");
|
|
35
|
+
const claudeSkillsDir = path.join(cwd, ".claude", "skills");
|
|
36
|
+
const results = await detectSkillsDrift(skillsDir);
|
|
37
|
+
if (results.length === 0) {
|
|
38
|
+
process.stdout.write(chalk.yellow("No skills found to sync.\n"));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
for (const { name, status } of results) {
|
|
42
|
+
const src = path.join(skillsDir, name);
|
|
43
|
+
const dst = path.join(agentsSkillsDir, name);
|
|
44
|
+
if (dryRun) continue;
|
|
45
|
+
if (status === "unchanged") {
|
|
46
|
+
await ensureClaudeSymlink(claudeSkillsDir, name);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
await mkdir(path.dirname(dst), { recursive: true });
|
|
50
|
+
if (existsSync(dst)) await rm(dst, {
|
|
51
|
+
recursive: true,
|
|
52
|
+
force: true
|
|
53
|
+
});
|
|
54
|
+
await cp(src, dst, { recursive: true });
|
|
55
|
+
await ensureClaudeSymlink(claudeSkillsDir, name);
|
|
56
|
+
}
|
|
57
|
+
printSummary(results, dryRun);
|
|
58
|
+
}
|
|
59
|
+
async function ensureClaudeSymlink(claudeSkillsDir, name) {
|
|
60
|
+
await mkdir(claudeSkillsDir, { recursive: true });
|
|
61
|
+
const linkPath = path.join(claudeSkillsDir, name);
|
|
62
|
+
const target = path.join("..", "..", ".agents", "skills", name);
|
|
63
|
+
if (existsSync(linkPath)) try {
|
|
64
|
+
const stat = await lstat(linkPath);
|
|
65
|
+
if (stat.isSymbolicLink()) {
|
|
66
|
+
const current = await readlink(linkPath);
|
|
67
|
+
if (current === target) return;
|
|
68
|
+
}
|
|
69
|
+
await rm(linkPath, {
|
|
70
|
+
recursive: true,
|
|
71
|
+
force: true
|
|
72
|
+
});
|
|
73
|
+
} catch {
|
|
74
|
+
await rm(linkPath, {
|
|
75
|
+
recursive: true,
|
|
76
|
+
force: true
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
await symlink(target, linkPath, "dir");
|
|
81
|
+
} catch (err) {
|
|
82
|
+
const code = err.code;
|
|
83
|
+
if (code === "EPERM" || code === "EEXIST") {
|
|
84
|
+
const absoluteTarget = path.resolve(claudeSkillsDir, target);
|
|
85
|
+
await cp(absoluteTarget, linkPath, { recursive: true });
|
|
86
|
+
} else throw err;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function hashDir(dir) {
|
|
90
|
+
const hash = createHash("sha256");
|
|
91
|
+
const files = await collectFiles(dir);
|
|
92
|
+
files.sort();
|
|
93
|
+
for (const rel of files) {
|
|
94
|
+
const abs = path.join(dir, rel);
|
|
95
|
+
const data = await readFile(abs);
|
|
96
|
+
hash.update(rel);
|
|
97
|
+
hash.update("\0");
|
|
98
|
+
hash.update(data);
|
|
99
|
+
hash.update("\0");
|
|
100
|
+
}
|
|
101
|
+
return hash.digest("hex");
|
|
102
|
+
}
|
|
103
|
+
async function collectFiles(dir, prefix = "") {
|
|
104
|
+
const out = [];
|
|
105
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
106
|
+
for (const entry of entries) {
|
|
107
|
+
const rel = prefix ? path.join(prefix, entry.name) : entry.name;
|
|
108
|
+
if (entry.isDirectory()) out.push(...await collectFiles(path.join(dir, entry.name), rel));
|
|
109
|
+
else if (entry.isFile()) out.push(rel);
|
|
110
|
+
}
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
function printSummary(results, dryRun) {
|
|
114
|
+
const symbols = {
|
|
115
|
+
added: chalk.green("+"),
|
|
116
|
+
updated: chalk.yellow("~"),
|
|
117
|
+
unchanged: chalk.dim("=")
|
|
118
|
+
};
|
|
119
|
+
const labels = {
|
|
120
|
+
added: chalk.green("added"),
|
|
121
|
+
updated: chalk.yellow("updated"),
|
|
122
|
+
unchanged: chalk.dim("unchanged")
|
|
123
|
+
};
|
|
124
|
+
const header = dryRun ? chalk.bold("Dry run — no files written:") : chalk.bold("Synced built-in skills:");
|
|
125
|
+
process.stdout.write(`${header}\n`);
|
|
126
|
+
for (const { name, status } of results) process.stdout.write(` ${symbols[status]} ${name} ${chalk.dim(`(${labels[status]})`)}\n`);
|
|
127
|
+
const counts = results.reduce((acc, { status }) => {
|
|
128
|
+
acc[status] += 1;
|
|
129
|
+
return acc;
|
|
130
|
+
}, {
|
|
131
|
+
added: 0,
|
|
132
|
+
updated: 0,
|
|
133
|
+
unchanged: 0
|
|
134
|
+
});
|
|
135
|
+
process.stdout.write(chalk.dim(`\n${counts.added} added, ${counts.updated} updated, ${counts.unchanged} unchanged.\n`));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
export { detectSkillsDrift, syncSkills };
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
//#region src/locale/types.d.ts
|
|
2
|
+
type Plural = {
|
|
3
|
+
one: string;
|
|
4
|
+
other: string;
|
|
5
|
+
};
|
|
6
|
+
type Locale = {
|
|
7
|
+
id: 'en' | 'zh-TW' | 'zh-CN' | 'ja';
|
|
8
|
+
common: {
|
|
9
|
+
cancel: string;
|
|
10
|
+
save: string;
|
|
11
|
+
delete: string;
|
|
12
|
+
rename: string;
|
|
13
|
+
move: string;
|
|
14
|
+
add: string;
|
|
15
|
+
done: string;
|
|
16
|
+
tryAgain: string;
|
|
17
|
+
selected: string;
|
|
18
|
+
};
|
|
19
|
+
notFound: {
|
|
20
|
+
eyebrow: string;
|
|
21
|
+
title: string;
|
|
22
|
+
};
|
|
23
|
+
home: {
|
|
24
|
+
appTitle: string;
|
|
25
|
+
draft: string;
|
|
26
|
+
duplicate: string;
|
|
27
|
+
themes: string;
|
|
28
|
+
assets: string;
|
|
29
|
+
folders: string;
|
|
30
|
+
pages: string;
|
|
31
|
+
menu: string;
|
|
32
|
+
newFolder: string;
|
|
33
|
+
folderName: string;
|
|
34
|
+
updateAvailable: string;
|
|
35
|
+
updatePackage: string;
|
|
36
|
+
updatingPackage: string;
|
|
37
|
+
updatePackageDone: string;
|
|
38
|
+
updatePackageFailed: string;
|
|
39
|
+
restartServer: string;
|
|
40
|
+
restartingServer: string;
|
|
41
|
+
restartServerFailed: string;
|
|
42
|
+
changeIcon: string;
|
|
43
|
+
iconEmojiTab: string;
|
|
44
|
+
iconColorTab: string;
|
|
45
|
+
folderActions: string;
|
|
46
|
+
searchPlaceholder: string;
|
|
47
|
+
clearSearch: string;
|
|
48
|
+
sortLabel: string;
|
|
49
|
+
sortByCreatedDesc: string;
|
|
50
|
+
sortByCreatedAsc: string;
|
|
51
|
+
sortByTitleAsc: string;
|
|
52
|
+
sortByTitleDesc: string;
|
|
53
|
+
noMatches: string;
|
|
54
|
+
nothingMatchesPrefix: string;
|
|
55
|
+
nothingMatchesSuffix: string;
|
|
56
|
+
noDocsYet: string;
|
|
57
|
+
createDocHintPrefix: string;
|
|
58
|
+
createDocHintSuffix: string;
|
|
59
|
+
folderEmptyTitle: string;
|
|
60
|
+
folderEmptyHint: string;
|
|
61
|
+
docActions: string;
|
|
62
|
+
moveToFolder: string;
|
|
63
|
+
renameDialogEyebrow: string;
|
|
64
|
+
renameDialogTitle: string;
|
|
65
|
+
renameDialogDescription: string;
|
|
66
|
+
docNamePlaceholder: string;
|
|
67
|
+
moveDialogEyebrow: string;
|
|
68
|
+
moveDialogTitle: string;
|
|
69
|
+
moveDialogDescriptionPrefix: string;
|
|
70
|
+
moveDialogDescriptionSuffix: string;
|
|
71
|
+
deleteDialogEyebrow: string;
|
|
72
|
+
deleteDialogTitle: string;
|
|
73
|
+
deleteDialogDescriptionPrefix: string;
|
|
74
|
+
deleteDialogDescriptionMid: string;
|
|
75
|
+
deleteDialogDescriptionSuffix: string;
|
|
76
|
+
toastFolderCreated: string;
|
|
77
|
+
toastFolderCreateFailed: string;
|
|
78
|
+
toastDocDuplicated: string;
|
|
79
|
+
toastDocDuplicateFailed: string;
|
|
80
|
+
toastDocMoved: string;
|
|
81
|
+
toastDocMoveFailed: string;
|
|
82
|
+
toastFolderDeleted: string;
|
|
83
|
+
toastFolderDeleteFailed: string;
|
|
84
|
+
toastFolderReorderFailed: string;
|
|
85
|
+
pickIcon: string;
|
|
86
|
+
};
|
|
87
|
+
page: {
|
|
88
|
+
loadingEyebrow: string;
|
|
89
|
+
};
|
|
90
|
+
asset: {
|
|
91
|
+
devOnlyMessage: string;
|
|
92
|
+
sectionAria: string;
|
|
93
|
+
eyebrow: string;
|
|
94
|
+
scopeDoc: string;
|
|
95
|
+
scopeGlobal: string;
|
|
96
|
+
fileCount: Plural;
|
|
97
|
+
createdAt: string;
|
|
98
|
+
modifiedAt: string;
|
|
99
|
+
nameColumn: string;
|
|
100
|
+
typeColumn: string;
|
|
101
|
+
sizeColumn: string;
|
|
102
|
+
statusColumn: string;
|
|
103
|
+
sortAria: string;
|
|
104
|
+
sortByColumn: string;
|
|
105
|
+
sortAscending: string;
|
|
106
|
+
sortDescending: string;
|
|
107
|
+
assetSearchPlaceholder: string;
|
|
108
|
+
clearAssetSearch: string;
|
|
109
|
+
usageFilterAria: string;
|
|
110
|
+
usageAll: string;
|
|
111
|
+
usageUsed: string;
|
|
112
|
+
usageUnused: string;
|
|
113
|
+
typeFilterAria: string;
|
|
114
|
+
typeAll: string;
|
|
115
|
+
typeImage: string;
|
|
116
|
+
typeFont: string;
|
|
117
|
+
typeVideo: string;
|
|
118
|
+
typeOther: string;
|
|
119
|
+
gridViewAria: string;
|
|
120
|
+
listViewAria: string;
|
|
121
|
+
gridColumnsAria: string;
|
|
122
|
+
gridColumnsValue: string;
|
|
123
|
+
noMatchingAssets: string;
|
|
124
|
+
noMatchingAssetsHint: string;
|
|
125
|
+
clearFilters: string;
|
|
126
|
+
searchLogos: string;
|
|
127
|
+
upload: string;
|
|
128
|
+
dropToUpload: string;
|
|
129
|
+
loading: string;
|
|
130
|
+
noAssetsYet: string;
|
|
131
|
+
noAssetsHintPrefix: string;
|
|
132
|
+
noAssetsHintSuffix: string;
|
|
133
|
+
nameAlreadyExists: string;
|
|
134
|
+
previewAria: string;
|
|
135
|
+
actionsAria: string;
|
|
136
|
+
previewMenuItem: string;
|
|
137
|
+
renameMenuItem: string;
|
|
138
|
+
deleteMenuItem: string;
|
|
139
|
+
conflictTitle: string;
|
|
140
|
+
conflictDescription: string;
|
|
141
|
+
conflictReplace: string;
|
|
142
|
+
conflictRenameCopy: string;
|
|
143
|
+
deleteAssetTitle: string;
|
|
144
|
+
deleteAssetDescription: string;
|
|
145
|
+
deleteAssetInUseDescription: string;
|
|
146
|
+
deleteAssetInUseHint: string;
|
|
147
|
+
deleteAndRevert: string;
|
|
148
|
+
toastRevertFailed: string;
|
|
149
|
+
toastDeletedWithRevert: string;
|
|
150
|
+
noPreview: string;
|
|
151
|
+
importHintComment: string;
|
|
152
|
+
importHintSemi: string;
|
|
153
|
+
logoSearchTitle: string;
|
|
154
|
+
logoSearchPoweredByPrefix: string;
|
|
155
|
+
logoSearchPlaceholder: string;
|
|
156
|
+
logoSearchErrorTitle: string;
|
|
157
|
+
logoSearchErrorBody: string;
|
|
158
|
+
logoSearchNoResults: string;
|
|
159
|
+
logoSearchEmpty: string;
|
|
160
|
+
logoSearchEmptyHintPrefix: string;
|
|
161
|
+
logoSearchEmptyHintSuffix: string;
|
|
162
|
+
logoVariantLight: string;
|
|
163
|
+
logoVariantDark: string;
|
|
164
|
+
toastUploadFailed: string;
|
|
165
|
+
toastReplaced: string;
|
|
166
|
+
toastUploadedAs: string;
|
|
167
|
+
toastUploaded: string;
|
|
168
|
+
toastRenameFailed: string;
|
|
169
|
+
toastRenamed: string;
|
|
170
|
+
toastDeleteFailed: string;
|
|
171
|
+
toastDeleted: string;
|
|
172
|
+
toastDownloadFailed: string;
|
|
173
|
+
toastSearchFailed: string;
|
|
174
|
+
};
|
|
175
|
+
commandMenu: {
|
|
176
|
+
trigger: string;
|
|
177
|
+
triggerAria: string;
|
|
178
|
+
triggerTooltip: string;
|
|
179
|
+
placeholder: string;
|
|
180
|
+
empty: string;
|
|
181
|
+
groupDocs: string;
|
|
182
|
+
groupFolders: string;
|
|
183
|
+
groupNavigation: string;
|
|
184
|
+
groupAppearance: string;
|
|
185
|
+
groupDeveloper: string;
|
|
186
|
+
themeItem: string;
|
|
187
|
+
languageItem: string;
|
|
188
|
+
hintNavigate: string;
|
|
189
|
+
hintSelect: string;
|
|
190
|
+
hintClose: string;
|
|
191
|
+
};
|
|
192
|
+
themeToggle: {
|
|
193
|
+
toggleAria: string;
|
|
194
|
+
title: string;
|
|
195
|
+
light: string;
|
|
196
|
+
dark: string;
|
|
197
|
+
system: string;
|
|
198
|
+
};
|
|
199
|
+
languageToggle: {
|
|
200
|
+
toggleAria: string;
|
|
201
|
+
title: string;
|
|
202
|
+
};
|
|
203
|
+
themes: {
|
|
204
|
+
title: string;
|
|
205
|
+
noThemesTitle: string;
|
|
206
|
+
noThemesHintPrefix: string;
|
|
207
|
+
noThemesHintSuffix: string;
|
|
208
|
+
noDemoYet: string;
|
|
209
|
+
noDemoHintPrefix: string;
|
|
210
|
+
noDemoHintSuffix: string;
|
|
211
|
+
backToGallery: string;
|
|
212
|
+
openThemeAria: string;
|
|
213
|
+
usedBy: string;
|
|
214
|
+
usedByEmpty: string;
|
|
215
|
+
expandPromptAria: string;
|
|
216
|
+
collapsePromptAria: string;
|
|
217
|
+
};
|
|
218
|
+
}; //#endregion
|
|
219
|
+
export { Locale, Plural };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PKG, detectPackageManager, fetchLatest, formatCommand, isOutdated, localOpenPagesCommand, runCommand, updateCommandFor } from "./update-package-Cxt57pz7.js";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
//#region src/cli/update.ts
|
|
7
|
+
async function installedVersion(cwd) {
|
|
8
|
+
try {
|
|
9
|
+
const raw = await readFile(path.join(cwd, "node_modules", ...PKG.split("/"), "package.json"), "utf8");
|
|
10
|
+
return JSON.parse(raw).version ?? null;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async function update(opts) {
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
const [latest, installed] = await Promise.all([fetchLatest(), installedVersion(cwd)]);
|
|
18
|
+
const current = installed ?? opts.current;
|
|
19
|
+
if (latest && !isOutdated(current, latest) && !opts.force) {
|
|
20
|
+
process.stdout.write(`${chalk.green("✓")} ${PKG} ${chalk.bold(current)} is the latest version.\n`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const target = latest ? chalk.bold(latest) : chalk.bold("latest");
|
|
24
|
+
process.stdout.write(`Updating ${PKG} ${chalk.dim(current)} → ${target}\n`);
|
|
25
|
+
const packageManager = await detectPackageManager(cwd);
|
|
26
|
+
const install = await updateCommandFor(packageManager, cwd);
|
|
27
|
+
process.stdout.write(chalk.dim(`$ ${formatCommand(install)}\n`));
|
|
28
|
+
await runCommand(install, cwd, { stdio: "inherit" });
|
|
29
|
+
if (opts.skills !== false) {
|
|
30
|
+
process.stdout.write(chalk.dim("$ open-pages sync:skills\n"));
|
|
31
|
+
await runCommand(localOpenPagesCommand(cwd, ["sync:skills"]), cwd, { stdio: "inherit" });
|
|
32
|
+
}
|
|
33
|
+
process.stdout.write(`${chalk.green("✓")} Updated ${PKG} to ${target}. Restart \`open-pages dev\` to use it.\n`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
export { update };
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
|
|
5
|
+
//#region src/shared/update-package.ts
|
|
6
|
+
const PKG = "@autono/open-pages";
|
|
7
|
+
const CACHE_TTL_MS = 10 * 60 * 1e3;
|
|
8
|
+
const COMMAND_TIMEOUT_MS = 3e5;
|
|
9
|
+
let cache = null;
|
|
10
|
+
function parseSemver(v) {
|
|
11
|
+
const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(v.trim());
|
|
12
|
+
if (!m) return null;
|
|
13
|
+
return [
|
|
14
|
+
Number(m[1]),
|
|
15
|
+
Number(m[2]),
|
|
16
|
+
Number(m[3])
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
function isOutdated(current, latest) {
|
|
20
|
+
const a = parseSemver(current);
|
|
21
|
+
const b = parseSemver(latest);
|
|
22
|
+
if (!a || !b) return false;
|
|
23
|
+
for (let i = 0; i < 3; i++) {
|
|
24
|
+
if (b[i] > a[i]) return true;
|
|
25
|
+
if (b[i] < a[i]) return false;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
/** npm `latest` dist-tag, cached for 10 minutes. Network failures yield null. */
|
|
30
|
+
async function fetchLatest(now = Date.now()) {
|
|
31
|
+
if (cache && now - cache.at < CACHE_TTL_MS) return cache.latest;
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG}/latest`, {
|
|
34
|
+
signal: AbortSignal.timeout(3e3),
|
|
35
|
+
headers: { accept: "application/json" }
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok) throw new Error(`registry ${res.status}`);
|
|
38
|
+
const body = await res.json();
|
|
39
|
+
const latest = typeof body.version === "string" ? body.version : null;
|
|
40
|
+
cache = {
|
|
41
|
+
at: now,
|
|
42
|
+
latest
|
|
43
|
+
};
|
|
44
|
+
return latest;
|
|
45
|
+
} catch {
|
|
46
|
+
return cache?.latest ?? null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function invalidateLatestCache() {
|
|
50
|
+
cache = null;
|
|
51
|
+
}
|
|
52
|
+
async function fileExists(file) {
|
|
53
|
+
try {
|
|
54
|
+
await fs.access(file);
|
|
55
|
+
return true;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function detectPackageManager(cwd) {
|
|
61
|
+
if (await fileExists(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
62
|
+
if (await fileExists(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
63
|
+
if (await fileExists(path.join(cwd, "bun.lockb"))) return "bun";
|
|
64
|
+
if (await fileExists(path.join(cwd, "bun.lock"))) return "bun";
|
|
65
|
+
if (await fileExists(path.join(cwd, "package-lock.json"))) return "npm";
|
|
66
|
+
const ua = process.env.npm_config_user_agent ?? "";
|
|
67
|
+
if (ua.startsWith("pnpm")) return "pnpm";
|
|
68
|
+
if (ua.startsWith("yarn")) return "yarn";
|
|
69
|
+
if (ua.startsWith("bun")) return "bun";
|
|
70
|
+
return "npm";
|
|
71
|
+
}
|
|
72
|
+
async function updateCommandFor(packageManager, cwd) {
|
|
73
|
+
switch (packageManager) {
|
|
74
|
+
case "pnpm": {
|
|
75
|
+
const workspaceRoot = await fileExists(path.join(cwd, "pnpm-workspace.yaml"));
|
|
76
|
+
return {
|
|
77
|
+
cmd: "pnpm",
|
|
78
|
+
args: workspaceRoot ? [
|
|
79
|
+
"add",
|
|
80
|
+
"--workspace-root",
|
|
81
|
+
`${PKG}@latest`
|
|
82
|
+
] : ["add", `${PKG}@latest`]
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
case "yarn": return {
|
|
86
|
+
cmd: "yarn",
|
|
87
|
+
args: ["add", `${PKG}@latest`]
|
|
88
|
+
};
|
|
89
|
+
case "bun": return {
|
|
90
|
+
cmd: "bun",
|
|
91
|
+
args: ["add", `${PKG}@latest`]
|
|
92
|
+
};
|
|
93
|
+
case "npm": return {
|
|
94
|
+
cmd: "npm",
|
|
95
|
+
args: ["install", `${PKG}@latest`]
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The freshly installed package's own CLI, so skills come from the new
|
|
101
|
+
* version rather than whatever process is driving the update.
|
|
102
|
+
*/
|
|
103
|
+
function localOpenPagesCommand(cwd, args) {
|
|
104
|
+
const bin = path.join(cwd, "node_modules", ...PKG.split("/"), "bin.js");
|
|
105
|
+
return {
|
|
106
|
+
cmd: process.execPath,
|
|
107
|
+
args: [bin, ...args],
|
|
108
|
+
shell: false
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function formatCommand(spec) {
|
|
112
|
+
return [spec.cmd, ...spec.args].join(" ");
|
|
113
|
+
}
|
|
114
|
+
async function runCommand(spec, cwd, opts = {}) {
|
|
115
|
+
await new Promise((resolve, reject) => {
|
|
116
|
+
const child = spawn(spec.cmd, spec.args, {
|
|
117
|
+
cwd,
|
|
118
|
+
env: process.env,
|
|
119
|
+
shell: spec.shell ?? process.platform === "win32",
|
|
120
|
+
stdio: opts.stdio ?? [
|
|
121
|
+
"ignore",
|
|
122
|
+
"ignore",
|
|
123
|
+
"pipe"
|
|
124
|
+
]
|
|
125
|
+
});
|
|
126
|
+
let stderr = "";
|
|
127
|
+
const timer = setTimeout(() => {
|
|
128
|
+
child.kill();
|
|
129
|
+
reject(new Error(`${formatCommand(spec)} timed out`));
|
|
130
|
+
}, COMMAND_TIMEOUT_MS);
|
|
131
|
+
child.stderr?.on("data", (chunk) => {
|
|
132
|
+
stderr += chunk.toString("utf8");
|
|
133
|
+
if (stderr.length > 2e3) stderr = stderr.slice(-2e3);
|
|
134
|
+
});
|
|
135
|
+
child.on("error", (err) => {
|
|
136
|
+
clearTimeout(timer);
|
|
137
|
+
reject(err);
|
|
138
|
+
});
|
|
139
|
+
child.on("close", (code) => {
|
|
140
|
+
clearTimeout(timer);
|
|
141
|
+
if (code === 0) {
|
|
142
|
+
resolve();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const detail = stderr.trim();
|
|
146
|
+
reject(new Error(detail || `${formatCommand(spec)} exited with code ${code ?? "unknown"}`));
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
export { PKG, detectPackageManager, fetchLatest, formatCommand, invalidateLatestCache, isOutdated, localOpenPagesCommand, runCommand, updateCommandFor };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
//#region src/vite/version.ts
|
|
6
|
+
function findPackageRoot(fromFile) {
|
|
7
|
+
let dir = path.dirname(fromFile);
|
|
8
|
+
while (dir !== path.dirname(dir)) {
|
|
9
|
+
if (existsSync(path.join(dir, "package.json"))) return dir;
|
|
10
|
+
dir = path.dirname(dir);
|
|
11
|
+
}
|
|
12
|
+
throw new Error(`Could not find package.json walking up from ${fromFile}`);
|
|
13
|
+
}
|
|
14
|
+
const PKG_ROOT = findPackageRoot(fileURLToPath(import.meta.url));
|
|
15
|
+
const APP_ROOT = path.join(PKG_ROOT, "src", "app");
|
|
16
|
+
function readCoreVersion() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = readFileSync(path.join(PKG_ROOT, "package.json"), "utf8");
|
|
19
|
+
return JSON.parse(raw).version ?? "0.0.0";
|
|
20
|
+
} catch {
|
|
21
|
+
return "0.0.0";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { APP_ROOT, PKG_ROOT, readCoreVersion };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import "../types-C5NCdDT-.js";
|
|
2
|
+
import { OpenPagesConfig } from "../config-C9or4m4J.js";
|
|
3
|
+
import { InlineConfig } from "vite";
|
|
4
|
+
|
|
5
|
+
//#region src/vite/config.d.ts
|
|
6
|
+
type CreateViteConfigOptions = {
|
|
7
|
+
userCwd: string;
|
|
8
|
+
config?: OpenPagesConfig;
|
|
9
|
+
mode?: 'serve' | 'build';
|
|
10
|
+
};
|
|
11
|
+
declare function createViteConfig(opts: CreateViteConfigOptions): Promise<InlineConfig>;
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { createViteConfig };
|
package/env.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Ambient module declarations for assets imported from `pages/<id>/assets/`.
|
|
2
|
+
// Mirrors Vite's default asset handling (default export = resolved URL).
|
|
3
|
+
//
|
|
4
|
+
// Consumers opt in via tsconfig:
|
|
5
|
+
//
|
|
6
|
+
// { "compilerOptions": { "types": ["@autono/open-pages/env"] } }
|
|
7
|
+
|
|
8
|
+
declare module '*.svg' {
|
|
9
|
+
const src: string;
|
|
10
|
+
export default src;
|
|
11
|
+
}
|
|
12
|
+
declare module '*.png' {
|
|
13
|
+
const src: string;
|
|
14
|
+
export default src;
|
|
15
|
+
}
|
|
16
|
+
declare module '*.jpg' {
|
|
17
|
+
const src: string;
|
|
18
|
+
export default src;
|
|
19
|
+
}
|
|
20
|
+
declare module '*.jpeg' {
|
|
21
|
+
const src: string;
|
|
22
|
+
export default src;
|
|
23
|
+
}
|
|
24
|
+
declare module '*.webp' {
|
|
25
|
+
const src: string;
|
|
26
|
+
export default src;
|
|
27
|
+
}
|
|
28
|
+
declare module '*.gif' {
|
|
29
|
+
const src: string;
|
|
30
|
+
export default src;
|
|
31
|
+
}
|
|
32
|
+
declare module '*.avif' {
|
|
33
|
+
const src: string;
|
|
34
|
+
export default src;
|
|
35
|
+
}
|
|
36
|
+
declare module '*.mp4' {
|
|
37
|
+
const src: string;
|
|
38
|
+
export default src;
|
|
39
|
+
}
|
|
40
|
+
declare module '*.webm' {
|
|
41
|
+
const src: string;
|
|
42
|
+
export default src;
|
|
43
|
+
}
|
|
44
|
+
declare module '*.woff' {
|
|
45
|
+
const src: string;
|
|
46
|
+
export default src;
|
|
47
|
+
}
|
|
48
|
+
declare module '*.woff2' {
|
|
49
|
+
const src: string;
|
|
50
|
+
export default src;
|
|
51
|
+
}
|
|
52
|
+
declare module '*.ttf' {
|
|
53
|
+
const src: string;
|
|
54
|
+
export default src;
|
|
55
|
+
}
|
|
56
|
+
declare module '*.otf' {
|
|
57
|
+
const src: string;
|
|
58
|
+
export default src;
|
|
59
|
+
}
|