Merge branch 'master' into feat/parse-binary-file

This commit is contained in:
Chooooo 2024-10-10 19:52:42 +09:00 committed by GitHub
commit 59513b8d99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 546 additions and 71 deletions

View File

@ -33,6 +33,7 @@
"@codemirror/language": "^6.10.2",
"@codemirror/legacy-modes": "^6.4.0",
"@gitbutler/ui": "workspace:*",
"@gitbutler/shared": "workspace:*",
"@lezer/common": "^1.2.1",
"@lezer/highlight": "^1.2.0",
"@octokit/rest": "^20.1.1",

View File

@ -1,3 +1,4 @@
import { splitPromptMessages } from './anthropicUtils';
import {
SHORT_DEFAULT_COMMIT_TEMPLATE,
SHORT_DEFAULT_BRANCH_TEMPLATE,
@ -11,29 +12,11 @@ import {
} from '$lib/ai/types';
import { andThenAsync, ok, wrapAsync, type Result } from '$lib/result';
import Anthropic from '@anthropic-ai/sdk';
import type { MessageParam, RawMessageStreamEvent } from '@anthropic-ai/sdk/resources/messages.mjs';
import type { RawMessageStreamEvent } from '@anthropic-ai/sdk/resources/messages.mjs';
import type { Stream } from '@anthropic-ai/sdk/streaming.mjs';
const DEFAULT_MAX_TOKENS = 1024;
function splitPromptMessages(prompt: Prompt): [MessageParam[], string | undefined] {
const messages: MessageParam[] = [];
let system: string | undefined = undefined;
for (const message of prompt) {
if (message.role === 'system') {
system = message.content;
continue;
}
messages.push({
role: message.role,
content: message.content
});
}
return [messages, system];
}
export class AnthropicAIClient implements AIClient {
defaultCommitTemplate = SHORT_DEFAULT_COMMIT_TEMPLATE;
defaultBranchTemplate = SHORT_DEFAULT_BRANCH_TEMPLATE;

View File

@ -0,0 +1,35 @@
import { isMessageRole, type Prompt } from './types';
import { isStr } from '$lib/utils/string';
import type { MessageParam } from '@anthropic-ai/sdk/resources/messages.mjs';
export function splitPromptMessages(prompt: Prompt): [MessageParam[], string | undefined] {
const messages: MessageParam[] = [];
let system: string | undefined = undefined;
for (const message of prompt) {
if (message.role === 'system') {
system = message.content;
continue;
}
messages.push({
role: message.role,
content: message.content
});
}
return [messages, system];
}
export function messageParamToPrompt(messages: MessageParam[]): Prompt {
const result: Prompt = [];
for (const message of messages) {
if (!isStr(message.content)) continue;
if (!isMessageRole(message.role)) continue;
result.push({
role: message.role,
content: message.content
});
}
return result;
}

View File

@ -1,12 +1,28 @@
import { messageParamToPrompt, splitPromptMessages } from './anthropicUtils';
import {
SHORT_DEFAULT_BRANCH_TEMPLATE,
SHORT_DEFAULT_COMMIT_TEMPLATE,
SHORT_DEFAULT_PR_TEMPLATE
} from '$lib/ai/prompts';
import { ModelKind, type AIClient, type Prompt } from '$lib/ai/types';
import { map, type Result } from '$lib/result';
import type { AIClient, ModelKind, Prompt } from '$lib/ai/types';
import type { HttpClient } from '$lib/backend/httpClient';
function splitPromptMessagesIfNecessary(
modelKind: ModelKind,
prompt: Prompt
): [Prompt, string | undefined] {
switch (modelKind) {
case ModelKind.Anthropic: {
const [messages, system] = splitPromptMessages(prompt);
return [messageParamToPrompt(messages), system];
}
case ModelKind.OpenAI:
case ModelKind.Ollama:
return [prompt, undefined];
}
}
export class ButlerAIClient implements AIClient {
defaultCommitTemplate = SHORT_DEFAULT_COMMIT_TEMPLATE;
defaultBranchTemplate = SHORT_DEFAULT_BRANCH_TEMPLATE;
@ -19,11 +35,13 @@ export class ButlerAIClient implements AIClient {
) {}
async evaluate(prompt: Prompt): Promise<Result<string, Error>> {
const [messages, system] = splitPromptMessagesIfNecessary(this.modelKind, prompt);
const response = await this.cloud.postSafe<{ message: string }>(
'evaluate_prompt/predict.json',
{
body: {
messages: prompt,
messages,
system,
max_tokens: 400,
model_kind: this.modelKind
},

View File

@ -1,3 +1,4 @@
import { isStr } from '$lib/utils/string';
import type { Persisted } from '$lib/persisted/persisted';
import type { Result } from '$lib/result';
@ -30,6 +31,12 @@ export enum MessageRole {
Assistant = 'assistant'
}
export function isMessageRole(role: unknown): role is MessageRole {
if (!isStr(role)) return false;
const roles = Object.values(MessageRole);
return roles.includes(role as MessageRole);
}
export interface PromptMessage {
content: string;
role: MessageRole;

View File

@ -47,10 +47,10 @@
if (topPatch.remoteCommitId !== topPatch.id) return true;
return false;
});
const branchColorType = $derived<CommitStatus | 'localAndShadow'>(
const branchType = $derived<CommitStatus | 'localAndShadow'>(
hasShadow ? 'localAndShadow' : topPatch?.status ?? 'local'
);
const lineColor = $derived(getColorFromBranchType(branchColorType));
const lineColor = $derived(getColorFromBranchType(branchType));
// Pretty cumbersome way of getting the PR number, would be great if we can
// make it more concise somehow.
@ -69,7 +69,9 @@
}
function editTitle(title: string) {
branchController.updateBranchName(branch.id, title);
if (currentSeries?.name && title !== currentSeries.name) {
branchController.updateSeriesName(branch.id, currentSeries.name, title);
}
}
function editDescription(_description: string) {
@ -83,21 +85,29 @@
<div class="branch-header">
<div class="branch-info">
<StackingStatusIcon icon="tick-small" iconColor="#fff" color={lineColor} gap={false} lineTop />
<StackingStatusIcon
icon={branchType === 'integrated' ? 'tick-small' : 'remote-branch-small'}
iconColor="#fff"
color={lineColor}
gap={false}
lineTop
/>
<div class="text-14 text-bold branch-info__name">
<span class="remote-name">{$baseBranch.remoteName ?? 'origin'}/</span>
<BranchLabel {name} onChange={(name) => editTitle(name)} />
<Button
size="tag"
icon="open-link"
style="ghost"
onclick={(e: MouseEvent) => {
const url = gitHostBranch?.url;
if (url) openExternalUrl(url);
e.preventDefault();
e.stopPropagation();
}}
></Button>
{#if gitHostBranch}
<Button
size="tag"
icon="open-link"
style="ghost"
onclick={(e: MouseEvent) => {
const url = gitHostBranch?.url;
if (url) openExternalUrl(url);
e.preventDefault();
e.stopPropagation();
}}
></Button>
{/if}
</div>
<div class="branch-info__btns">
<Button
@ -127,33 +137,43 @@
/>
</div>
{/if}
<div class="branch-action">
<div class="branch-action__line" style:--bg-color={lineColor}></div>
<div class="branch-action__body">
{#if $pr}
<StackingPullRequestCard pr={$pr} {prMonitor} sourceBranch={$pr.sourceBranch} />
{:else}
<Button
style="ghost"
wide
outline
disabled={commits.length === 0 || !$gitHost || !$prService}
onclick={handleOpenPR}>Create pull request</Button
>
{/if}
{#if gitHostBranch}
<div class="branch-action">
<div class="branch-action__line" style:--bg-color={lineColor}></div>
<div class="branch-action__body">
{#if $pr}
<StackingPullRequestCard pr={$pr} {prMonitor} sourceBranch={$pr.sourceBranch} />
{:else}
<Button
style="ghost"
wide
outline
disabled={commits.length === 0 || !$gitHost || !$prService}
onclick={handleOpenPR}>Create pull request</Button
>
{/if}
</div>
</div>
</div>
{/if}
<PrDetailsModal
bind:this={prDetailsModal}
type="preview-series"
{upstreamName}
{name}
{commits}
/>
</div>
<PrDetailsModal bind:this={prDetailsModal} type="preview-series" {upstreamName} {name} {commits} />
<style lang="postcss">
.branch-header {
display: flex;
border-bottom: 1px solid var(--clr-border-2);
display: flex;
flex-direction: column;
overflow: hidden;
&:not(:last-child) {
border-bottom: 1px solid var(--clr-border-2);
}
}
.branch-info {

View File

@ -4,7 +4,7 @@
const FALLBACK_COLOR = 'var(--clr-scale-ntrl-80)';
interface Props {
icon: 'plus-small' | 'tick-small' | 'virtual-branch-small';
icon: 'plus-small' | 'tick-small' | 'remote-branch-small';
iconColor?: string;
color?: string;
gap?: boolean;

View File

@ -55,6 +55,9 @@
let files: RemoteFile[] = [];
let showDetails = false;
$: conflicted = commit.conflicted;
$: isAncestorMostConflicted = branch?.ancestorMostConflictedCommit?.id === commit.id;
async function loadFiles() {
files = await listRemoteCommitFiles(project.id, commit.id);
}
@ -91,6 +94,8 @@
let createRefModal: Modal;
let createRefName = $baseBranch.remoteName + '/';
let conflictResolutionConfirmationModal: ReturnType<typeof Modal> | undefined;
function openCommitMessageModal(e: Event) {
e.stopPropagation();
@ -138,11 +143,16 @@
async function editPatch() {
if (!canEdit()) return;
modeService!.enterEditMode(commit.id, branch!.refname);
}
$: conflicted = commit.conflicted;
async function handleEditPatch() {
if (conflicted && !isAncestorMostConflicted) {
conflictResolutionConfirmationModal?.show();
return;
}
await editPatch();
}
</script>
<Modal bind:this={commitMessageModal} width="small" onSubmit={submitCommitMessageModal}>
@ -187,6 +197,20 @@
{/snippet}
</Modal>
<Modal bind:this={conflictResolutionConfirmationModal} width="small" onSubmit={editPatch}>
{#snippet children()}
<div>
<p>It's generally better to start resolving conflicts from the bottom up.</p>
<br />
<p>Are you sure you want to resolve conflicts for this commit?</p>
</div>
{/snippet}
{#snippet controls(close)}
<Button style="ghost" outline type="reset" onclick={close}>Cancel</Button>
<Button style="pop" outline type="submit">Yes</Button>
{/snippet}
</Modal>
<CommitContextMenu
bind:this={contextMenu}
targetElement={draggableCommitElement}
@ -397,7 +421,7 @@
>
{/if}
{#if canEdit()}
<Button size="tag" style="ghost" outline onclick={editPatch}>
<Button size="tag" style="ghost" outline onclick={handleEditPatch}>
{#if conflicted}
Resolve conflicts
{:else}

View File

@ -52,8 +52,8 @@
let aiLoading = false;
let aiConfigurationValid = false;
let titleTextArea: HTMLTextAreaElement;
let descriptionTextArea: HTMLTextAreaElement;
let titleTextArea: HTMLTextAreaElement | undefined;
let descriptionTextArea: HTMLTextAreaElement | undefined;
$: ({ title, description } = splitMessage(commitMessage));
$: valid = !!title;
@ -138,7 +138,7 @@
if (e.key === KeyName.Delete && value.length === 0) {
e.preventDefault();
if (titleTextArea) {
titleTextArea?.focus();
titleTextArea.focus();
titleTextArea.selectionStart = titleTextArea.textLength;
}
autoHeight(e.currentTarget);
@ -178,9 +178,11 @@
: `${toMove}\n${description}`;
commitMessage = concatMessage(toKeep, newDescription);
tick().then(() => {
descriptionTextArea?.focus();
descriptionTextArea.setSelectionRange(0, 0);
autoHeight(descriptionTextArea);
if (descriptionTextArea) {
descriptionTextArea.focus();
descriptionTextArea.setSelectionRange(0, 0);
autoHeight(descriptionTextArea);
}
});
}

View File

@ -402,6 +402,10 @@
&:not(.is-last) {
border-bottom: 1px solid var(--clr-border-2);
}
&.is-last {
border-radius: 0 0 var(--radius-m) var(--radius-m);
}
}
.commit-card {

View File

@ -34,7 +34,7 @@
<StackingBranchHeader
commits={currentSeries.patches}
name={currentSeries.branchName}
upstreamName={currentSeries.name}
upstreamName={currentSeries.upstreamReference ? currentSeries.name : undefined}
/>
<StackingCommitList
remoteOnlyPatches={currentSeries.upstreamPatches}

View File

@ -161,6 +161,14 @@ export class VirtualBranch {
return this.upstreamName || this.name;
}
get ancestorMostConflictedCommit(): DetailedCommit | undefined {
if (this.commits.length === 0) return undefined;
for (let i = this.commits.length - 1; i >= 0; i--) {
const commit = this.commits[i];
if (commit?.conflicted) return commit;
}
}
}
// Used for dependency injection

View File

@ -107,6 +107,10 @@ export class VirtualBranchService {
this.projectMetrics.setMetric('locked_hunk_count', lockedHunks.length);
this.projectMetrics.setMetric('file_count', files.length);
this.projectMetrics.setMetric('virtual_branch_count', branches.length);
this.projectMetrics.setMetric(
'max_stack_count',
Math.max(...branches.map((b) => b.series.length))
);
} catch (err: unknown) {
console.error(err);
}

58
packages/shared/README.md Normal file
View File

@ -0,0 +1,58 @@
# create-svelte
Everything you need to build a Svelte library, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
Read more about creating a library [in the docs](https://kit.svelte.dev/docs/packaging).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
## Building
To build your library:
```bash
npm run package
```
To create a production version of your showcase app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
## Publishing
Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
To publish your library to [npm](https://www.npmjs.com):
```bash
npm publish
```

View File

@ -0,0 +1,68 @@
{
"name": "@gitbutler/shared",
"version": "0.0.1",
"description": "UI Elements shared between GitButler Web and Desktop",
"scripts": {
"dev": "vite dev",
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "pnpm check --watch",
"package": "pnpm run --sequential \"/^package:.*/\"",
"package:svelte": "svelte-kit sync && svelte-package",
"prepublishOnly": "pnpm run package",
"prepare": "svelte-kit sync",
"test": "vitest run --mode development",
"test:watch": "vitest --watch --mode development"
},
"exports": {
"./*.svelte": {
"svelte": "./dist/*.svelte",
"types": "./dist/*.svelte.d.ts"
},
"./*": {
"import": "./dist/*.js",
"types": "./dist/*.d.ts"
},
"./*.css": {
"import": "./dist/styles/*.css"
},
"./*.json": {
"import": "./dist/*.json",
"types": "./dist/*.json"
}
},
"files": [
"dist",
"!dist/**/*.test.*",
"!dist/**/*.spec.*"
],
"peerDependencies": {
"svelte": "^4.0.0 || ^5.0.0-0"
},
"devDependencies": {
"@gitbutler/ui": "workspace:*",
"@csstools/postcss-bundler": "^1.0.15",
"@sveltejs/adapter-static": "catalog:svelte",
"@sveltejs/kit": "catalog:svelte",
"@sveltejs/package": "^2.3.2",
"@sveltejs/vite-plugin-svelte": "catalog:svelte",
"@terrazzo/cli": "^0.0.11",
"@terrazzo/plugin-css": "^0.0.9",
"@types/postcss-pxtorem": "^6.0.3",
"@vitest/browser": "^2.0.5",
"autoprefixer": "^10.4.19",
"cpy-cli": "^5.0.0",
"date-fns": "^2.30.0",
"playwright": "^1.46.1",
"postcss": "^8.4.38",
"postcss-cli": "^11.0.0",
"postcss-minify": "^1.1.0",
"postcss-nesting": "^12.1.5",
"postcss-pxtorem": "^6.1.0",
"rimraf": "^6.0.1",
"svelte": "catalog:svelte",
"svelte-check": "catalog:svelte",
"vite": "catalog:",
"vitest": "^2.0.5"
},
"type": "module"
}

View File

@ -0,0 +1,23 @@
import postcssBundler from '@csstools/postcss-bundler';
import autoprefixer from 'autoprefixer';
import postcssMinify from 'postcss-minify';
import postcssNesting from 'postcss-nesting';
import pxToRem from 'postcss-pxtorem';
export default {
plugins: [
pxToRem({
rootValue: 16,
unitPrecision: 5,
propList: ['*'],
selectorBlackList: [],
replace: true,
mediaQuery: false,
minPixelValue: 0
}),
autoprefixer(),
postcssNesting(),
postcssBundler(),
postcssMinify()
]
};

13
packages/shared/src/app.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
export {};

View File

@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div>%sveltekit.body%</div>
</body>
</html>

View File

@ -0,0 +1,7 @@
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});

View File

@ -0,0 +1,4 @@
// Reexport your entry components here
export function foo() {
return 'foo';
}

View File

@ -0,0 +1,3 @@
<h1>Welcome to your library project</h1>
<p>Create your package using @sveltejs/package and preview/showcase your work with SvelteKit</p>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,22 @@
import staticAdapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess({ script: true }),
kit: {
adapter: staticAdapter({
pages: 'build',
assets: 'build',
fallback: 'index.html',
precompress: true,
strict: false
})
},
compilerOptions: {
css: 'injected',
enableSourcemap: true
}
};
export default config;

View File

@ -0,0 +1,40 @@
import { defineConfig } from '@terrazzo/cli';
import css from '@terrazzo/plugin-css';
function pxToRem(token) {
if (token.$type === 'dimension' && token.$value.slice(-2) === 'px') {
return token.$value.slice(0, -2) / 16 + 'rem';
}
}
function clearFxPrefix(id) {
if (id.includes('fx.')) {
return id.replace('fx.', '').replace('.', '-');
}
}
export default defineConfig({
tokens: './src/lib/data/design-tokens.json',
outDir: './src/styles/core',
plugins: [
css({
filename: 'design-tokens.css',
modeSelectors: [
{
mode: 'dark',
selectors: [':root.dark']
}
],
p3: false,
transform: pxToRem,
generateName(variableId) {
return clearFxPrefix(variableId);
},
utility: {
bg: ['clr.bg.*'],
text: ['clr.text.*'],
border: ['clr.border.*']
}
})
]
});

View File

@ -0,0 +1,32 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"target": "es6",
"lib": ["dom", "dom.iterable", "ES2021"],
"allowJs": true,
"checkJs": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"experimentalDecorators": true
},
"include": [
".svelte-kit/ambient.d.ts",
".svelte-kit/non-ambient.d.ts",
".svelte-kit/types/**/$types.d.ts",
"terrazzo.config.js",
"postcss.config.js",
"vite.config.js",
"vite.config.ts",
"vitest.workspace.ts",
"src/**/*.js",
"src/**/*.ts",
"src/**/*.svelte",
"tests/**/*.js",
"tests/**/*.ts",
"tests/**/*.svelte"
]
}

View File

@ -0,0 +1,9 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [sveltekit()],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
}
});

View File

@ -139,6 +139,9 @@ importers:
'@codemirror/legacy-modes':
specifier: ^6.4.0
version: 6.4.0
'@gitbutler/shared':
specifier: workspace:*
version: link:../../packages/shared
'@gitbutler/ui':
specifier: workspace:*
version: link:../../packages/ui
@ -336,6 +339,81 @@ importers:
specifier: 'catalog:'
version: 5.2.13(@types/node@22.3.0)
packages/shared:
devDependencies:
'@csstools/postcss-bundler':
specifier: ^1.0.15
version: 1.0.15(postcss@8.4.39)
'@gitbutler/ui':
specifier: workspace:*
version: link:../ui
'@sveltejs/adapter-static':
specifier: catalog:svelte
version: 3.0.4(@sveltejs/kit@2.5.25(@sveltejs/vite-plugin-svelte@4.0.0-next.6(svelte@5.0.0-next.243)(vite@5.2.13(@types/node@22.3.0)))(svelte@5.0.0-next.243)(vite@5.2.13(@types/node@22.3.0)))
'@sveltejs/kit':
specifier: catalog:svelte
version: 2.5.25(@sveltejs/vite-plugin-svelte@4.0.0-next.6(svelte@5.0.0-next.243)(vite@5.2.13(@types/node@22.3.0)))(svelte@5.0.0-next.243)(vite@5.2.13(@types/node@22.3.0))
'@sveltejs/package':
specifier: ^2.3.2
version: 2.3.2(svelte@5.0.0-next.243)(typescript@5.4.5)
'@sveltejs/vite-plugin-svelte':
specifier: catalog:svelte
version: 4.0.0-next.6(svelte@5.0.0-next.243)(vite@5.2.13(@types/node@22.3.0))
'@terrazzo/cli':
specifier: ^0.0.11
version: 0.0.11
'@terrazzo/plugin-css':
specifier: ^0.0.9
version: 0.0.9(@terrazzo/cli@0.0.11)
'@types/postcss-pxtorem':
specifier: ^6.0.3
version: 6.0.3
'@vitest/browser':
specifier: ^2.0.5
version: 2.0.5(playwright@1.46.1)(typescript@5.4.5)(vitest@2.0.5)(webdriverio@8.40.2)
autoprefixer:
specifier: ^10.4.19
version: 10.4.19(postcss@8.4.39)
cpy-cli:
specifier: ^5.0.0
version: 5.0.0
date-fns:
specifier: ^2.30.0
version: 2.30.0
playwright:
specifier: ^1.46.1
version: 1.46.1
postcss:
specifier: ^8.4.38
version: 8.4.39
postcss-cli:
specifier: ^11.0.0
version: 11.0.0(postcss@8.4.39)
postcss-minify:
specifier: ^1.1.0
version: 1.1.0(postcss@8.4.39)
postcss-nesting:
specifier: ^12.1.5
version: 12.1.5(postcss@8.4.39)
postcss-pxtorem:
specifier: ^6.1.0
version: 6.1.0(postcss@8.4.39)
rimraf:
specifier: ^6.0.1
version: 6.0.1
svelte:
specifier: catalog:svelte
version: 5.0.0-next.243
svelte-check:
specifier: catalog:svelte
version: 4.0.1(svelte@5.0.0-next.243)(typescript@5.4.5)
vite:
specifier: 'catalog:'
version: 5.2.13(@types/node@22.3.0)
vitest:
specifier: ^2.0.5
version: 2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(happy-dom@14.12.3)(jsdom@24.1.1)
packages/ui:
devDependencies:
'@csstools/postcss-bundler':

View File

@ -2,10 +2,11 @@
"$schema": "https://turborepo.org/schema.json",
"tasks": {
"package": {
"dependsOn": ["^package"],
"outputs": ["dist/**"]
},
"build": {
"dependsOn": ["^package"],
"dependsOn": ["package"],
"passThroughEnv": ["SENTRY_AUTH_TOKEN", "GITHUB_TOKEN"],
"env": ["SENTRY_RELEASE"],
"outputs": [
@ -17,20 +18,19 @@
]
},
"dev": {
"dependsOn": ["@gitbutler/ui#package"],
"dependsOn": ["package"],
"cache": false,
"persistent": true
},
"check": {
"dependsOn": ["@gitbutler/ui#package"]
"dependsOn": ["package"]
},
"playwright:install": {},
"test": {
"dependsOn": ["@gitbutler/ui#package", "playwright:install"]
"dependsOn": ["package", "playwright:install"]
},
"//#globallint": {
// Root rules require dependencies to manually be listed https://github.com/vercel/turbo/discussions/7481
"dependsOn": ["@gitbutler/ui#package"]
"dependsOn": ["@gitbutler/ui#package", "@gitbutler/shared#package"]
}
}
}