fimo 0.2.3-staging.7 → 0.2.3-staging.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/assets/skills/fimo/references/setup-plain-vite.md +4 -1
- package/assets/skills/fimo/references/setup-react-router.md +3 -2
- package/assets/skills/fimo-cli/references/agent-setup.md +1 -1
- package/assets/skills/fimo-cli/references/branches.md +2 -0
- package/dist/cli/bundle.json +2 -2
- package/dist/cli/index.js +758 -631
- package/dist/runtime/templates.d.ts +5 -5
- package/dist/runtime/templates.d.ts.map +1 -1
- package/dist/runtime/templates.js +14 -13
- package/package.json +1 -2
- package/scripts/lib/dev-release-state.mjs +44 -0
- package/scripts/lib/dev-release-state.test.ts +36 -0
- package/scripts/postinstall.mjs +6 -4
- package/scripts/publish-npm.mjs +12 -1
- package/templates/react-router/package.json +1 -8
- package/templates/react-router/pnpm-workspace.yaml +6 -3
- package/templates/react-router/public/claude-color.svg +1 -0
- package/templates/react-router/public/codex.svg +1 -0
- package/templates/react-router/public/copilot-color.svg +1 -0
- package/templates/react-router/public/cursor-light.svg +12 -0
- package/templates/react-router/public/fimo-logo-black.svg +3 -0
- package/templates/react-router/src/index.css +0 -4
- package/templates/react-router/src/pages/Index.tsx +38 -97
- package/scripts/lib/cleanup-release.mjs +0 -64
- package/scripts/lib/cleanup-release.test.ts +0 -142
- package/scripts/publish-tarball.mjs +0 -245
|
@@ -30,8 +30,7 @@ export declare function getTemplatePath(framework?: TemplateFramework): string;
|
|
|
30
30
|
*/
|
|
31
31
|
export declare function getLegacyTemplateDir(): string;
|
|
32
32
|
export interface ReleaseMeta {
|
|
33
|
-
|
|
34
|
-
source: 'npm' | 'url' | 'dev' | null;
|
|
33
|
+
source: 'npm' | 'dev' | null;
|
|
35
34
|
}
|
|
36
35
|
export declare function readReleaseMeta(): ReleaseMeta;
|
|
37
36
|
export declare function readCliSemver(): string | null;
|
|
@@ -51,9 +50,10 @@ interface PkgWithDeps {
|
|
|
51
50
|
devDependencies?: Record<string, string>;
|
|
52
51
|
}
|
|
53
52
|
/**
|
|
54
|
-
* Rewrite `fimo` (in dependencies + devDependencies) to the current pin.
|
|
55
|
-
*
|
|
56
|
-
*
|
|
53
|
+
* Rewrite `fimo` (in dependencies + devDependencies) to the current pin. Only
|
|
54
|
+
* touches entries that look like a value we own: the template's dist-tag, an old
|
|
55
|
+
* tarball URL, an exact/ranged semver, or a local `file:` dependency. Bespoke
|
|
56
|
+
* values are left alone.
|
|
57
57
|
*
|
|
58
58
|
* Returns true if anything changed.
|
|
59
59
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/runtime/templates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/runtime/templates.ts"],"names":[],"mappings":"AAgCA,eAAO,MAAM,mBAAmB,oDAAqD,CAAC;AACtF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACrE,eAAO,MAAM,gBAAgB,EAAE,iBAAkC,CAAC;AAElE;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,GAAE,iBAAoC,GAAG,MAAM,CAEvF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAmBD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,eAAe,IAAI,WAAW,CAS7C;AAED,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAW7C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAC/C,MAAM,GAAG,IAAI,CAUf;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAAG,MAAM,GAAG,IAAI,CAE9F;AAED,UAAU,WAAW;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,GAAE,MAAM,GAAG,IAAuB,GAAG,OAAO,CA2B/F"}
|
|
@@ -27,7 +27,6 @@ const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
|
27
27
|
const PACKAGE_ROOT = path.resolve(MODULE_DIR, '..', '..');
|
|
28
28
|
const RELEASE_FILE = path.join(PACKAGE_ROOT, 'release.json');
|
|
29
29
|
const PACKAGE_JSON_FILE = path.join(PACKAGE_ROOT, 'package.json');
|
|
30
|
-
const TARBALL_URL_BASE = 'https://pub-41cdea46386f4b238d8c528c4327dfc1.r2.dev/cli';
|
|
31
30
|
export const TEMPLATE_FRAMEWORKS = ['react-router', 'astro', 'next', 'vite'];
|
|
32
31
|
export const DEFAULT_TEMPLATE = 'react-router';
|
|
33
32
|
/**
|
|
@@ -70,12 +69,11 @@ export function readReleaseMeta() {
|
|
|
70
69
|
try {
|
|
71
70
|
const raw = fs.readFileSync(RELEASE_FILE, 'utf8');
|
|
72
71
|
const parsed = JSON.parse(raw);
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
return { id, source };
|
|
72
|
+
const source = parsed.source === 'npm' || parsed.source === 'dev' ? parsed.source : null;
|
|
73
|
+
return { source };
|
|
76
74
|
}
|
|
77
75
|
catch {
|
|
78
|
-
return {
|
|
76
|
+
return { source: null };
|
|
79
77
|
}
|
|
80
78
|
}
|
|
81
79
|
export function readCliSemver() {
|
|
@@ -101,9 +99,6 @@ export function computeFimoPin(meta, semver, options = {}) {
|
|
|
101
99
|
return semver;
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
|
-
if (meta.id) {
|
|
105
|
-
return `${TARBALL_URL_BASE}/fimo-${meta.id}.tgz`;
|
|
106
|
-
}
|
|
107
102
|
if ((meta.source === 'dev' || meta.source === null) && options.devPackageRoot) {
|
|
108
103
|
return `file:${options.devPackageRoot}`;
|
|
109
104
|
}
|
|
@@ -114,9 +109,10 @@ export function resolveFimoPin(options = {}) {
|
|
|
114
109
|
return computeFimoPin(readReleaseMeta(), readCliSemver(), options);
|
|
115
110
|
}
|
|
116
111
|
/**
|
|
117
|
-
* Rewrite `fimo` (in dependencies + devDependencies) to the current pin.
|
|
118
|
-
*
|
|
119
|
-
*
|
|
112
|
+
* Rewrite `fimo` (in dependencies + devDependencies) to the current pin. Only
|
|
113
|
+
* touches entries that look like a value we own: the template's dist-tag, an old
|
|
114
|
+
* tarball URL, an exact/ranged semver, or a local `file:` dependency. Bespoke
|
|
115
|
+
* values are left alone.
|
|
120
116
|
*
|
|
121
117
|
* Returns true if anything changed.
|
|
122
118
|
*/
|
|
@@ -134,9 +130,14 @@ export function rewriteFimoDep(pkg, pin = resolveFimoPin()) {
|
|
|
134
130
|
if (typeof current !== 'string') {
|
|
135
131
|
continue;
|
|
136
132
|
}
|
|
137
|
-
|
|
133
|
+
// Migrate projects still pinned to the retired R2 tarball, repin a semver,
|
|
134
|
+
// rewrite the committed template's dist-tag, or (dev flow) swap a local
|
|
135
|
+
// `file:` build for a published version on deploy.
|
|
136
|
+
const looksLikeLegacyR2 = current.includes('r2.dev/cli/fimo-');
|
|
137
|
+
const looksLikeLocalFile = current.startsWith('file:');
|
|
138
138
|
const looksLikeSemver = /^[\^~]?\d+\.\d+\.\d+/.test(current);
|
|
139
|
-
|
|
139
|
+
const looksLikeOwnedDistTag = current === 'latest' || current === 'staging' || current === 'experimental';
|
|
140
|
+
if ((looksLikeLegacyR2 || looksLikeLocalFile || looksLikeSemver || looksLikeOwnedDistTag) && current !== pin) {
|
|
140
141
|
deps['fimo'] = pin;
|
|
141
142
|
changed = true;
|
|
142
143
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fimo",
|
|
3
|
-
"version": "0.2.3-staging.
|
|
3
|
+
"version": "0.2.3-staging.9",
|
|
4
4
|
"description": "Fimo CLI - create, deploy, and manage Fimo projects",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fimo": "dist/cli/index.js"
|
|
@@ -45,7 +45,6 @@
|
|
|
45
45
|
"check:types": "tsc -b tsconfig.json",
|
|
46
46
|
"start": "tsx src/cli/index.ts",
|
|
47
47
|
"install-cli": "pnpm build && node scripts/install-cli.mjs",
|
|
48
|
-
"publish-cli": "node scripts/publish-tarball.mjs",
|
|
49
48
|
"publish:npm": "node scripts/publish-npm.mjs",
|
|
50
49
|
"prepublishOnly": "pnpm run build && pnpm run build:bundle",
|
|
51
50
|
"release:bump": "node scripts/bump-version.mjs",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { relative, resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Record the latest locally-published experimental CLI version for this
|
|
7
|
+
* checkout. `fimo deploy` uses this to swap a project-local `file:` dependency
|
|
8
|
+
* to an immutable npm version before pushing to a remote sandbox.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} cliRoot - apps/cli root
|
|
11
|
+
* @param {{ version: string, channel: string }} release
|
|
12
|
+
* @returns {string} the file written
|
|
13
|
+
*/
|
|
14
|
+
export function writeDevReleaseState(cliRoot, release) {
|
|
15
|
+
const repoRoot = resolve(cliRoot, '..', '..');
|
|
16
|
+
const dir = resolve(repoRoot, '.fimo');
|
|
17
|
+
mkdirSync(dir, { recursive: true });
|
|
18
|
+
|
|
19
|
+
const payload = {
|
|
20
|
+
version: release.version,
|
|
21
|
+
channel: release.channel,
|
|
22
|
+
packageRoot: relative(repoRoot, cliRoot),
|
|
23
|
+
gitSha: readGitSha(repoRoot),
|
|
24
|
+
publishedAt: new Date().toISOString(),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const file = resolve(dir, 'dev.json');
|
|
28
|
+
writeFileSync(file, JSON.stringify(payload, null, 2) + '\n');
|
|
29
|
+
return file;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readGitSha(repoRoot) {
|
|
33
|
+
const result = spawnSync('git', ['rev-parse', 'HEAD'], {
|
|
34
|
+
cwd: repoRoot,
|
|
35
|
+
encoding: 'utf8',
|
|
36
|
+
});
|
|
37
|
+
if (result.status === 0) {
|
|
38
|
+
const sha = result.stdout.trim();
|
|
39
|
+
if (sha.length > 0) {
|
|
40
|
+
return sha;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { writeDevReleaseState } from './dev-release-state.mjs';
|
|
8
|
+
|
|
9
|
+
const tmpRoots: string[] = [];
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
for (const root of tmpRoots.splice(0)) {
|
|
13
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('writeDevReleaseState', () => {
|
|
18
|
+
it('writes repo-root .fimo/dev.json for the checkout', () => {
|
|
19
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'fimo-dev-state-'));
|
|
20
|
+
tmpRoots.push(root);
|
|
21
|
+
const cliRoot = path.join(root, 'apps', 'cli');
|
|
22
|
+
fs.mkdirSync(cliRoot, { recursive: true });
|
|
23
|
+
|
|
24
|
+
const file = writeDevReleaseState(cliRoot, {
|
|
25
|
+
version: '0.2.3-experimental.42',
|
|
26
|
+
channel: 'experimental',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
expect(file).toBe(path.join(root, '.fimo', 'dev.json'));
|
|
30
|
+
expect(JSON.parse(fs.readFileSync(file, 'utf8'))).toMatchObject({
|
|
31
|
+
version: '0.2.3-experimental.42',
|
|
32
|
+
channel: 'experimental',
|
|
33
|
+
packageRoot: 'apps/cli',
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -17,10 +17,12 @@
|
|
|
17
17
|
// never break the user's install).
|
|
18
18
|
//
|
|
19
19
|
// pnpm caveat: by default, pnpm strips build scripts from non-approved deps.
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
20
|
+
// Fimo-controlled installs (`fimo create --install`, sandbox `fimopm install`,
|
|
21
|
+
// and E2E helper installs) pass a scoped allow-all-builds flag for pnpm so the
|
|
22
|
+
// fimo postinstall hook can refresh project skills. The template intentionally
|
|
23
|
+
// does not persist allowlists in package.json / pnpm-workspace.yaml because
|
|
24
|
+
// those conflict with sandbox install flags and drift when deps change. npm /
|
|
25
|
+
// yarn run lifecycle scripts by default and need no extra config.
|
|
24
26
|
|
|
25
27
|
import fs from 'node:fs';
|
|
26
28
|
import path from 'node:path';
|
package/scripts/publish-npm.mjs
CHANGED
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
// staging URLs for experimental/staging, prod for latest. Never a tunnel.
|
|
15
15
|
// 4. For prerelease channels, synthesizes a disposable X.Y.Z-<tag>.<n> version.
|
|
16
16
|
// 5. Runs `npm publish --tag <distTag>` (no --provenance — strapi/fimo is private).
|
|
17
|
-
// 6.
|
|
17
|
+
// 6. On real experimental publishes, records the exact version in repo-root
|
|
18
|
+
// .fimo/dev.json for local source-checkout deploys.
|
|
19
|
+
// 7. Restores package.json + removes the transient release.json.
|
|
18
20
|
//
|
|
19
21
|
// `npm publish` triggers prepublishOnly (clean → build → build:bundle), so the
|
|
20
22
|
// bundled tarball is always fresh.
|
|
@@ -25,6 +27,7 @@ import { dirname, resolve } from 'node:path';
|
|
|
25
27
|
import { fileURLToPath } from 'node:url';
|
|
26
28
|
|
|
27
29
|
import { resolveChannel } from './lib/channels.mjs';
|
|
30
|
+
import { writeDevReleaseState } from './lib/dev-release-state.mjs';
|
|
28
31
|
import {
|
|
29
32
|
computePublishVersion,
|
|
30
33
|
pinTemplateFimo,
|
|
@@ -120,6 +123,14 @@ try {
|
|
|
120
123
|
console.error(`[publish-npm] npm publish failed (exit ${result.status}).`);
|
|
121
124
|
process.exit(result.status ?? 1);
|
|
122
125
|
}
|
|
126
|
+
|
|
127
|
+
if (!dryRun && channel.distTag === 'experimental') {
|
|
128
|
+
const devStatePath = writeDevReleaseState(CLI_ROOT, {
|
|
129
|
+
version: publishVersion,
|
|
130
|
+
channel: channel.distTag,
|
|
131
|
+
});
|
|
132
|
+
console.log(`[publish-npm] wrote ${devStatePath}`);
|
|
133
|
+
}
|
|
123
134
|
} finally {
|
|
124
135
|
// Restore the workspace: package.json version, template fimo pin, and remove
|
|
125
136
|
// the transient release.json so local `fimo` runs fall back to localhost.
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "react-router dev --port 5173",
|
|
8
|
-
"prebuild": "fimo validate",
|
|
9
8
|
"build": "react-router build && fimo export-static",
|
|
10
9
|
"lint": "oxlint --deny-warnings",
|
|
11
10
|
"typecheck": "tsc --noEmit",
|
|
@@ -22,7 +21,7 @@
|
|
|
22
21
|
"cmdk": "^1.1.1",
|
|
23
22
|
"date-fns": "^4.1.0",
|
|
24
23
|
"embla-carousel-react": "^8.6.0",
|
|
25
|
-
"fimo": "0.2.3-staging.
|
|
24
|
+
"fimo": "0.2.3-staging.9",
|
|
26
25
|
"input-otp": "^1.4.2",
|
|
27
26
|
"isbot": "^5",
|
|
28
27
|
"lucide-react": "^0.577.0",
|
|
@@ -53,11 +52,5 @@
|
|
|
53
52
|
"tw-animate-css": "^1.4.0",
|
|
54
53
|
"typescript": "5.9.3",
|
|
55
54
|
"vite": "^8.0.13"
|
|
56
|
-
},
|
|
57
|
-
"pnpm": {
|
|
58
|
-
"onlyBuiltDependencies": [
|
|
59
|
-
"esbuild",
|
|
60
|
-
"fimo"
|
|
61
|
-
]
|
|
62
55
|
}
|
|
63
56
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# Build approval is handled by Fimo-controlled install commands (`fimo create
|
|
2
|
+
# --install`, sandbox `fimopm install`, and E2E helpers) via scoped pnpm
|
|
3
|
+
# allow-all-builds flags. Do NOT add `allowBuilds` / `onlyBuiltDependencies`
|
|
4
|
+
# here: pnpm refuses to have both an allowlist and allow-all-builds
|
|
5
|
+
# (ERR_PNPM_CONFIG_CONFLICT_BUILT_DEPENDENCIES), which makes sandbox installs
|
|
6
|
+
# fail before the project's `fimo` dep is available.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Codex</title><path clip-rule="evenodd" d="M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Copilot</title><path d="M17.533 1.829A2.528 2.528 0 0015.11 0h-.737a2.531 2.531 0 00-2.484 2.087l-1.263 6.937.314-1.08a2.528 2.528 0 012.424-1.833h4.284l1.797.706 1.731-.706h-.505a2.528 2.528 0 01-2.423-1.829l-.715-2.453z" fill="url(#lobe-icons-copilot-0-_R_0_)" transform="translate(0 1)"></path><path d="M6.726 20.16A2.528 2.528 0 009.152 22h1.566c1.37 0 2.49-1.1 2.525-2.48l.17-6.69-.357 1.228a2.528 2.528 0 01-2.423 1.83h-4.32l-1.54-.842-1.667.843h.497c1.124 0 2.113.75 2.426 1.84l.697 2.432z" fill="url(#lobe-icons-copilot-1-_R_0_)" transform="translate(0 1)"></path><path d="M15 0H6.252c-2.5 0-4 3.331-5 6.662-1.184 3.947-2.734 9.225 1.75 9.225H6.78c1.13 0 2.12-.753 2.43-1.847.657-2.317 1.809-6.359 2.713-9.436.46-1.563.842-2.906 1.43-3.742A1.97 1.97 0 0115 0" fill="url(#lobe-icons-copilot-2-_R_0_)" transform="translate(0 1)"></path><path d="M15 0H6.252c-2.5 0-4 3.331-5 6.662-1.184 3.947-2.734 9.225 1.75 9.225H6.78c1.13 0 2.12-.753 2.43-1.847.657-2.317 1.809-6.359 2.713-9.436.46-1.563.842-2.906 1.43-3.742A1.97 1.97 0 0115 0" fill="url(#lobe-icons-copilot-3-_R_0_)" transform="translate(0 1)"></path><path d="M9 22h8.749c2.5 0 4-3.332 5-6.663 1.184-3.948 2.734-9.227-1.75-9.227H17.22c-1.129 0-2.12.754-2.43 1.848a1149.2 1149.2 0 01-2.713 9.437c-.46 1.564-.842 2.907-1.43 3.743A1.97 1.97 0 019 22" fill="url(#lobe-icons-copilot-4-_R_0_)" transform="translate(0 1)"></path><path d="M9 22h8.749c2.5 0 4-3.332 5-6.663 1.184-3.948 2.734-9.227-1.75-9.227H17.22c-1.129 0-2.12.754-2.43 1.848a1149.2 1149.2 0 01-2.713 9.437c-.46 1.564-.842 2.907-1.43 3.743A1.97 1.97 0 019 22" fill="url(#lobe-icons-copilot-5-_R_0_)" transform="translate(0 1)"></path><defs><radialGradient cx="85.44%" cy="100.653%" fx="85.44%" fy="100.653%" gradientTransform="scale(-.8553 -1) rotate(50.927 2.041 -1.946)" id="lobe-icons-copilot-0-_R_0_" r="105.116%"><stop offset="9.6%" stop-color="#00AEFF"></stop><stop offset="77.3%" stop-color="#2253CE"></stop><stop offset="100%" stop-color="#0736C4"></stop></radialGradient><radialGradient cx="18.143%" cy="32.928%" fx="18.143%" fy="32.928%" gradientTransform="scale(.8897 1) rotate(52.069 .193 .352)" id="lobe-icons-copilot-1-_R_0_" r="95.612%"><stop offset="0%" stop-color="#FFB657"></stop><stop offset="63.4%" stop-color="#FF5F3D"></stop><stop offset="92.3%" stop-color="#C02B3C"></stop></radialGradient><radialGradient cx="82.987%" cy="-9.792%" fx="82.987%" fy="-9.792%" gradientTransform="scale(-1 -.9441) rotate(-70.872 .142 1.17)" id="lobe-icons-copilot-4-_R_0_" r="140.622%"><stop offset="6.6%" stop-color="#8C48FF"></stop><stop offset="50%" stop-color="#F2598A"></stop><stop offset="89.6%" stop-color="#FFB152"></stop></radialGradient><linearGradient id="lobe-icons-copilot-2-_R_0_" x1="39.465%" x2="46.884%" y1="12.117%" y2="103.774%"><stop offset="15.6%" stop-color="#0D91E1"></stop><stop offset="48.7%" stop-color="#52B471"></stop><stop offset="65.2%" stop-color="#98BD42"></stop><stop offset="93.7%" stop-color="#FFC800"></stop></linearGradient><linearGradient id="lobe-icons-copilot-3-_R_0_" x1="45.949%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#3DCBFF"></stop><stop offset="24.7%" stop-color="#0588F7" stop-opacity="0"></stop></linearGradient><linearGradient id="lobe-icons-copilot-5-_R_0_" x1="83.507%" x2="83.453%" y1="-6.106%" y2="21.131%"><stop offset="5.8%" stop-color="#F8ADFA"></stop><stop offset="70.8%" stop-color="#A86EDD" stop-opacity="0"></stop></linearGradient></defs></svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 466.73 532.09">
|
|
3
|
+
<!-- Generator: Adobe Illustrator 29.6.1, SVG Export Plug-In . SVG Version: 2.1.1 Build 9) -->
|
|
4
|
+
<defs>
|
|
5
|
+
<style>
|
|
6
|
+
.st0 {
|
|
7
|
+
fill: #26251e;
|
|
8
|
+
}
|
|
9
|
+
</style>
|
|
10
|
+
</defs>
|
|
11
|
+
<path class="st0" d="M457.43,125.94L244.42,2.96c-6.84-3.95-15.28-3.95-22.12,0L9.3,125.94c-5.75,3.32-9.3,9.46-9.3,16.11v247.99c0,6.65,3.55,12.79,9.3,16.11l213.01,122.98c6.84,3.95,15.28,3.95,22.12,0l213.01-122.98c5.75-3.32,9.3-9.46,9.3-16.11v-247.99c0-6.65-3.55-12.79-9.3-16.11h-.01ZM444.05,151.99l-205.63,356.16c-1.39,2.4-5.06,1.42-5.06-1.36v-233.21c0-4.66-2.49-8.97-6.53-11.31L24.87,145.67c-2.4-1.39-1.42-5.06,1.36-5.06h411.26c5.84,0,9.49,6.33,6.57,11.39h-.01Z"/>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="2017" height="420" viewBox="0 0 2017 420" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M1424.99 4.51883C1407.48 -1.17117 1389.04 -1.49117 1371.66 3.57883C1352.68 9.11883 1336.33 20.7488 1324.37 37.2188L1107.47 335.759C1104.64 339.659 1100.88 340.879 1096.29 339.389C1091.71 337.899 1089.38 334.699 1089.38 329.879V90.1188C1089.38 69.7688 1082.99 50.7488 1070.89 35.1088C1059.81 20.7888 1044.7 10.2188 1027.19 4.52883C1009.68 -1.16117 991.239 -1.48117 973.859 3.58883C954.879 9.12883 938.529 20.7588 926.569 37.2288L709.669 335.769C706.839 339.669 703.069 340.889 698.489 339.399C693.899 337.909 691.579 334.709 691.579 329.889V210.009C691.579 187.919 673.669 170.009 651.579 170.009C629.489 170.009 611.579 187.919 611.579 210.009V329.889C611.579 350.239 617.969 369.259 630.069 384.899C641.149 399.219 656.259 409.789 673.769 415.479C683.039 418.489 692.569 419.999 702.069 419.999C710.509 419.999 718.919 418.809 727.099 416.419C746.079 410.879 762.429 399.249 774.389 382.779L991.289 84.2388C994.119 80.3388 997.879 79.1188 1002.47 80.6088C1007.05 82.0988 1009.38 85.2988 1009.38 90.1188V329.879C1009.38 350.229 1015.77 369.249 1027.87 384.889C1038.95 399.209 1054.06 409.779 1071.57 415.469C1089.08 421.159 1107.52 421.489 1124.9 416.409C1143.88 410.869 1160.23 399.239 1172.19 382.769L1389.09 84.2288C1391.92 80.3288 1395.69 79.1088 1400.27 80.5988C1404.85 82.0888 1407.18 85.2888 1407.18 90.1088V379.959C1407.18 402.049 1425.09 419.959 1447.18 419.959C1469.27 419.959 1487.18 402.049 1487.18 379.959V90.1188C1487.18 69.7688 1480.79 50.7488 1468.69 35.1088C1457.61 20.7888 1442.5 10.2188 1424.99 4.52883V4.51883ZM363.419 80.0188H517.429C539.519 80.0188 557.429 62.1088 557.429 40.0188C557.429 17.9288 539.519 0.018832 517.429 0.018832H363.419C302.799 0.018832 245.339 29.2988 209.709 78.3388L7.63908 356.459C-5.34092 374.329 -1.38092 399.349 16.4891 412.329C23.5891 417.489 31.8191 419.969 39.9691 419.969C52.3391 419.969 64.5391 414.249 72.3591 403.479L150.949 295.299C171.579 266.929 204.839 249.989 239.919 249.989H517.419C539.509 249.989 557.419 232.079 557.419 209.989C557.419 187.899 539.509 169.989 517.419 169.989H241.999L274.429 125.359C295.059 96.9688 328.329 80.0188 363.419 80.0188ZM1826.52 0.018832H1731.33C1626.56 0.018832 1541.33 85.2488 1541.33 190.019V229.969C1541.33 334.739 1626.56 419.969 1731.33 419.969H1826.52C1931.29 419.969 2016.52 334.739 2016.52 229.969V190.019C2016.52 85.2488 1931.28 0.018832 1826.52 0.018832ZM1936.52 229.969C1936.52 290.619 1887.17 339.969 1826.52 339.969H1731.33C1670.68 339.969 1621.33 290.619 1621.33 229.969V190.019C1621.33 129.369 1670.68 80.0188 1731.33 80.0188H1826.52C1887.17 80.0188 1936.52 129.369 1936.52 190.019V229.969ZM651.579 80.0188C673.669 80.0188 691.579 62.1088 691.579 40.0188C691.579 17.9288 673.669 0.018832 651.579 0.018832C629.489 0.018832 611.579 17.9288 611.579 40.0188C611.579 62.1088 629.489 80.0188 651.579 80.0188Z" fill="black"/>
|
|
3
|
+
</svg>
|
|
@@ -1,104 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
{
|
|
3
|
-
title: 'Update this website',
|
|
4
|
-
ui: 'Use Preview, Content, or Code in the Fimo UI to edit the site directly.',
|
|
5
|
-
cli: 'Edit the homepage locally and shape the page in your own editor.',
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
title: 'Publish',
|
|
9
|
-
ui: 'Click Publish in the top-right corner when you are ready to go live.',
|
|
10
|
-
cli: 'Run the publish command from the terminal when you are ready to go live.',
|
|
11
|
-
},
|
|
12
|
-
];
|
|
13
|
-
|
|
14
|
-
const links = [
|
|
15
|
-
{ label: 'Documentation', href: 'https://docs.fimo.ai' },
|
|
16
|
-
{ label: 'Community', href: 'https://fimo.ai' },
|
|
17
|
-
{ label: 'Blog', href: 'https://blog.fimo.ai' },
|
|
18
|
-
{ label: 'Roadmap', href: 'https://fimo.canny.io' },
|
|
19
|
-
{ label: 'Discord', href: 'https://discord.fimo.ai' },
|
|
20
|
-
];
|
|
1
|
+
import { AppWindow, Globe, SquareTerminal } from 'lucide-react';
|
|
21
2
|
|
|
22
3
|
const Index = () => {
|
|
23
4
|
return (
|
|
24
|
-
<div className="relative min-h-screen overflow-hidden bg-
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<div className="rounded-2xl border border-orange-200 bg-orange-50 p-4">
|
|
61
|
-
<p className="text-xs font-semibold tracking-[0.24em] text-orange-700 uppercase">CLI</p>
|
|
62
|
-
<p className="mt-2 text-sm leading-6 text-zinc-700">
|
|
63
|
-
{action.title === 'Update this website' ? (
|
|
64
|
-
<>
|
|
65
|
-
Edit{' '}
|
|
66
|
-
<code className="rounded bg-white px-1.5 py-0.5 text-[0.95em] text-zinc-950">
|
|
67
|
-
src/pages/Index.tsx
|
|
68
|
-
</code>{' '}
|
|
69
|
-
locally and shape the page in your own editor.
|
|
70
|
-
</>
|
|
71
|
-
) : (
|
|
72
|
-
<>
|
|
73
|
-
Run{' '}
|
|
74
|
-
<code className="rounded bg-white px-1.5 py-0.5 text-[0.95em] text-zinc-950">
|
|
75
|
-
fimo deploy --publish
|
|
76
|
-
</code>{' '}
|
|
77
|
-
from the terminal when you are ready to go live.
|
|
78
|
-
</>
|
|
79
|
-
)}
|
|
80
|
-
</p>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
</article>
|
|
84
|
-
))}
|
|
85
|
-
</section>
|
|
86
|
-
|
|
87
|
-
<footer className="mt-16 border-t border-zinc-200 pt-8">
|
|
88
|
-
<div className="flex flex-wrap items-center justify-center gap-x-6 gap-y-3 text-sm text-zinc-500">
|
|
89
|
-
{links.map((link) => (
|
|
90
|
-
<a
|
|
91
|
-
key={link.label}
|
|
92
|
-
href={link.href}
|
|
93
|
-
target="_blank"
|
|
94
|
-
rel="noreferrer"
|
|
95
|
-
className="transition-colors hover:text-zinc-950"
|
|
96
|
-
>
|
|
97
|
-
{link.label}
|
|
98
|
-
</a>
|
|
99
|
-
))}
|
|
5
|
+
<div className="relative min-h-screen overflow-hidden bg-white">
|
|
6
|
+
<main className="mx-auto flex min-h-screen flex-col items-center px-6 py-16">
|
|
7
|
+
<div className="w-full max-w-3xl">
|
|
8
|
+
<img src="/fimo-logo-black.svg" alt="Fimo" className="pointer-events-none mb-8 h-6 w-auto" />
|
|
9
|
+
<div className="flex flex-col gap-8 text-zinc-500">
|
|
10
|
+
<p>Welcome to your new Fimo site!</p>
|
|
11
|
+
<ul className="space-y-8 sm:space-y-4">
|
|
12
|
+
<li className="flex flex-col gap-3 sm:flex-row sm:items-center">
|
|
13
|
+
<SquareTerminal className="hidden size-4 shrink-0 text-zinc-500 sm:block" />
|
|
14
|
+
<span>If you're working locally, you can edit it with your favorite coding agent or IDE.</span>
|
|
15
|
+
<span className="flex items-center gap-3">
|
|
16
|
+
<img src="/claude-color.svg" alt="Claude" className="pointer-events-none h-5 w-auto" />
|
|
17
|
+
<img src="/codex.svg" alt="Codex" className="pointer-events-none h-5 w-auto" />
|
|
18
|
+
<img src="/copilot-color.svg" alt="Copilot" className="pointer-events-none h-5 w-auto" />
|
|
19
|
+
<img src="/cursor-light.svg" alt="Cursor" className="pointer-events-none h-5 w-auto" />
|
|
20
|
+
</span>
|
|
21
|
+
</li>
|
|
22
|
+
<li className="flex flex-col gap-3 sm:flex-row sm:items-center">
|
|
23
|
+
<Globe className="hidden size-4 shrink-0 text-zinc-500 sm:block" />
|
|
24
|
+
<span>If you're on the web, you can edit it with the chat.</span>
|
|
25
|
+
</li>
|
|
26
|
+
</ul>
|
|
27
|
+
<hr />
|
|
28
|
+
<div className="flex flex-col gap-4 text-sm sm:flex-row">
|
|
29
|
+
<a href="https://fimo.ai" target="_blank" rel="noreferrer">
|
|
30
|
+
Fimo.ai
|
|
31
|
+
</a>
|
|
32
|
+
<a href="https://docs.fimo.ai" target="_blank" rel="noreferrer">
|
|
33
|
+
Documentation
|
|
34
|
+
</a>
|
|
35
|
+
<a href="https://blog.fimo.ai" target="_blank" rel="noreferrer">
|
|
36
|
+
Blog
|
|
37
|
+
</a>
|
|
38
|
+
<a href="https://fimo.canny.io" target="_blank" rel="noreferrer">
|
|
39
|
+
Roadmap
|
|
40
|
+
</a>
|
|
100
41
|
</div>
|
|
101
|
-
</
|
|
42
|
+
</div>
|
|
102
43
|
</div>
|
|
103
44
|
</main>
|
|
104
45
|
</div>
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { rmSync } from 'node:fs';
|
|
2
|
-
|
|
3
|
-
// Helpers around the workspace-`release.json` cleanup behaviour used by
|
|
4
|
-
// `publish-tarball.mjs`. Extracted so the cleanup logic can be unit
|
|
5
|
-
// tested without spinning up the full clean → build → bundle → pack →
|
|
6
|
-
// upload chain.
|
|
7
|
-
//
|
|
8
|
-
// The contract is small but worth pinning:
|
|
9
|
-
// 1. `cleanupReleaseFile` is idempotent and safe when the file is
|
|
10
|
-
// already absent.
|
|
11
|
-
// 2. `registerReleaseCleanup` wires cleanup to process.on('exit'),
|
|
12
|
-
// SIGINT, and SIGTERM so the file is removed on any termination
|
|
13
|
-
// path (including process.exit calls inside the publish script).
|
|
14
|
-
// 3. The `skip` option short-circuits both surfaces - `cleanupReleaseFile`
|
|
15
|
-
// checks it, and `registerReleaseCleanup` closes over it.
|
|
16
|
-
|
|
17
|
-
export function cleanupReleaseFile(releaseFile, options = {}) {
|
|
18
|
-
if (options.skip) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
try {
|
|
22
|
-
rmSync(releaseFile, { force: true });
|
|
23
|
-
return true;
|
|
24
|
-
} catch {
|
|
25
|
-
// Best effort. A stale release.json is annoying but not
|
|
26
|
-
// worth bailing the publish for.
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Registers cleanup against the Node lifecycle and returns a callable
|
|
32
|
-
// that does the cleanup once-only. Useful in two ways:
|
|
33
|
-
// a) The bottom of the publish script calls the returned function
|
|
34
|
-
// explicitly so the success path can log a confirmation line.
|
|
35
|
-
// b) Failure paths (process.exit / SIGINT / SIGTERM) hit the
|
|
36
|
-
// registered handlers and still run the cleanup.
|
|
37
|
-
//
|
|
38
|
-
// Idempotency is enforced via a closure flag - calling the returned
|
|
39
|
-
// function twice (e.g., once explicitly + once on exit) only removes
|
|
40
|
-
// the file the first time.
|
|
41
|
-
export function registerReleaseCleanup(releaseFile, options = {}) {
|
|
42
|
-
let alreadyCleaned = false;
|
|
43
|
-
const skip = options.skip === true;
|
|
44
|
-
|
|
45
|
-
const cleanupOnce = () => {
|
|
46
|
-
if (alreadyCleaned || skip) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
alreadyCleaned = true;
|
|
50
|
-
return cleanupReleaseFile(releaseFile);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
process.on('exit', cleanupOnce);
|
|
54
|
-
process.on('SIGINT', () => {
|
|
55
|
-
cleanupOnce();
|
|
56
|
-
process.exit(130);
|
|
57
|
-
});
|
|
58
|
-
process.on('SIGTERM', () => {
|
|
59
|
-
cleanupOnce();
|
|
60
|
-
process.exit(143);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
return cleanupOnce;
|
|
64
|
-
}
|