@hitch42/applet 0.1.1-beta.8 → 0.1.1-beta.9
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/dist/_internal/client.js +120 -11
- package/dist/_internal/log-context.d.ts +34 -0
- package/dist/_internal/log-context.js +2 -0
- package/dist/_internal/server.d.ts +1 -1
- package/dist/_internal/server.js +112 -57
- package/dist/applet.js +12 -12
- package/dist/build-Bh_S5BUv.js +2 -0
- package/dist/{build-DANx9Hgg.js → build-CEfFoIZZ.js} +1 -1
- package/dist/{ci-5qWl7lT3.js → ci-BKw14X2h.js} +14 -13
- package/dist/client.d.ts +3 -3
- package/dist/{contract-rP_eV9PK.d.ts → contract-CsUpTBe0.d.ts} +1 -1
- package/dist/{deploy-MQWLG2EA.js → deploy-wGYjwXrx.js} +139 -88
- package/dist/{generate-BxYHdoAQ.js → generate-BEIYs17x.js} +65 -28
- package/dist/generate-Dox-OYt6.js +2 -0
- package/dist/headers-DkNr9MLJ.js +17 -0
- package/dist/index.d.ts +23 -22
- package/dist/index.js +2 -1
- package/dist/{init-jDEgYIXg.js → init-6oGPM46R.js} +15 -17
- package/dist/{load-config-BYSxDVAl.js → load-config-xEdTXs0y.js} +2 -2
- package/dist/log-context-zu8U9Sjm.js +73 -0
- package/dist/{login-C7RKmmTe.js → login-CUx3TmFQ.js} +1 -1
- package/dist/{logs-DgjgAxj2.js → logs-DSjuEN0Q.js} +20 -22
- package/dist/{manifest-DD_SGkS6.d.ts → manifest-C6_F4bL8.d.ts} +5 -1
- package/dist/{manifest-Bp87Uz0a.js → manifest-CJSL9GuC.js} +20 -4
- package/dist/{project-CbYPtpPq.js → project-BRZGd6xq.js} +199 -18
- package/dist/query-cache-CXmAyLv3.js +82 -0
- package/dist/react.d.ts +3 -2
- package/dist/react.js +98 -80
- package/dist/{schedules-dhU1yyFr.js → schedules-C8_Svr4h.js} +1 -1
- package/dist/server.d.ts +9 -4
- package/dist/server.js +29 -8
- package/dist/{telephony-protocol-DRgiYjqQ.d.ts → telephony-protocol-D-nf3Gca.d.ts} +15 -13
- package/dist/telephony.d.ts +24 -4
- package/dist/telephony.js +135 -16
- package/dist/{upload-YbRKEqR6.d.ts → upload-DKZzz5kW.d.ts} +6 -6
- package/dist/{variables-Bwnr7oxf.js → variables-DT5RyHdH.js} +13 -13
- package/dist/vite.d.ts +3 -60
- package/dist/vite.js +50 -15
- package/dist/{workflow-engine-MogejNfF.js → workflow-engine-BOTzURKM.js} +1 -7
- package/dist/{workspace-XVtM12ZC.js → workspace-D0dnnlxL.js} +33 -38
- package/package.json +13 -5
- package/scaffold/.agents/skills/hitch-applets/SKILL.md +30 -4
- package/scaffold/.agents/skills/hitch-applets/references/manifest.md +8 -0
- package/scaffold/.agents/skills/hitch-applets/references/markdown.md +2 -0
- package/scaffold/.agents/skills/hitch-applets/references/records.md +23 -1
- package/scaffold/.agents/skills/hitch-data/SKILL.md +2 -1
- package/scaffold/.agents/skills/hitch-data/references/attributes.md +7 -1
- package/scaffold/.agents/skills/hitch-data/references/limits.md +13 -13
- package/scaffold/.agents/skills/hitch-theory/SKILL.md +3 -2
- package/scaffold/.agents/skills/react-best-practices/SKILL.md +127 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-effect-event-deps.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-defer-await.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-dependencies.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/async-parallel.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-analyzable-paths.md +42 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-conditional.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +46 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/bundle-preload.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-event-listeners.md +78 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/scaffold/.agents/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-function-results.md +58 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-cache-storage.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-flatmap-filter.md +51 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-length-check-first.md +50 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-request-idle-callback.md +104 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/scaffold/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-resource-hints.md +81 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-script-defer-async.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rendering-usetransition-loading.md +43 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-no-inline-components.md +75 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/scaffold/.agents/skills/tanstack-query/SKILL.md +136 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/automatic-invalidation-after-mutations.md +124 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/broadcast-realtime-and-multi-tab-synchronization.md +150 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/compose-query-with-tanstack-router-and-start.md +248 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/enforce-query-best-practices-with-eslint.md +167 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/persist-offline-and-restore-caches.md +181 -0
- package/scaffold/.agents/skills/tanstack-query/references/compositions/query-data-and-forms.md +156 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/build-query-abstractions.md +130 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/cancel-queries-and-consume-abort-signals.md +176 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/concurrent-optimistic-updates.md +135 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/coordinate-query-execution.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/design-query-keys-and-options.md +182 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/fetch-and-observe-queries.md +193 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/implement-optimistic-updates-and-cache-writes.md +168 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/paginate-and-build-infinite-queries.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/seed-placeholder-select-and-transform-data.md +188 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/selectors-and-derived-state.md +145 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/tune-defaults-freshness-retries-and-refetching.md +172 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/understand-query-internals-and-observers.md +104 -0
- package/scaffold/.agents/skills/tanstack-query/references/core/write-mutations-and-invalidate-related-queries.md +183 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/debug-with-devtools.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/handle-status-and-errors.md +119 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/shape-data-and-render-efficiently.md +184 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-framework-adapter-reactivity.md +185 -0
- package/scaffold/.agents/skills/tanstack-query/references/framework/use-suspense-and-error-boundaries.md +208 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/migrate-major-versions-and-codemods.md +169 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/prefetch-and-remove-request-waterfalls.md +228 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/setup-query-client-and-providers.md +161 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/ssr-hydration-and-streaming.md +209 -0
- package/scaffold/.agents/skills/tanstack-query/references/lifecycle/test-query-code.md +160 -0
- package/scaffold/.agents/skills/tanstack-router/SKILL.md +134 -0
- package/scaffold/.agents/skills/tanstack-router/references/compositions/router-query.md +412 -0
- package/scaffold/.agents/skills/tanstack-router/references/react-router.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/auth-and-guards.md +495 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/code-splitting.md +318 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/data-loading.md +490 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/index.md +158 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/navigation.md +433 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/not-found-and-errors.md +436 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/path-params.md +383 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/search-params.md +343 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/ssr.md +462 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-core/type-safety.md +493 -0
- package/scaffold/.agents/skills/tanstack-router/references/router-plugin.md +250 -0
- package/scaffold/.agents/skills/tanstack-router/references/virtual-file-routes.md +215 -0
- package/scaffold/.agents/skills/web-design-guidelines/SKILL.md +184 -0
- package/scaffold/.github/workflows/hitch.yml +1 -1
- package/scaffold/AGENTS.md +2 -2
- package/scaffold/applet/src/client/components/ui/alert.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/button.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/checkbox.tsx +1 -1
- package/scaffold/applet/src/client/components/ui/dialog.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/dropdown-menu.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/input-group.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/select.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/sheet.tsx +2 -2
- package/scaffold/applet/src/client/components/ui/spinner.tsx +2 -1
- package/scaffold/applet/src/client/components/ui/tabs.tsx +1 -1
- package/scaffold/applet/src/client/lib/utils.ts +1 -6
- package/scaffold/applet/src/client/styles/globals.css +2 -0
- package/dist/build-CFCKKMn7.js +0 -2
- package/dist/generate-CQ07Hdpo.js +0 -2
|
@@ -1,9 +1,72 @@
|
|
|
1
|
-
import { i as readWorkspaceConfig } from "./workspace-
|
|
2
|
-
import { n as loadAppletSourceDefinition } from "./load-config-
|
|
1
|
+
import { i as readWorkspaceConfig, l as organizationInstanceUrl, s as DEFAULT_INSTANCE_URL } from "./workspace-D0dnnlxL.js";
|
|
2
|
+
import { n as loadAppletSourceDefinition } from "./load-config-xEdTXs0y.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
|
-
import { cp, mkdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
|
|
5
|
+
import { cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "node:fs/promises";
|
|
6
6
|
import { dirname, relative, resolve } from "node:path";
|
|
7
|
+
import { TomlError, parse, stringify } from "smol-toml";
|
|
8
|
+
//#region src/agent-support.ts
|
|
9
|
+
var AgentConfigError = class extends Error {};
|
|
10
|
+
async function ensureAgentConfigs(root, org) {
|
|
11
|
+
const servers = {
|
|
12
|
+
hitch: {
|
|
13
|
+
type: "http",
|
|
14
|
+
url: `${organizationInstanceUrl(DEFAULT_INSTANCE_URL, org)}/mcp`
|
|
15
|
+
},
|
|
16
|
+
"chrome-devtools": {
|
|
17
|
+
type: "stdio",
|
|
18
|
+
command: "pnpx",
|
|
19
|
+
args: ["chrome-devtools-mcp@latest", "--headless"]
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const configs = await Promise.all([{
|
|
23
|
+
path: resolve(root, ".mcp.json"),
|
|
24
|
+
format: "json",
|
|
25
|
+
key: "mcpServers"
|
|
26
|
+
}, {
|
|
27
|
+
path: resolve(root, ".codex/config.toml"),
|
|
28
|
+
format: "toml",
|
|
29
|
+
key: "mcp_servers"
|
|
30
|
+
}].map(async ({ path, format, key }) => {
|
|
31
|
+
const current = existsSync(path) ? await readFile(path, "utf8") : void 0;
|
|
32
|
+
let config;
|
|
33
|
+
let additions;
|
|
34
|
+
try {
|
|
35
|
+
config = z.record(z.string(), z.unknown()).parse(current === void 0 ? {} : format === "json" ? JSON.parse(current) : parse(current, { integersAsBigInt: true }));
|
|
36
|
+
const existing = config[key] === void 0 ? {} : z.record(z.string(), z.unknown()).parse(config[key]);
|
|
37
|
+
const missing = Object.entries(servers).filter(([name]) => !Object.hasOwn(existing, name));
|
|
38
|
+
if (current !== void 0 && missing.length === 0) return void 0;
|
|
39
|
+
additions = Object.fromEntries(missing.map(([name, server]) => [name, format === "json" ? server : Object.fromEntries(Object.entries(server).filter(([field]) => field !== "type"))]));
|
|
40
|
+
config[key] = {
|
|
41
|
+
...existing,
|
|
42
|
+
...additions
|
|
43
|
+
};
|
|
44
|
+
} catch (cause) {
|
|
45
|
+
throw new AgentConfigError(`Invalid agent configuration in ${path}.`, { cause });
|
|
46
|
+
}
|
|
47
|
+
if (format === "json") return {
|
|
48
|
+
path,
|
|
49
|
+
contents: `${JSON.stringify(config, null, 2)}\n`
|
|
50
|
+
};
|
|
51
|
+
const contents = `${current ?? ""}${current ? "\n" : ""}${stringify({ [key]: additions })}`;
|
|
52
|
+
try {
|
|
53
|
+
parse(contents, { integersAsBigInt: true });
|
|
54
|
+
return {
|
|
55
|
+
path,
|
|
56
|
+
contents
|
|
57
|
+
};
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (!(error instanceof TomlError)) throw error;
|
|
60
|
+
return {
|
|
61
|
+
path,
|
|
62
|
+
contents: stringify(config, { numbersAsFloat: true })
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
await mkdir(resolve(root, ".codex"), { recursive: true });
|
|
67
|
+
await Promise.all(configs.filter((config) => config !== void 0).map(({ path, contents }) => writeFile(path, contents)));
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
7
70
|
//#region src/project.ts
|
|
8
71
|
const PACKAGE_MANAGER = "pnpm@11.18.0+sha512.33d83c77da82f49fba836925c6f1b841181ec3132b670639bd012f7075f5c7cf634c5f870147c19aae7478fac01df09d8892e880454896edd23ee9b33757563c";
|
|
9
72
|
const cliManifestValueSchema = z.string().min(1, "must be a non-empty string");
|
|
@@ -11,6 +74,7 @@ const cliManifestSchema = z.object({
|
|
|
11
74
|
name: cliManifestValueSchema,
|
|
12
75
|
version: cliManifestValueSchema,
|
|
13
76
|
dependencies: z.object({
|
|
77
|
+
"@fontsource-variable/geist-mono": cliManifestValueSchema,
|
|
14
78
|
"@fontsource-variable/inter": cliManifestValueSchema,
|
|
15
79
|
"@orpc/contract": cliManifestValueSchema,
|
|
16
80
|
"@tiptap/core": cliManifestValueSchema,
|
|
@@ -24,12 +88,14 @@ const cliManifestSchema = z.object({
|
|
|
24
88
|
"@tailwindcss/vite": cliManifestValueSchema,
|
|
25
89
|
"@tanstack/router-cli": cliManifestValueSchema,
|
|
26
90
|
"class-variance-authority": cliManifestValueSchema,
|
|
27
|
-
|
|
91
|
+
cn: cliManifestValueSchema,
|
|
28
92
|
"lucide-react": cliManifestValueSchema,
|
|
93
|
+
oxfmt: cliManifestValueSchema,
|
|
94
|
+
oxlint: cliManifestValueSchema,
|
|
95
|
+
"oxlint-tsgolint": cliManifestValueSchema,
|
|
29
96
|
"react-aria-components": cliManifestValueSchema,
|
|
30
97
|
shadcn: cliManifestValueSchema,
|
|
31
98
|
streamdown: cliManifestValueSchema,
|
|
32
|
-
"tailwind-merge": cliManifestValueSchema,
|
|
33
99
|
tailwindcss: cliManifestValueSchema,
|
|
34
100
|
"tw-animate-css": cliManifestValueSchema,
|
|
35
101
|
vite: cliManifestValueSchema,
|
|
@@ -51,11 +117,11 @@ const cliManifestSchema = z.object({
|
|
|
51
117
|
async function loadCliManifest(options) {
|
|
52
118
|
const result = cliManifestSchema.safeParse(JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8")));
|
|
53
119
|
if (!result.success) {
|
|
54
|
-
const issue = result.error.issues
|
|
120
|
+
const issue = result.error.issues.at(0);
|
|
55
121
|
if (issue === void 0) throw new Error("Invalid CLI package manifest.");
|
|
56
122
|
throw new Error(`Invalid CLI package manifest field "${issue.path.join(".")}": ${issue.message}.`);
|
|
57
123
|
}
|
|
58
|
-
const catalogEntry = [...Object.entries(result.data.dependencies).map(([name, value]) => [`dependencies.${name}`, value]), ...Object.entries(result.data.peerDependencies).map(([name, value]) => [`peerDependencies.${name}`, value])].find(([, value]) => value
|
|
124
|
+
const catalogEntry = [...Object.entries(result.data.dependencies).map(([name, value]) => [`dependencies.${name}`, value]), ...Object.entries(result.data.peerDependencies).map(([name, value]) => [`peerDependencies.${name}`, value])].find(([, value]) => value.startsWith("catalog:"));
|
|
59
125
|
if (catalogEntry !== void 0) {
|
|
60
126
|
if (options?.allowDevelopment === true) return void 0;
|
|
61
127
|
throw new Error(`Invalid CLI package manifest field "${catalogEntry[0]}": "catalog:" identifies an unpublished development build. Run the published @hitch42/applet CLI instead.`);
|
|
@@ -71,8 +137,16 @@ function workspacePackage(org) {
|
|
|
71
137
|
name: `${org.replaceAll("_", "-")}-applets`,
|
|
72
138
|
private: true,
|
|
73
139
|
type: "module",
|
|
140
|
+
scripts: {
|
|
141
|
+
lint: "oxlint",
|
|
142
|
+
fmt: "oxfmt",
|
|
143
|
+
check: "oxfmt --check && oxlint"
|
|
144
|
+
},
|
|
74
145
|
devDependencies: {
|
|
75
146
|
"@hitch42/applet": "catalog:",
|
|
147
|
+
oxfmt: "catalog:",
|
|
148
|
+
oxlint: "catalog:",
|
|
149
|
+
"oxlint-tsgolint": "catalog:",
|
|
76
150
|
typescript: "catalog:",
|
|
77
151
|
vite: "catalog:",
|
|
78
152
|
vitest: "catalog:"
|
|
@@ -85,6 +159,7 @@ function workspaceFile(cli) {
|
|
|
85
159
|
- applets/*
|
|
86
160
|
catalog:
|
|
87
161
|
"@hitch42/applet": npm:${cli.name}@${cli.version}
|
|
162
|
+
"@fontsource-variable/geist-mono": "${cli.dependencies["@fontsource-variable/geist-mono"]}"
|
|
88
163
|
"@fontsource-variable/inter": "${cli.dependencies["@fontsource-variable/inter"]}"
|
|
89
164
|
"@orpc/contract": "${cli.dependencies["@orpc/contract"]}"
|
|
90
165
|
"@orpc/server": "${cli.peerDependencies["@orpc/server"]}"
|
|
@@ -104,14 +179,16 @@ catalog:
|
|
|
104
179
|
"@types/react-dom": "${cli.peerDependencies["@types/react-dom"]}"
|
|
105
180
|
"@tailwindcss/vite": "${cli.dependencies["@tailwindcss/vite"]}"
|
|
106
181
|
class-variance-authority: "${cli.dependencies["class-variance-authority"]}"
|
|
107
|
-
|
|
182
|
+
cn: "${cli.dependencies.cn}"
|
|
108
183
|
lucide-react: "${cli.dependencies["lucide-react"]}"
|
|
184
|
+
oxfmt: "${cli.dependencies.oxfmt}"
|
|
185
|
+
oxlint: "${cli.dependencies.oxlint}"
|
|
186
|
+
oxlint-tsgolint: "${cli.dependencies["oxlint-tsgolint"]}"
|
|
109
187
|
react: "${cli.peerDependencies.react}"
|
|
110
188
|
react-aria-components: "${cli.dependencies["react-aria-components"]}"
|
|
111
189
|
react-dom: "${cli.peerDependencies["react-dom"]}"
|
|
112
190
|
shadcn: "${cli.dependencies.shadcn}"
|
|
113
191
|
streamdown: "${cli.dependencies.streamdown}"
|
|
114
|
-
tailwind-merge: "${cli.dependencies["tailwind-merge"]}"
|
|
115
192
|
tailwindcss: "${cli.dependencies.tailwindcss}"
|
|
116
193
|
tw-animate-css: "${cli.dependencies["tw-animate-css"]}"
|
|
117
194
|
typescript: "${cli.peerDependencies.typescript}"
|
|
@@ -126,17 +203,91 @@ minimumReleaseAgeExclude:
|
|
|
126
203
|
- "@hitch42/*"
|
|
127
204
|
`;
|
|
128
205
|
}
|
|
206
|
+
const OXLINT_CONFIG = `{
|
|
207
|
+
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
|
208
|
+
"plugins": ["eslint", "typescript", "unicorn", "import", "node"],
|
|
209
|
+
"options": { "typeAware": true, "typeCheck": true },
|
|
210
|
+
"env": { "node": true },
|
|
211
|
+
"overrides": [
|
|
212
|
+
{
|
|
213
|
+
"files": ["applets/*/src/client/**"],
|
|
214
|
+
"plugins": ["eslint", "typescript", "unicorn", "import", "react", "react-perf"],
|
|
215
|
+
"env": { "node": false, "browser": true },
|
|
216
|
+
"rules": {
|
|
217
|
+
"react/capitalized-calls": "error",
|
|
218
|
+
"react/error-boundaries": "error",
|
|
219
|
+
"react/exhaustive-effect-dependencies": "error",
|
|
220
|
+
"react/globals": "error",
|
|
221
|
+
"react/hooks": "error",
|
|
222
|
+
"react/immutability": "error",
|
|
223
|
+
"react/incompatible-library": "error",
|
|
224
|
+
"react/invariant": "error",
|
|
225
|
+
"react/memo-dependencies": "error",
|
|
226
|
+
"react/no-deriving-state-in-effects": "error",
|
|
227
|
+
"react/preserve-manual-memoization": "error",
|
|
228
|
+
"react/purity": "error",
|
|
229
|
+
"react/refs": "error",
|
|
230
|
+
"react/rule-suppression": "error",
|
|
231
|
+
"react/set-state-in-effect": "error",
|
|
232
|
+
"react/set-state-in-render": "error",
|
|
233
|
+
"react/static-components": "error",
|
|
234
|
+
"react/syntax": "error",
|
|
235
|
+
"react/todo": "error",
|
|
236
|
+
"react/unsupported-syntax": "error",
|
|
237
|
+
"react/use-memo": "error",
|
|
238
|
+
"react/void-use-memo": "error"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"files": ["applets/*/test/**"],
|
|
243
|
+
"plugins": ["eslint", "typescript", "unicorn", "import", "vitest"],
|
|
244
|
+
"rules": {
|
|
245
|
+
"vitest/expect-expect": [
|
|
246
|
+
"warn",
|
|
247
|
+
{ "assertFunctionNames": ["expect", "expect*", "assert", "assert.*", "assert*"] }
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
}
|
|
253
|
+
`;
|
|
254
|
+
async function oxfmtConfig(root) {
|
|
255
|
+
const appletsRoot = resolve(root, "applets");
|
|
256
|
+
const overrides = (existsSync(appletsRoot) ? await readdir(appletsRoot) : []).filter((code) => existsSync(resolve(appletsRoot, code, "src/client/styles/globals.css"))).sort().map((code) => `
|
|
257
|
+
{
|
|
258
|
+
"files": ["applets/${code}/**"],
|
|
259
|
+
"options": {
|
|
260
|
+
"sortTailwindcss": {
|
|
261
|
+
"stylesheet": "applets/${code}/src/client/styles/globals.css",
|
|
262
|
+
"functions": ["cn", "cva"]
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}`);
|
|
266
|
+
return `{
|
|
267
|
+
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
|
268
|
+
"sortImports": true,
|
|
269
|
+
"overrides": [${overrides.join(",")}${overrides.length > 0 ? "\n " : ""}]
|
|
270
|
+
}
|
|
271
|
+
`;
|
|
272
|
+
}
|
|
129
273
|
const GITIGNORE_START = "# BEGIN Hitch generated files";
|
|
130
274
|
const GITIGNORE_END = "# END Hitch generated files";
|
|
131
275
|
const SKILLS = [
|
|
132
276
|
"hitch-applets",
|
|
133
277
|
"hitch-cli",
|
|
134
278
|
"hitch-data",
|
|
135
|
-
"hitch-theory"
|
|
279
|
+
"hitch-theory",
|
|
280
|
+
"react-best-practices",
|
|
281
|
+
"tanstack-query",
|
|
282
|
+
"tanstack-router",
|
|
283
|
+
"web-design-guidelines"
|
|
136
284
|
];
|
|
137
285
|
const GITIGNORE = `${GITIGNORE_START}
|
|
138
286
|
${SKILLS.map((skill) => `/.agents/skills/${skill}/`).join("\n")}
|
|
287
|
+
${SKILLS.map((skill) => `/.claude/skills/${skill}`).join("\n")}
|
|
139
288
|
/.node-version
|
|
289
|
+
/.oxfmtrc.json
|
|
290
|
+
/.oxlintrc.json
|
|
140
291
|
/AGENTS.md
|
|
141
292
|
/CLAUDE.md
|
|
142
293
|
/package.json
|
|
@@ -176,10 +327,12 @@ async function writeWorkspaceSupport(root, config, cli) {
|
|
|
176
327
|
const resolvedCli = cli ?? await loadCliManifest();
|
|
177
328
|
if (resolvedCli === void 0) throw new Error("The CLI package manifest is not published.");
|
|
178
329
|
assertWorkspaceCli(config, resolvedCli);
|
|
330
|
+
await ensureAgentConfigs(root, config.org);
|
|
179
331
|
const deployWorkflowTarget = resolve(root, ".github/workflows/hitch.yml");
|
|
180
332
|
const agents = await readFile(new URL("../scaffold/AGENTS.md", import.meta.url), "utf8");
|
|
181
333
|
await Promise.all([
|
|
182
334
|
mkdir(resolve(root, ".agents/skills"), { recursive: true }),
|
|
335
|
+
mkdir(resolve(root, ".claude/skills"), { recursive: true }),
|
|
183
336
|
config.githubWorkflow === false ? void 0 : mkdir(resolve(root, ".github/workflows"), { recursive: true }),
|
|
184
337
|
...SKILLS.map((skill) => rm(resolve(root, ".agents/skills", skill), {
|
|
185
338
|
force: true,
|
|
@@ -192,11 +345,21 @@ async function writeWorkspaceSupport(root, config, cli) {
|
|
|
192
345
|
writeFile(resolve(root, "pnpm-workspace.yaml"), workspaceFile(resolvedCli)),
|
|
193
346
|
config.githubWorkflow === false || existsSync(deployWorkflowTarget) ? void 0 : cp(new URL("../scaffold/.github/workflows/hitch.yml", import.meta.url), deployWorkflowTarget),
|
|
194
347
|
writeFile(resolve(root, ".node-version"), "24\n"),
|
|
348
|
+
writeFile(resolve(root, ".oxlintrc.json"), OXLINT_CONFIG),
|
|
349
|
+
oxfmtConfig(root).then((config) => writeFile(resolve(root, ".oxfmtrc.json"), config)),
|
|
195
350
|
writeGitignore(root),
|
|
196
351
|
writeFile(resolve(root, "AGENTS.md"), agents)
|
|
197
352
|
]);
|
|
198
353
|
await rm(resolve(root, "CLAUDE.md"), { force: true });
|
|
199
354
|
await symlink("AGENTS.md", resolve(root, "CLAUDE.md"));
|
|
355
|
+
await Promise.all(SKILLS.map(async (skill) => {
|
|
356
|
+
const target = resolve(root, ".claude/skills", skill);
|
|
357
|
+
await rm(target, { force: true });
|
|
358
|
+
await symlink(`../../.agents/skills/${skill}`, target, "dir");
|
|
359
|
+
}));
|
|
360
|
+
}
|
|
361
|
+
function sortedByName(packages) {
|
|
362
|
+
return Object.fromEntries(Object.entries(packages).sort(([a], [b]) => a < b ? -1 : 1));
|
|
200
363
|
}
|
|
201
364
|
function appletPackage(definition, options) {
|
|
202
365
|
return {
|
|
@@ -209,14 +372,18 @@ function appletPackage(definition, options) {
|
|
|
209
372
|
generate: "applet generate",
|
|
210
373
|
deploy: "applet deploy",
|
|
211
374
|
test: "vitest run",
|
|
212
|
-
typecheck: "tsc --noEmit"
|
|
375
|
+
typecheck: "tsc --noEmit",
|
|
376
|
+
lint: "oxlint",
|
|
377
|
+
fmt: "oxfmt",
|
|
378
|
+
check: "oxfmt --check && oxlint"
|
|
213
379
|
},
|
|
214
|
-
dependencies: {
|
|
380
|
+
dependencies: sortedByName({
|
|
215
381
|
"@hitch42/applet": "catalog:",
|
|
216
382
|
"@orpc/contract": "catalog:",
|
|
217
383
|
zod: "catalog:",
|
|
218
384
|
...options.hasServer ? { "@orpc/server": "catalog:" } : {},
|
|
219
385
|
...options.hasClient ? {
|
|
386
|
+
"@fontsource-variable/geist-mono": "catalog:",
|
|
220
387
|
"@fontsource-variable/inter": "catalog:",
|
|
221
388
|
"@tanstack/react-query": "catalog:",
|
|
222
389
|
"@tanstack/react-router": "catalog:",
|
|
@@ -229,19 +396,18 @@ function appletPackage(definition, options) {
|
|
|
229
396
|
"@tiptap/react": "catalog:",
|
|
230
397
|
"@tiptap/starter-kit": "catalog:",
|
|
231
398
|
"class-variance-authority": "catalog:",
|
|
232
|
-
|
|
399
|
+
cn: "catalog:",
|
|
233
400
|
"lucide-react": "catalog:",
|
|
234
401
|
react: "catalog:",
|
|
235
402
|
"react-aria-components": "catalog:",
|
|
236
403
|
"react-dom": "catalog:",
|
|
237
404
|
shadcn: "catalog:",
|
|
238
405
|
streamdown: "catalog:",
|
|
239
|
-
"tailwind-merge": "catalog:",
|
|
240
406
|
"tw-animate-css": "catalog:"
|
|
241
407
|
} : {},
|
|
242
408
|
...definition.dependencies
|
|
243
|
-
},
|
|
244
|
-
devDependencies: {
|
|
409
|
+
}),
|
|
410
|
+
devDependencies: sortedByName({
|
|
245
411
|
"@types/node": "catalog:",
|
|
246
412
|
typescript: "catalog:",
|
|
247
413
|
vite: "catalog:",
|
|
@@ -253,9 +419,21 @@ function appletPackage(definition, options) {
|
|
|
253
419
|
tailwindcss: "catalog:"
|
|
254
420
|
} : {},
|
|
255
421
|
...definition.devDependencies
|
|
256
|
-
}
|
|
422
|
+
})
|
|
257
423
|
};
|
|
258
424
|
}
|
|
425
|
+
const LEGACY_CN_HELPER = `import { clsx, type ClassValue } from "clsx";
|
|
426
|
+
import { twMerge } from "tailwind-merge";
|
|
427
|
+
|
|
428
|
+
export function cn(...inputs: ClassValue[]) {
|
|
429
|
+
return twMerge(clsx(inputs));
|
|
430
|
+
}
|
|
431
|
+
`;
|
|
432
|
+
async function replaceLegacyCnHelper(root) {
|
|
433
|
+
const path = resolve(root, "src/client/lib/utils.ts");
|
|
434
|
+
if (!existsSync(path) || await readFile(path, "utf8") !== LEGACY_CN_HELPER) return;
|
|
435
|
+
await cp(new URL("../scaffold/applet/src/client/lib/utils.ts", import.meta.url), path);
|
|
436
|
+
}
|
|
259
437
|
async function writeAppletSupport(root, definition) {
|
|
260
438
|
const hasClient = existsSync(resolve(root, "src/client/routes"));
|
|
261
439
|
const hasAuthorRoot = existsSync(resolve(root, "src/client/routes/__root.tsx"));
|
|
@@ -264,6 +442,7 @@ async function writeAppletSupport(root, definition) {
|
|
|
264
442
|
if (!hasServer && (definition.schedules?.length ?? 0) > 0) throw new Error("An applet with schedules must have src/server/main.ts.");
|
|
265
443
|
await Promise.all(hasClient ? [] : [rm(resolve(root, "index.html"), { force: true }), rm(resolve(root, "components.json"), { force: true })]);
|
|
266
444
|
await Promise.all([
|
|
445
|
+
replaceLegacyCnHelper(root),
|
|
267
446
|
writeFile(resolve(root, "package.json"), `${JSON.stringify(appletPackage(definition, {
|
|
268
447
|
hasClient,
|
|
269
448
|
hasServer
|
|
@@ -335,7 +514,9 @@ export default defineConfig({
|
|
|
335
514
|
"./.hitch/*.ts",
|
|
336
515
|
"./.hitch/*.tsx",
|
|
337
516
|
"./src/**/*.ts",
|
|
338
|
-
"./src/**/*.tsx"
|
|
517
|
+
"./src/**/*.tsx",
|
|
518
|
+
"./test/**/*.ts",
|
|
519
|
+
"./test/**/*.tsx"
|
|
339
520
|
]
|
|
340
521
|
}
|
|
341
522
|
`),
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//#region src/internal/query-cache.ts
|
|
2
|
+
const STORE = "clients";
|
|
3
|
+
const TIMESTAMP_INDEX = "timestamp";
|
|
4
|
+
const TAB_KEY = "hitch:query-tab";
|
|
5
|
+
const SAVE_INTERVAL = 1e3;
|
|
6
|
+
function openQueryCacheDatabase() {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const open = indexedDB.open("hitch-query-cache", 1);
|
|
9
|
+
open.onupgradeneeded = () => {
|
|
10
|
+
open.result.createObjectStore("clients").createIndex("timestamp", "timestamp");
|
|
11
|
+
};
|
|
12
|
+
open.onblocked = () => reject(/* @__PURE__ */ new Error("The query cache is open in an older tab."));
|
|
13
|
+
open.onsuccess = () => {
|
|
14
|
+
open.result.onversionchange = () => open.result.close();
|
|
15
|
+
resolve(open.result);
|
|
16
|
+
};
|
|
17
|
+
open.onerror = () => reject(open.error);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
let database;
|
|
21
|
+
function openCacheDatabase() {
|
|
22
|
+
database ??= window.__hitchCacheDatabase ?? openQueryCacheDatabase();
|
|
23
|
+
return database;
|
|
24
|
+
}
|
|
25
|
+
async function inStore(mode, run) {
|
|
26
|
+
const transaction = (await openCacheDatabase()).transaction(STORE, mode);
|
|
27
|
+
const request = run(transaction.objectStore(STORE));
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
transaction.oncomplete = () => resolve(request.result);
|
|
30
|
+
transaction.onabort = () => reject(transaction.error ?? request.error);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function cacheTabId() {
|
|
34
|
+
const existing = sessionStorage.getItem(TAB_KEY);
|
|
35
|
+
if (existing) return existing;
|
|
36
|
+
const id = crypto.randomUUID();
|
|
37
|
+
sessionStorage.setItem(TAB_KEY, id);
|
|
38
|
+
return id;
|
|
39
|
+
}
|
|
40
|
+
function indexedDbPersister(key) {
|
|
41
|
+
let pending;
|
|
42
|
+
let throttled = false;
|
|
43
|
+
const save = (client) => inStore("readwrite", (store) => store.put(client, key)).then(() => void 0, (error) => console.error("Could not persist the applet query cache.", error));
|
|
44
|
+
const release = () => {
|
|
45
|
+
if (!pending) {
|
|
46
|
+
throttled = false;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
save(pending);
|
|
50
|
+
pending = void 0;
|
|
51
|
+
setTimeout(release, SAVE_INTERVAL);
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
persistClient: (client) => {
|
|
55
|
+
if (throttled) {
|
|
56
|
+
pending = client;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
throttled = true;
|
|
60
|
+
setTimeout(release, SAVE_INTERVAL);
|
|
61
|
+
return save(client);
|
|
62
|
+
},
|
|
63
|
+
restoreClient: () => inStore("readonly", (store) => store.get(key)),
|
|
64
|
+
removeClient: () => inStore("readwrite", (store) => store.delete(key))
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function sweepExpiredQueryCaches(maxAge) {
|
|
68
|
+
return inStore("readwrite", (store) => {
|
|
69
|
+
const cursor = store.index(TIMESTAMP_INDEX).openKeyCursor(IDBKeyRange.upperBound(Date.now() - maxAge));
|
|
70
|
+
cursor.onsuccess = () => {
|
|
71
|
+
if (!cursor.result) return;
|
|
72
|
+
store.delete(cursor.result.primaryKey);
|
|
73
|
+
cursor.result.continue();
|
|
74
|
+
};
|
|
75
|
+
return cursor;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function clearAppletQueryCaches(appletCode) {
|
|
79
|
+
return inStore("readwrite", (store) => store.delete(IDBKeyRange.bound(`${appletCode}:`, `${appletCode}:\uffff`)));
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { openQueryCacheDatabase as a, openCacheDatabase as i, clearAppletQueryCaches as n, sweepExpiredQueryCaches as o, indexedDbPersister as r, cacheTabId as t };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as UploadedHitchFile } from "./upload-
|
|
1
|
+
import { a as UploadedHitchFile } from "./upload-DKZzz5kW.js";
|
|
2
2
|
import { ReactElement } from "react";
|
|
3
3
|
import "@tiptap/core";
|
|
4
4
|
//#region src/react/markdown.d.ts
|
|
@@ -29,9 +29,10 @@ type MarkdownEditorProps = {
|
|
|
29
29
|
minLength?: number;
|
|
30
30
|
maxLength?: number;
|
|
31
31
|
disabled?: boolean;
|
|
32
|
+
autoFocus?: boolean;
|
|
32
33
|
className?: string;
|
|
33
34
|
onUploadError?: (error: unknown, file: File) => void;
|
|
34
35
|
};
|
|
35
|
-
declare function MarkdownEditor({ value, onChange, files, id, placeholder, required, minLength, maxLength, disabled, className, onUploadError }: MarkdownEditorProps): ReactElement;
|
|
36
|
+
declare function MarkdownEditor({ value, onChange, files, id, placeholder, required, minLength, maxLength, disabled, autoFocus, className, onUploadError }: MarkdownEditorProps): ReactElement;
|
|
36
37
|
//#endregion
|
|
37
38
|
export { Markdown, MarkdownEditor, type MarkdownEditorFiles, type MarkdownEditorProps, type MarkdownFiles, type MarkdownProps };
|