engineering blog at https://blog.tangled.sh

Compare changes

Choose any two refs to compare.

+6 -6
flake.lock
··· 69 69 "nixpkgs": "nixpkgs_2" 70 70 }, 71 71 "locked": { 72 - "lastModified": 1751977408, 73 - "narHash": "sha256-g9N7+p0LKWdFV/LHEhFX8fJajyzegkxOOhIkTNAicGw=", 72 + "lastModified": 1758224598, 73 + "narHash": "sha256-Ai+kyEpZVPTuk0IP34kE8ZaXxhI+Z97msUFPe82k0Ic=", 74 74 "ref": "refs/heads/master", 75 - "rev": "d3aff34752cd06a62e4177da654a84b93bca4824", 76 - "revCount": 93, 75 + "rev": "e67e553dc237e41adc9ceae4d834fc02d44e4eb4", 76 + "revCount": 96, 77 77 "type": "git", 78 - "url": "https://tangled.sh/@icyphox.sh/vite" 78 + "url": "https://tangled.sh/@anirudh.fi/vite" 79 79 }, 80 80 "original": { 81 81 "type": "git", 82 - "url": "https://tangled.sh/@icyphox.sh/vite" 82 + "url": "https://tangled.sh/@anirudh.fi/vite" 83 83 } 84 84 } 85 85 },
+1 -1
flake.nix
··· 4 4 inputs = { 5 5 nixpkgs.url = "github:nixos/nixpkgs"; 6 6 vite = { 7 - url = "git+https://tangled.sh/@icyphox.sh/vite"; 7 + url = "git+https://tangled.sh/@anirudh.fi/vite"; 8 8 flake = true; 9 9 }; 10 10 inter-fonts-src = {
+1 -1
input.css
··· 97 97 } 98 98 99 99 img { 100 - @apply dark:brightness-75 dark:opacity-90 border border-gray-200 rounded-sm dark:border-gray-700; 100 + @apply border border-gray-200 rounded dark:border-gray-700; 101 101 } 102 102 103 103 img.icon {
+120 -54
pages/blog/6-months.md
··· 2 2 atroot: true 3 3 template: 4 4 slug: 6-months 5 - title: 6 months of tangling 6 - subtitle: new domain, a quick recap, and notes on the future 7 - date: 2025-09-17 8 - image: /static/img/logo_with_text.jpeg 5 + title: 6 months of Tangled 6 + subtitle: a quick recap, and notes on the future 7 + date: 2025-10-21 8 + image: /static/img/6-months.png 9 9 authors: 10 10 - name: Anirudh 11 - email: anirudh@tangled.sh 12 - handle: icyphox.sh 11 + email: anirudh@tangled.org 12 + handle: anirudh.fi 13 13 - name: Akshay 14 - email: akshay@tangled.sh 14 + email: akshay@tangled.org 15 15 handle: oppi.li 16 - draft: true 16 + draft: false 17 17 --- 18 18 19 - Hello Tanglers! It's been over 6 months since we launched Tangled, so we 20 - figured we'd do a quick retrospective on what we shipped and what's 21 - next. 22 - 23 - But before that, we've got a big announcement! 24 - 25 - ## tangled.sh is now tangled.org! 19 + Hello Tanglers! It's been over 6 months since we first announced 20 + Tangled, so we figured we'd do a quick retrospective of what we built so 21 + far and what's next. 26 22 27 - Yep! We managed to get the tangled.org domain thanks to [Chris 28 - Maytag](https://bsky.app/profile/cpm5280.bsky.social) who very kindly 29 - let us have it! 30 - 31 - We're still in the process of migrating and there may be stray 32 - references to the .sh domain in places so bear with us. Rest assured: 33 - your current links to tangled.sh will be redirected to tangled.org. 23 + If you're new here, here's a quick overview: Tangled is a git hosting 24 + and collaboration platform built on top of the [AT 25 + Protocol](https://atproto.com). You can read a bit more about our 26 + architecture [here](/intro). 34 27 35 28 ## new logo and mascot: dolly! 36 29 37 - Tangled finally has a logo! Designed by Akshay himself, Dolly is in reference to the first ever *cloned* mammal. 30 + Tangled finally has a logo! Designed by Akshay himself, Dolly is in 31 + reference to the first ever *cloned* mammal. For a full set of brand assets and guidelines, see our new [branding page](https://tangled.org/brand). 38 32 39 33 ![logo with text](/static/img/logo_with_text.jpeg) 40 34 41 - ## major platform highlights 35 + With that, let's recap the major platform improvements so far! 36 + 37 + ## pull requests: doubling down on jujutsu 42 38 43 - One of the first major features we built was our pull requests system, 44 - which follows a unique round-based submission & review approach. This 45 - was really fun to innovate on -- it remains one of Tangled's core 46 - differentiators, and one we plan to keep improving. 39 + One of the first major features we built was our [pull requests 40 + system](/pulls), which follows a unique round-based submission & review 41 + approach. This was really fun to innovate on -- it remains one of 42 + Tangled's core differentiators, and one we plan to keep improving. 47 43 48 44 In the same vein, we're the first ever code forge to support [stacking 49 45 pull requests](/stacking) using Jujutsu! We're big fans of the tool and 50 46 we use it everyday as we hack on 51 - [core](https://tangled.sh/@tangled.sh/core). Ultimately, we think 52 - PR-based collaboration should evolve beyond the traditional model, and 53 - we're excited to keep experimenting with new ideas that make code review 54 - and contribution easier! 47 + [tangled.org/core](https://tangled.org/@tangled.org/core). 48 + 49 + Ultimately, we think PR-based collaboration should evolve beyond the 50 + traditional model, and we're excited to keep experimenting with new 51 + ideas that make code review and contribution easier! 52 + 53 + ## spindle 55 54 56 55 CI was our most requested feature, and we spent a *lot* of time debating 57 56 how to approach it. We considered integrating with existing platforms, 58 57 but none were good fits. So we gave in to NIH and [built spindle 59 - ourselves](/ci)! This turned out great -- we could go all in on Nix and 60 - make it "atproto native". It also attracted a chunk of the Nix crowd, 61 - which we're very happy about! 58 + ourselves](/ci)! This allowed us to go in on Nix using Nixery to build 59 + CI images on the fly and cache them. 62 60 63 - Spindle is still early but designed to be extensible. The current 64 - Docker-based engine is limiting -- we plan to switch to micro VMs 65 - eventually. Meanwhile, if you've got ideas for other spindle backends 66 - (Kubernetes?!), we'd love patches! 61 + Spindle is still early but designed to be extensible and is AT-native. 62 + The current Docker/Nixery-based engine is limiting -- we plan to switch 63 + to micro VMs down the line to run full-fledged NixOS (and other base 64 + images). Meanwhile, if you've got ideas for other spindle backends 65 + (Kubernetes?!), we'd love to [hear from you](https://chat.tangled.org). 67 66 68 - A rather large change we recently introduced was a complete migration of 69 - the knotserver to an [XRPC](https://atproto.com/specs/xrpc) API. 70 - Alongside this, we also decoupled the knot from the appview by getting 71 - rid of the registration secret, which was centralizing. Knots (and 72 - spindles) simply declare their owner, which any appview can verify. Once 73 - we stabilize the [lexicon definitions](lexicons) for these XRPC calls, 74 - building clients for knots (or entire appviews!) should become much simpler. 67 + ## XRPC APIs 68 + 69 + We introduced a complete migration of the knotserver to an 70 + [XRPC](https://atproto.com/specs/xrpc) API. Alongside this, we also 71 + decoupled the knot from the appview by getting rid of the registration 72 + secret, which was centralizing. Knots (and spindles) simply declare 73 + their owner, and any appview can verify ownership. Once we stabilize the 74 + [lexicon definitions](lexicons) for these XRPC calls, building clients 75 + for knots, or alternate implementations should become much simpler. 75 76 76 77 [lexicons]: https://tangled.sh/@tangled.sh/core/tree/master/lexicons 77 78 78 - Issues got a major rework too! They are now threaded: top-level comments 79 - with replies. This makes Q/A style discussions much easier to follow! 79 + ## issues rework 80 + 81 + Issues got a major rework (and facelift) too! They are now threaded: 82 + top-level comments with replies. This makes Q/A style discussions much 83 + easier to follow! 80 84 81 85 ![issue thread](/static/img/issue-threading.webp) 82 86 87 + ## hosted PDS 88 + 89 + A complaint we often recieved was the need for a Bluesky account to use 90 + Tangled; and besides, we realised that the overlap between Bluesky users 91 + and possible Tangled users only goes so far -- we aim to be a generic 92 + code forge after all, AT just happens to be an implementation 93 + detail. 94 + 95 + To address this, we spun up the tngl.sh PDS hosted right here in 96 + Finland. The only way to get an account on this PDS is by [signing 97 + up](https://tangled.sh/signup). There's a lot we can do to improve this 98 + experience as a generic PDS host, but we're still working out details 99 + around that. 100 + 101 + ## labels 102 + 103 + You can easily categorize issues and pulls via labels! There is plenty 104 + of customization available: 105 + 106 + - labels can be basic, or they can have a key and value set, for example: 107 + `wontfix` or `priority/high` 108 + - labels can be constrained to a set of values: `priority: [high medium low]` 109 + - there can be multiple labels of a given type: `reviewed-by: @oppi.li`, 110 + `reviewed-by: @anirudh.fi` 111 + 112 + The options are endless! You can access them via your repo's settings page. 113 + 114 + <div class="flex justify-center items-center gap-2"> 115 + <figure class="w-full m-0 flex flex-col items-center"> 116 + <a href="static/img/labels_vignette.webp"> 117 + <img class="my-1 w-full h-auto cursor-pointer" src="static/img/labels_vignette.webp" alt="A set of labels applied to an issue."> 118 + </a> 119 + <figcaption class="text-center">A set of labels applied to an issue.</figcaption> 120 + </figure> 121 + 122 + <figure class="w-1/3 m-0 flex flex-col items-center"> 123 + <a href="static/img/new_label_modal.png"> 124 + <img class="my-1 w-full h-auto cursor-pointer" src="static/img/new_label_modal.png" alt="Create custom key-value type labels."> 125 + </a> 126 + <figcaption class="text-center">Create custom key-value type labels.</figcaption> 127 + </figure> 128 + </div> 129 + 130 + 131 + ## notifications 132 + 133 + In-app notifications now exist! You get notifications for a variety of events now: 134 + 135 + * new issues/pulls on your repos (also for collaborators) 136 + * comments on your issues/pulls (also for collaborators) 137 + * close/reopen (or merge) of issues/pulls 138 + * new stars 139 + * new follows 140 + 141 + All of this can be fine-tuned in [/settings/notifications](https://tangled.org/settings/notifications). 142 + 143 + ![notifications](static/img/notifications.png) 144 + 145 + 83 146 ## the future 84 147 85 148 We're working on a *lot* of exciting new things and possibly some big 86 - announcements to come. For the next 6 months, the primary focus will be 87 - on these fronts: 149 + announcements to come. Be on the lookout for: 88 150 89 - * labels support for issues 90 - * notifications: both in-app and emails 151 + * email notifications 91 152 * preliminary support for issue and PR search 92 - * total federation and network playback 153 + * total "atprotation" [^1] -- the last two holdouts here are repo and pull records 154 + * total federation -- i.e. supporting third-party appviews by making it 155 + reproducible 156 + * achieve complete independence from Bluesky PBC by hosting our own relay 157 + 158 + That's all for now; we'll see you in the atmosphere! Meanwhile, if you'd like to contribute to projects on Tangled, make sure to check out the [good first issues page](https://tangled.org/goodfirstissues) to get started! 93 159 94 - That's all for now; we'll see you on the atmosphere! 160 + [^1]: atprotation implies a two-way sync between the PDS and appview. Currently, pull requests and repositories are not ingested -- so writing/updating either records on your PDS will not show up on the appview.
+1 -1
pages/blog/ci.md
··· 119 119 in your terminal if you've got Docker installed: 120 120 121 121 ``` 122 - docker run nixery.dev/bash/hello-go hello 122 + docker run nixery.dev/bash/hello-go hello-go 123 123 ``` 124 124 125 125 This should output `Hello, world!`. This is running the
static/img/6-months.png

This is a binary file and will not be displayed.

static/img/labels_vignette.webp

This is a binary file and will not be displayed.

static/img/new_label_modal.png

This is a binary file and will not be displayed.

static/img/notifications.png

This is a binary file and will not be displayed.

+5 -9
templates/partials/nav.html
··· 1 - <div class="w-full"> 2 - <div class="container mx-auto max-w-7xl px-4"> 3 - <div class="flex justify-start py-4 mb-8"> 4 - <a href="/" class="text-2xl no-underline hover:no-underline"> 5 - {{ template "fragments/logotypeSmall" }} 6 - </a> 7 - </div> 8 - </div> 9 - </div> 1 + <nav class="w-full flex items-center dark:text-white drop-shadow-sm bg-white dark:bg-gray-800 px-6 py-2 h-[44px]"> 2 + <a href="/" class="text-2xl no-underline hover:no-underline"> 3 + {{ template "fragments/logotypeSmall" }} 4 + </a> 5 + </nav>
+10 -2
templates/text.html
··· 5 5 <meta name="description" content="{{ index .Meta "subtitle" }}"> 6 6 <meta property="og:title" content="{{ .Meta.title }}" /> 7 7 <meta property="og:description" content="{{ .Meta.subtitle }}" /> 8 - <meta property="og:url" content="https://blog.tangled.sh/{{ .Meta.slug }}" /> 9 - <meta property="og:image" content="{{ .Meta.image }}" /> 8 + <meta property="og:url" content="https://blog.tangled.org/{{ .Meta.slug }}" /> 9 + <meta property="og:image" content="https://blog.tangled.org{{ .Meta.image }}" /> 10 10 <meta property="og:type" content="website" /> 11 + <meta property="og:image:width" content="1200" /> 12 + <meta property="og:image:height" content="630" /> 13 + 14 + <meta name="twitter:card" content="summary_large_image" /> 15 + <meta name="twitter:title" content="{{ .Meta.title }}" /> 16 + <meta name="twitter:description" content="{{ .Meta.subtitle }}" /> 17 + <meta name="twitter:image" content="https://blog.tangled.org{{ .Meta.image }}" /> 18 + 11 19 <title> 12 20 {{ index .Meta "title" }} 13 21 </title>