+202
-1
api/tangled/cbor_gen.go
+202
-1
api/tangled/cbor_gen.go
············
············
+16
-7
api/tangled/repopull.go
+16
-7
api/tangled/repopull.go
···-LexiconTypeID string `json:"$type,const=sh.tangled.repo.pull" cborgen:"$type,const=sh.tangled.repo.pull"`···
···+LexiconTypeID string `json:"$type,const=sh.tangled.repo.pull" cborgen:"$type,const=sh.tangled.repo.pull"`···
+10
api/tangled/repotree.go
+10
api/tangled/repotree.go
···
···
+4
-2
appview/config/config.go
+4
-2
appview/config/config.go
+147
appview/db/db.go
+147
appview/db/db.go
···+at_uri text generated always as ('at://' || owner_did || '/' || 'sh.tangled.repo.pull' || '/' || rkey) stored,+state integer not null default 0 check (state in (0, 1, 2, 3)), -- closed, open, merged, deleted
+13
-9
appview/db/email.go
+13
-9
appview/db/email.go
·········
···+func GetEmailToDid(e Execer, emails []string, isVerifiedFilter bool) (map[string]string, error) {······
+34
appview/db/language.go
+34
appview/db/language.go
······+func UpdateRepoLanguages(tx *sql.Tx, repoAt syntax.ATURI, ref string, langs []models.RepoLanguage) error {
+18
-25
appview/db/notifications.go
+18
-25
appview/db/notifications.go
······-// GetNotifications retrieves notifications for a user with pagination (legacy method for backward compatibility)-func (d *DB) GetNotifications(ctx context.Context, userDID string, limit, offset int) ([]*models.Notification, error) {-// GetNotificationsWithEntities retrieves notifications with entities for a user with pagination-func (d *DB) GetNotificationsWithEntities(ctx context.Context, userDID string, limit, offset int) ([]*models.NotificationWithEntity, error) {
······
+162
-233
appview/db/pulls.go
+162
-233
appview/db/pulls.go
·········-repo_at, owner_did, pull_id, title, target_branch, body, rkey, state, source_branch, source_repo_at, stack_id, change_id, parent_change_id·································
·········+repo_at, owner_did, pull_id, title, target_branch, body, rkey, state, source_branch, source_repo_at, stack_id, change_id, parent_at, parent_change_id························+pulls, err := GetPullsWithLimit(e, 1, FilterEq("repo_at", repoAt), FilterEq("pull_id", pullId))+func GetPullSubmissions(e Execer, filters ...filter) (map[syntax.ATURI][]*models.PullSubmission, error) {·········
+1
-1
appview/ingester.go
+1
-1
appview/ingester.go
···return fmt.Errorf("failed to find label def for key: %s, expected: %q", o.OperandKey, slices.Collect(maps.Keys(actx.Defs)))
+5
-1
appview/issues/issues.go
+5
-1
appview/issues/issues.go
+14
-4
appview/labels/labels.go
+14
-4
appview/labels/labels.go
··················
··················
+9
appview/middleware/middleware.go
+9
appview/middleware/middleware.go
···
+5
-4
appview/models/label.go
+5
-4
appview/models/label.go
···
···
+29
-1
appview/models/notifications.go
+29
-1
appview/models/notifications.go
······
+51
-4
appview/models/pull.go
+51
-4
appview/models/pull.go
··················
··················
+30
-35
appview/notifications/notifications.go
+30
-35
appview/notifications/notifications.go
···············
···············
+8
-48
appview/notify/db/db.go
+8
-48
appview/notify/db/db.go
························
························
+156
appview/pages/legal/privacy.md
+156
appview/pages/legal/privacy.md
···
···
+107
appview/pages/legal/terms.md
+107
appview/pages/legal/terms.md
···
···
+15
-17
appview/pages/markup/format.go
+15
-17
appview/pages/markup/format.go
······
······
+84
-16
appview/pages/pages.go
+84
-16
appview/pages/pages.go
·································
·····················+func (p *Pages) UserNotificationSettings(w io.Writer, params UserNotificationSettingsParams) error {············
+224
appview/pages/templates/brand/brand.html
+224
appview/pages/templates/brand/brand.html
···
···+<main class="col-span-full md:col-span-10 bg-white dark:bg-gray-800 drop-shadow-sm rounded p-6 md:px-10">+Tangled's logo and mascot is <strong>Dolly</strong>, the first ever <em>cloned</em> mammal. Please+All assets are served as SVGs, and can be downloaded by right-clicking and clicking "Save image as".+<div class="border border-gray-200 dark:border-gray-700 p-8 sm:p-16 bg-gray-50 dark:bg-gray-100 rounded">+This is the preferred version of the logotype, featuring dark text and elements, ideal for light+<div class="border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-100 p-8 sm:p-12 rounded">+<div class="border border-gray-200 dark:border-gray-700 p-8 sm:p-16 bg-gray-50 dark:bg-gray-100 rounded">
+4
-11
appview/pages/templates/errors/500.html
+4
-11
appview/pages/templates/errors/500.html
···<div class="w-16 h-16 mx-auto mb-4 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center">···-<div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded p-3 text-sm text-yellow-800 dark:text-yellow-200">
···<div class="w-16 h-16 mx-auto mb-4 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center">···
+3
appview/pages/templates/layouts/base.html
+3
appview/pages/templates/layouts/base.html
···<link rel="preload" href="/static/fonts/InterVariable.woff2" as="font" type="font/woff2" crossorigin />
+16
-6
appview/pages/templates/layouts/fragments/topbar.html
+16
-6
appview/pages/templates/layouts/fragments/topbar.html
···<nav class="space-x-4 px-6 py-2 rounded-b bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm">···<div class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700">···class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700"
···<nav class="space-x-4 px-6 py-2 rounded-b bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm">+<a href="/" hx-boost="true" class="text-2xl no-underline hover:no-underline flex items-center gap-2">+<span class="font-normal not-italic text-xs rounded bg-gray-100 dark:bg-gray-700 px-1 hidden md:inline">···<div class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700">···class="absolute flex flex-col right-0 mt-4 p-4 rounded w-48 bg-white dark:bg-gray-800 dark:text-white border border-gray-200 dark:border-gray-700"
+13
-6
appview/pages/templates/legal/privacy.html
+13
-6
appview/pages/templates/legal/privacy.html
···
···+<main class="col-span-full md:col-span-10 bg-white dark:bg-gray-800 drop-shadow-sm rounded p-6 md:px-10">
+13
-6
appview/pages/templates/legal/terms.html
+13
-6
appview/pages/templates/legal/terms.html
···
···+<main class="col-span-full md:col-span-10 bg-white dark:bg-gray-800 drop-shadow-sm rounded p-6 md:px-10">
+11
appview/pages/templates/notifications/fragments/bell.html
+11
appview/pages/templates/notifications/fragments/bell.html
···
···
+7
appview/pages/templates/notifications/fragments/count.html
+7
appview/pages/templates/notifications/fragments/count.html
···
···+<span class="absolute -top-1.5 -right-0.5 min-w-[16px] h-[16px] px-1 bg-red-500 text-white text-xs font-medium rounded-full flex items-center justify-center">
+81
appview/pages/templates/notifications/fragments/item.html
+81
appview/pages/templates/notifications/fragments/item.html
···
···+w-full mx-auto rounded drop-shadow-sm dark:text-white bg-white dark:bg-gray-800 px-2 md:px-6 py-4 transition-colors+{{if not .Read}}bg-blue-50 dark:bg-blue-800/20 border border-blue-500 dark:border-sky-800{{end}}+<span class="text-sm text-gray-500 dark:text-gray-400">{{ template "notificationSummary" . }}</span>+<div class="absolute border-2 border-white dark:border-gray-800 bg-gray-200 dark:bg-gray-700 bottom-1 right-1 rounded-full p-2 flex items-center justify-center z-10">+starred <span class="text-black dark:text-white">{{ resolve .Repo.Did }}/{{ .Repo.Name }}</span>
+65
appview/pages/templates/notifications/list.html
+65
appview/pages/templates/notifications/list.html
···
···+<div class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white">+<p class="text-gray-600 dark:text-gray-400">When you receive notifications, they'll appear here.</p>+class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700"+class="btn flex items-center gap-2 no-underline hover:no-underline dark:text-white dark:hover:bg-gray-700"
+7
appview/pages/templates/repo/fork.html
+7
appview/pages/templates/repo/fork.html
···<form hx-post="/{{ .RepoInfo.FullName }}/fork" class="space-y-12" hx-swap="none" hx-indicator="#spinner">
···<form hx-post="/{{ .RepoInfo.FullName }}/fork" class="space-y-12" hx-swap="none" hx-indicator="#spinner">+class="w-full p-2 border rounded bg-gray-100 dark:bg-gray-700 dark:text-white dark:border-gray-600" />
+1
-1
appview/pages/templates/repo/fragments/cloneDropdown.html
+1
-1
appview/pages/templates/repo/fragments/cloneDropdown.html
+1
-1
appview/pages/templates/repo/fragments/labelPanel.html
+1
-1
appview/pages/templates/repo/fragments/labelPanel.html
+26
appview/pages/templates/repo/fragments/participants.html
+26
appview/pages/templates/repo/fragments/participants.html
···
···+class="rounded-full h-8 w-8 mr-1 border-2 border-gray-100 dark:border-gray-900 z-{{sub 5 $i}}0"
+2
-2
appview/pages/templates/repo/fragments/readme.html
+2
-2
appview/pages/templates/repo/fragments/readme.html
···<div class="mt-4 rounded bg-white dark:bg-gray-800 drop-shadow-sm w-full mx-auto overflow-hidden">-<div class="px-4 py-2 bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600 flex items-center gap-2">
···<div class="mt-4 rounded bg-white dark:bg-gray-800 drop-shadow-sm w-full mx-auto overflow-hidden">
+1
-27
appview/pages/templates/repo/issues/issue.html
+1
-27
appview/pages/templates/repo/issues/issue.html
······-class="rounded-full h-8 w-8 mr-1 border-2 border-gray-100 dark:border-gray-900 z-{{sub 5 $i}}0"
+163
-61
appview/pages/templates/repo/new.html
+163
-61
appview/pages/templates/repo/new.html
···-<p class="text-sm text-gray-500 dark:text-gray-400">A knot hosts repository data. <a href="/knots" class="underline">Learn how to register your own knot.</a></p>
···+<div class="col-span-full md:col-start-3 md:col-span-8 bg-white dark:bg-gray-800 drop-shadow-sm rounded p-6 md:px-10">+<div class="text-sm text-gray-500 dark:text-gray-400 mb-4">Repository settings and hosting.</div>+<div class="shrink-0 hidden md:flex items-center px-2 py-2 gap-1 text-sm text-gray-700 dark:text-gray-300 md:border md:border-r-0 md:border-gray-300 md:dark:border-gray-600 md:rounded-l md:bg-gray-50 md:dark:bg-gray-700">+class="flex-1 dark:bg-gray-700 dark:text-white dark:border-gray-600 border border-gray-300 rounded md:rounded-r md:rounded-l-none px-3 py-2"+class="w-full w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 border border-gray-300 rounded px-3 py-2"+class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 border border-gray-300 rounded px-3 py-2"+<div class="w-full dark:bg-gray-700 dark:text-white dark:border-gray-600 border border-gray-300 rounded p-3 space-y-2">+<div class="w-6 h-6 bg-gray-200 dark:bg-gray-600 rounded-full flex items-center justify-center text-sm font-medium mt-1">
+30
-12
appview/pages/templates/repo/pulls/pull.html
+30
-12
appview/pages/templates/repo/pulls/pull.html
······-<div class="rounded drop-shadow-sm bg-white dark:bg-gray-800 p-2 text-gray-500 dark:text-gray-400">······-<div id="comment-{{$c.ID}}" class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full md:max-w-3/5 md:w-fit">
···+<section class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto dark:text-white">···+<div class="flex-1 rounded drop-shadow-sm bg-white dark:bg-gray-800 p-2 text-gray-500 dark:text-gray-400">······+<div id="comment-{{$c.ID}}" class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full">
+7
appview/pages/templates/repo/pulls/pulls.html
+7
appview/pages/templates/repo/pulls/pulls.html
···
+1
-1
appview/pages/templates/repo/tree.html
+1
-1
appview/pages/templates/repo/tree.html
+2
-2
appview/pages/templates/strings/put.html
+2
-2
appview/pages/templates/strings/put.html
···
···
+5
-7
appview/pages/templates/strings/timeline.html
+5
-7
appview/pages/templates/strings/timeline.html
······
···+<a href="/strings/{{ $resolved }}" class="flex gap-1 items-center">{{ template "user/fragments/picHandle" $resolved }}</a>···
+1
appview/pages/templates/user/completeSignup.html
+1
appview/pages/templates/user/completeSignup.html
+1
-1
appview/pages/templates/user/fragments/followCard.html
+1
-1
appview/pages/templates/user/fragments/followCard.html
···-<div class="flex flex-col divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded-sm">
···
+2
-2
appview/pages/templates/user/fragments/picHandle.html
+2
-2
appview/pages/templates/user/fragments/picHandle.html
+2
-3
appview/pages/templates/user/fragments/picHandleLink.html
+2
-3
appview/pages/templates/user/fragments/picHandleLink.html
+2
-1
appview/pages/templates/user/login.html
+2
-1
appview/pages/templates/user/login.html
······your Tangled (<code>.tngl.sh</code>) or <a href="https://bsky.app">Bluesky</a> (<code>.bsky.social</code>) account.
······your Tangled (<code>.tngl.sh</code>) or <a href="https://bsky.app">Bluesky</a> (<code>.bsky.social</code>) account.
+173
appview/pages/templates/user/settings/notifications.html
+173
appview/pages/templates/user/settings/notifications.html
···
···+<div class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto drop-shadow-sm dark:text-white">+Choose which notifications you want to receive when activity happens on your repositories and profile.+<div class="flex flex-col rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700 w-full">+<input type="checkbox" name="issue_commented" {{if .Preferences.IssueCommented}}checked{{end}}>+<input type="checkbox" name="email_notifications" {{if .Preferences.EmailNotifications}}checked{{end}}>
+7
-1
appview/pages/templates/user/signup.html
+7
-1
appview/pages/templates/user/signup.html
······
······
+1
-1
appview/pagination/page.go
+1
-1
appview/pagination/page.go
+59
-2
appview/pulls/pulls.go
+59
-2
appview/pulls/pulls.go
···························
···············+// build map from change id to existing at uris (ignore error as it shouldnt be possible here)+pAtUri, _ := syntax.ParseATURI(fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, p.Rkey))+// if change id has already been given a PR use its at uri instead of the newly created (and thus incorrect)············+// this is a bit of an ugly way to create the ATURI but its the best we can do with the data flow here+parsedParentAt, _ := syntax.ParseATURI(fmt.Sprintf("at://%s/%s/%s", user.Did, tangled.RepoPullNSID, pull.Rkey));
+17
-22
appview/repo/index.go
+17
-22
appview/repo/index.go
············
············
+16
-32
appview/repo/repo.go
+16
-32
appview/repo/repo.go
···············
···············
+65
-1
appview/signup/signup.go
+65
-1
appview/signup/signup.go
·········
·········
+14
-1
appview/state/knotstream.go
+14
-1
appview/state/knotstream.go
···
+5
-2
appview/state/router.go
+5
-2
appview/state/router.go
············
············
+35
-1
appview/state/state.go
+35
-1
appview/state/state.go
···posthog, err := posthog.NewWithConfig(config.Posthog.ApiKey, posthog.Config{Endpoint: config.Posthog.Endpoint})·········
···posthog, err := posthog.NewWithConfig(config.Posthog.ApiKey, posthog.Config{Endpoint: config.Posthog.Endpoint})·········
+15
-1
appview/validator/label.go
+15
-1
appview/validator/label.go
···-func (v *Validator) ValidateLabelOp(labelDef *models.LabelDefinition, labelOp *models.LabelOp) error {
···+func (v *Validator) ValidateLabelOp(labelDef *models.LabelDefinition, repo *models.Repo, labelOp *models.LabelOp) error {
+4
-1
appview/validator/validator.go
+4
-1
appview/validator/validator.go
···
···
+1
cmd/gen.go
+1
cmd/gen.go
+1
-1
docs/spindle/pipeline.md
+1
-1
docs/spindle/pipeline.md
···- `branch`: This is a **required** field that defines which branches the workflow should run for. If used with the `push` event, commits to the branch(es) listed here will trigger the workflow. If used with the `pull_request` event, updates to pull requests targeting the branch(es) listed here will trigger the workflow. This field has no effect with the `manual` event.-For example, if you'd like define a workflow that runs when commits are pushed to the `main` and `develop` branches, or when pull requests that target the `main` branch are updated, or manually, you can do so with:
···- `branch`: This is a **required** field that defines which branches the workflow should run for. If used with the `push` event, commits to the branch(es) listed here will trigger the workflow. If used with the `pull_request` event, updates to pull requests targeting the branch(es) listed here will trigger the workflow. This field has no effect with the `manual` event.+For example, if you'd like to define a workflow that runs when commits are pushed to the `main` and `develop` branches, or when pull requests that target the `main` branch are updated, or manually, you can do so with:
+1
-1
knotserver/config/config.go
+1
-1
knotserver/config/config.go
-103
knotserver/git/git.go
-103
knotserver/git/git.go
···············
···············
+1
-3
knotserver/git/tag.go
+1
-3
knotserver/git/tag.go
·········
·········
-4
knotserver/http_util.go
-4
knotserver/http_util.go
+1
-1
knotserver/xrpc/repo_blob.go
+1
-1
knotserver/xrpc/repo_blob.go
+24
knotserver/xrpc/repo_tree.go
+24
knotserver/xrpc/repo_tree.go
·········
·········
-158
legal/privacy.md
-158
legal/privacy.md
···
···
-109
legal/terms.md
-109
legal/terms.md
···
···
-29
lexicons/pulls/pull.json
-29
lexicons/pulls/pull.json
·········
+96
lexicons/pulls/round.json
+96
lexicons/pulls/round.json
···
···+"description": "A patch describing this change. Either gotten directly from the user (patch-based PR) or from the knot based on a commit from another repo. The source of the patch and it's potential details are described by sourceInfo"
+19
lexicons/repo/tree.json
+19
lexicons/repo/tree.json
······
+1
-1
nix/pkgs/knot-unwrapped.nix
+1
-1
nix/pkgs/knot-unwrapped.nix
+7
-5
types/repo.go
+7
-5
types/repo.go
···
···