···11-// Folder-specific settings
22-//
33-// For a full list of overridable settings, and general information on folder-specific settings,
44-// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
55-{
66- "languages": {
77- "HTML": {
88- "prettier": {
99- "format_on_save": false,
1010- "allowed": true,
1111- "parser": "go-template",
1212- "plugins": ["prettier-plugin-go-template"]
1313- }
1414- }
1515- }
1616-}
+183-600
api/tangled/cbor_gen.go
···2141214121422142 return nil
21432143}
21442144+func (t *Knot) MarshalCBOR(w io.Writer) error {
21452145+ if t == nil {
21462146+ _, err := w.Write(cbg.CborNull)
21472147+ return err
21482148+ }
21492149+21502150+ cw := cbg.NewCborWriter(w)
21512151+21522152+ if _, err := cw.Write([]byte{162}); err != nil {
21532153+ return err
21542154+ }
21552155+21562156+ // t.LexiconTypeID (string) (string)
21572157+ if len("$type") > 1000000 {
21582158+ return xerrors.Errorf("Value in field \"$type\" was too long")
21592159+ }
21602160+21612161+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
21622162+ return err
21632163+ }
21642164+ if _, err := cw.WriteString(string("$type")); err != nil {
21652165+ return err
21662166+ }
21672167+21682168+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("sh.tangled.knot"))); err != nil {
21692169+ return err
21702170+ }
21712171+ if _, err := cw.WriteString(string("sh.tangled.knot")); err != nil {
21722172+ return err
21732173+ }
21742174+21752175+ // t.CreatedAt (string) (string)
21762176+ if len("createdAt") > 1000000 {
21772177+ return xerrors.Errorf("Value in field \"createdAt\" was too long")
21782178+ }
21792179+21802180+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil {
21812181+ return err
21822182+ }
21832183+ if _, err := cw.WriteString(string("createdAt")); err != nil {
21842184+ return err
21852185+ }
21862186+21872187+ if len(t.CreatedAt) > 1000000 {
21882188+ return xerrors.Errorf("Value in field t.CreatedAt was too long")
21892189+ }
21902190+21912191+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil {
21922192+ return err
21932193+ }
21942194+ if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
21952195+ return err
21962196+ }
21972197+ return nil
21982198+}
21992199+22002200+func (t *Knot) UnmarshalCBOR(r io.Reader) (err error) {
22012201+ *t = Knot{}
22022202+22032203+ cr := cbg.NewCborReader(r)
22042204+22052205+ maj, extra, err := cr.ReadHeader()
22062206+ if err != nil {
22072207+ return err
22082208+ }
22092209+ defer func() {
22102210+ if err == io.EOF {
22112211+ err = io.ErrUnexpectedEOF
22122212+ }
22132213+ }()
22142214+22152215+ if maj != cbg.MajMap {
22162216+ return fmt.Errorf("cbor input should be of type map")
22172217+ }
22182218+22192219+ if extra > cbg.MaxLength {
22202220+ return fmt.Errorf("Knot: map struct too large (%d)", extra)
22212221+ }
22222222+22232223+ n := extra
22242224+22252225+ nameBuf := make([]byte, 9)
22262226+ for i := uint64(0); i < n; i++ {
22272227+ nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
22282228+ if err != nil {
22292229+ return err
22302230+ }
22312231+22322232+ if !ok {
22332233+ // Field doesn't exist on this type, so ignore it
22342234+ if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
22352235+ return err
22362236+ }
22372237+ continue
22382238+ }
22392239+22402240+ switch string(nameBuf[:nameLen]) {
22412241+ // t.LexiconTypeID (string) (string)
22422242+ case "$type":
22432243+22442244+ {
22452245+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
22462246+ if err != nil {
22472247+ return err
22482248+ }
22492249+22502250+ t.LexiconTypeID = string(sval)
22512251+ }
22522252+ // t.CreatedAt (string) (string)
22532253+ case "createdAt":
22542254+22552255+ {
22562256+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
22572257+ if err != nil {
22582258+ return err
22592259+ }
22602260+22612261+ t.CreatedAt = string(sval)
22622262+ }
22632263+22642264+ default:
22652265+ // Field doesn't exist on this type, so ignore it
22662266+ if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
22672267+ return err
22682268+ }
22692269+ }
22702270+ }
22712271+22722272+ return nil
22732273+}
21442274func (t *KnotMember) MarshalCBOR(w io.Writer) error {
21452275 if t == nil {
21462276 _, err := w.Write(cbg.CborNull)
···27162846 t.Submodules = true
27172847 default:
27182848 return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
27192719- }
27202720-27212721- default:
27222722- // Field doesn't exist on this type, so ignore it
27232723- if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
27242724- return err
27252725- }
27262726- }
27272727- }
27282728-27292729- return nil
27302730-}
27312731-func (t *Pipeline_Dependency) MarshalCBOR(w io.Writer) error {
27322732- if t == nil {
27332733- _, err := w.Write(cbg.CborNull)
27342734- return err
27352735- }
27362736-27372737- cw := cbg.NewCborWriter(w)
27382738-27392739- if _, err := cw.Write([]byte{162}); err != nil {
27402740- return err
27412741- }
27422742-27432743- // t.Packages ([]string) (slice)
27442744- if len("packages") > 1000000 {
27452745- return xerrors.Errorf("Value in field \"packages\" was too long")
27462746- }
27472747-27482748- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("packages"))); err != nil {
27492749- return err
27502750- }
27512751- if _, err := cw.WriteString(string("packages")); err != nil {
27522752- return err
27532753- }
27542754-27552755- if len(t.Packages) > 8192 {
27562756- return xerrors.Errorf("Slice value in field t.Packages was too long")
27572757- }
27582758-27592759- if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Packages))); err != nil {
27602760- return err
27612761- }
27622762- for _, v := range t.Packages {
27632763- if len(v) > 1000000 {
27642764- return xerrors.Errorf("Value in field v was too long")
27652765- }
27662766-27672767- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
27682768- return err
27692769- }
27702770- if _, err := cw.WriteString(string(v)); err != nil {
27712771- return err
27722772- }
27732773-27742774- }
27752775-27762776- // t.Registry (string) (string)
27772777- if len("registry") > 1000000 {
27782778- return xerrors.Errorf("Value in field \"registry\" was too long")
27792779- }
27802780-27812781- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("registry"))); err != nil {
27822782- return err
27832783- }
27842784- if _, err := cw.WriteString(string("registry")); err != nil {
27852785- return err
27862786- }
27872787-27882788- if len(t.Registry) > 1000000 {
27892789- return xerrors.Errorf("Value in field t.Registry was too long")
27902790- }
27912791-27922792- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Registry))); err != nil {
27932793- return err
27942794- }
27952795- if _, err := cw.WriteString(string(t.Registry)); err != nil {
27962796- return err
27972797- }
27982798- return nil
27992799-}
28002800-28012801-func (t *Pipeline_Dependency) UnmarshalCBOR(r io.Reader) (err error) {
28022802- *t = Pipeline_Dependency{}
28032803-28042804- cr := cbg.NewCborReader(r)
28052805-28062806- maj, extra, err := cr.ReadHeader()
28072807- if err != nil {
28082808- return err
28092809- }
28102810- defer func() {
28112811- if err == io.EOF {
28122812- err = io.ErrUnexpectedEOF
28132813- }
28142814- }()
28152815-28162816- if maj != cbg.MajMap {
28172817- return fmt.Errorf("cbor input should be of type map")
28182818- }
28192819-28202820- if extra > cbg.MaxLength {
28212821- return fmt.Errorf("Pipeline_Dependency: map struct too large (%d)", extra)
28222822- }
28232823-28242824- n := extra
28252825-28262826- nameBuf := make([]byte, 8)
28272827- for i := uint64(0); i < n; i++ {
28282828- nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
28292829- if err != nil {
28302830- return err
28312831- }
28322832-28332833- if !ok {
28342834- // Field doesn't exist on this type, so ignore it
28352835- if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
28362836- return err
28372837- }
28382838- continue
28392839- }
28402840-28412841- switch string(nameBuf[:nameLen]) {
28422842- // t.Packages ([]string) (slice)
28432843- case "packages":
28442844-28452845- maj, extra, err = cr.ReadHeader()
28462846- if err != nil {
28472847- return err
28482848- }
28492849-28502850- if extra > 8192 {
28512851- return fmt.Errorf("t.Packages: array too large (%d)", extra)
28522852- }
28532853-28542854- if maj != cbg.MajArray {
28552855- return fmt.Errorf("expected cbor array")
28562856- }
28572857-28582858- if extra > 0 {
28592859- t.Packages = make([]string, extra)
28602860- }
28612861-28622862- for i := 0; i < int(extra); i++ {
28632863- {
28642864- var maj byte
28652865- var extra uint64
28662866- var err error
28672867- _ = maj
28682868- _ = extra
28692869- _ = err
28702870-28712871- {
28722872- sval, err := cbg.ReadStringWithMax(cr, 1000000)
28732873- if err != nil {
28742874- return err
28752875- }
28762876-28772877- t.Packages[i] = string(sval)
28782878- }
28792879-28802880- }
28812881- }
28822882- // t.Registry (string) (string)
28832883- case "registry":
28842884-28852885- {
28862886- sval, err := cbg.ReadStringWithMax(cr, 1000000)
28872887- if err != nil {
28882888- return err
28892889- }
28902890-28912891- t.Registry = string(sval)
28922849 }
2893285028942851 default:
···3916387339173874 return nil
39183875}
39193919-func (t *Pipeline_Step) MarshalCBOR(w io.Writer) error {
39203920- if t == nil {
39213921- _, err := w.Write(cbg.CborNull)
39223922- return err
39233923- }
39243924-39253925- cw := cbg.NewCborWriter(w)
39263926- fieldCount := 3
39273927-39283928- if t.Environment == nil {
39293929- fieldCount--
39303930- }
39313931-39323932- if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
39333933- return err
39343934- }
39353935-39363936- // t.Name (string) (string)
39373937- if len("name") > 1000000 {
39383938- return xerrors.Errorf("Value in field \"name\" was too long")
39393939- }
39403940-39413941- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("name"))); err != nil {
39423942- return err
39433943- }
39443944- if _, err := cw.WriteString(string("name")); err != nil {
39453945- return err
39463946- }
39473947-39483948- if len(t.Name) > 1000000 {
39493949- return xerrors.Errorf("Value in field t.Name was too long")
39503950- }
39513951-39523952- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil {
39533953- return err
39543954- }
39553955- if _, err := cw.WriteString(string(t.Name)); err != nil {
39563956- return err
39573957- }
39583958-39593959- // t.Command (string) (string)
39603960- if len("command") > 1000000 {
39613961- return xerrors.Errorf("Value in field \"command\" was too long")
39623962- }
39633963-39643964- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("command"))); err != nil {
39653965- return err
39663966- }
39673967- if _, err := cw.WriteString(string("command")); err != nil {
39683968- return err
39693969- }
39703970-39713971- if len(t.Command) > 1000000 {
39723972- return xerrors.Errorf("Value in field t.Command was too long")
39733973- }
39743974-39753975- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Command))); err != nil {
39763976- return err
39773977- }
39783978- if _, err := cw.WriteString(string(t.Command)); err != nil {
39793979- return err
39803980- }
39813981-39823982- // t.Environment ([]*tangled.Pipeline_Pair) (slice)
39833983- if t.Environment != nil {
39843984-39853985- if len("environment") > 1000000 {
39863986- return xerrors.Errorf("Value in field \"environment\" was too long")
39873987- }
39883988-39893989- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("environment"))); err != nil {
39903990- return err
39913991- }
39923992- if _, err := cw.WriteString(string("environment")); err != nil {
39933993- return err
39943994- }
39953995-39963996- if len(t.Environment) > 8192 {
39973997- return xerrors.Errorf("Slice value in field t.Environment was too long")
39983998- }
39993999-40004000- if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Environment))); err != nil {
40014001- return err
40024002- }
40034003- for _, v := range t.Environment {
40044004- if err := v.MarshalCBOR(cw); err != nil {
40054005- return err
40064006- }
40074007-40084008- }
40094009- }
40104010- return nil
40114011-}
40124012-40134013-func (t *Pipeline_Step) UnmarshalCBOR(r io.Reader) (err error) {
40144014- *t = Pipeline_Step{}
40154015-40164016- cr := cbg.NewCborReader(r)
40174017-40184018- maj, extra, err := cr.ReadHeader()
40194019- if err != nil {
40204020- return err
40214021- }
40224022- defer func() {
40234023- if err == io.EOF {
40244024- err = io.ErrUnexpectedEOF
40254025- }
40264026- }()
40274027-40284028- if maj != cbg.MajMap {
40294029- return fmt.Errorf("cbor input should be of type map")
40304030- }
40314031-40324032- if extra > cbg.MaxLength {
40334033- return fmt.Errorf("Pipeline_Step: map struct too large (%d)", extra)
40344034- }
40354035-40364036- n := extra
40374037-40384038- nameBuf := make([]byte, 11)
40394039- for i := uint64(0); i < n; i++ {
40404040- nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
40414041- if err != nil {
40424042- return err
40434043- }
40444044-40454045- if !ok {
40464046- // Field doesn't exist on this type, so ignore it
40474047- if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
40484048- return err
40494049- }
40504050- continue
40514051- }
40524052-40534053- switch string(nameBuf[:nameLen]) {
40544054- // t.Name (string) (string)
40554055- case "name":
40564056-40574057- {
40584058- sval, err := cbg.ReadStringWithMax(cr, 1000000)
40594059- if err != nil {
40604060- return err
40614061- }
40624062-40634063- t.Name = string(sval)
40644064- }
40654065- // t.Command (string) (string)
40664066- case "command":
40674067-40684068- {
40694069- sval, err := cbg.ReadStringWithMax(cr, 1000000)
40704070- if err != nil {
40714071- return err
40724072- }
40734073-40744074- t.Command = string(sval)
40754075- }
40764076- // t.Environment ([]*tangled.Pipeline_Pair) (slice)
40774077- case "environment":
40784078-40794079- maj, extra, err = cr.ReadHeader()
40804080- if err != nil {
40814081- return err
40824082- }
40834083-40844084- if extra > 8192 {
40854085- return fmt.Errorf("t.Environment: array too large (%d)", extra)
40864086- }
40874087-40884088- if maj != cbg.MajArray {
40894089- return fmt.Errorf("expected cbor array")
40904090- }
40914091-40924092- if extra > 0 {
40934093- t.Environment = make([]*Pipeline_Pair, extra)
40944094- }
40954095-40964096- for i := 0; i < int(extra); i++ {
40974097- {
40984098- var maj byte
40994099- var extra uint64
41004100- var err error
41014101- _ = maj
41024102- _ = extra
41034103- _ = err
41044104-41054105- {
41064106-41074107- b, err := cr.ReadByte()
41084108- if err != nil {
41094109- return err
41104110- }
41114111- if b != cbg.CborNull[0] {
41124112- if err := cr.UnreadByte(); err != nil {
41134113- return err
41144114- }
41154115- t.Environment[i] = new(Pipeline_Pair)
41164116- if err := t.Environment[i].UnmarshalCBOR(cr); err != nil {
41174117- return xerrors.Errorf("unmarshaling t.Environment[i] pointer: %w", err)
41184118- }
41194119- }
41204120-41214121- }
41224122-41234123- }
41244124- }
41254125-41264126- default:
41274127- // Field doesn't exist on this type, so ignore it
41284128- if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
41294129- return err
41304130- }
41314131- }
41324132- }
41334133-41344134- return nil
41354135-}
41363876func (t *Pipeline_TriggerMetadata) MarshalCBOR(w io.Writer) error {
41373877 if t == nil {
41383878 _, err := w.Write(cbg.CborNull)
···4609434946104350 cw := cbg.NewCborWriter(w)
4611435146124612- if _, err := cw.Write([]byte{165}); err != nil {
43524352+ if _, err := cw.Write([]byte{164}); err != nil {
43534353+ return err
43544354+ }
43554355+43564356+ // t.Raw (string) (string)
43574357+ if len("raw") > 1000000 {
43584358+ return xerrors.Errorf("Value in field \"raw\" was too long")
43594359+ }
43604360+43614361+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("raw"))); err != nil {
43624362+ return err
43634363+ }
43644364+ if _, err := cw.WriteString(string("raw")); err != nil {
43654365+ return err
43664366+ }
43674367+43684368+ if len(t.Raw) > 1000000 {
43694369+ return xerrors.Errorf("Value in field t.Raw was too long")
43704370+ }
43714371+43724372+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Raw))); err != nil {
43734373+ return err
43744374+ }
43754375+ if _, err := cw.WriteString(string(t.Raw)); err != nil {
46134376 return err
46144377 }
46154378···46524415 return err
46534416 }
4654441746554655- // t.Steps ([]*tangled.Pipeline_Step) (slice)
46564656- if len("steps") > 1000000 {
46574657- return xerrors.Errorf("Value in field \"steps\" was too long")
44184418+ // t.Engine (string) (string)
44194419+ if len("engine") > 1000000 {
44204420+ return xerrors.Errorf("Value in field \"engine\" was too long")
46584421 }
4659442246604660- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("steps"))); err != nil {
46614661- return err
46624662- }
46634663- if _, err := cw.WriteString(string("steps")); err != nil {
44234423+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("engine"))); err != nil {
46644424 return err
46654425 }
46664666-46674667- if len(t.Steps) > 8192 {
46684668- return xerrors.Errorf("Slice value in field t.Steps was too long")
46694669- }
46704670-46714671- if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Steps))); err != nil {
46724672- return err
46734673- }
46744674- for _, v := range t.Steps {
46754675- if err := v.MarshalCBOR(cw); err != nil {
46764676- return err
46774677- }
46784678-46794679- }
46804680-46814681- // t.Environment ([]*tangled.Pipeline_Pair) (slice)
46824682- if len("environment") > 1000000 {
46834683- return xerrors.Errorf("Value in field \"environment\" was too long")
46844684- }
46854685-46864686- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("environment"))); err != nil {
46874687- return err
46884688- }
46894689- if _, err := cw.WriteString(string("environment")); err != nil {
46904690- return err
46914691- }
46924692-46934693- if len(t.Environment) > 8192 {
46944694- return xerrors.Errorf("Slice value in field t.Environment was too long")
46954695- }
46964696-46974697- if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Environment))); err != nil {
44264426+ if _, err := cw.WriteString(string("engine")); err != nil {
46984427 return err
46994428 }
47004700- for _, v := range t.Environment {
47014701- if err := v.MarshalCBOR(cw); err != nil {
47024702- return err
47034703- }
4704442944304430+ if len(t.Engine) > 1000000 {
44314431+ return xerrors.Errorf("Value in field t.Engine was too long")
47054432 }
4706443347074707- // t.Dependencies ([]*tangled.Pipeline_Dependency) (slice)
47084708- if len("dependencies") > 1000000 {
47094709- return xerrors.Errorf("Value in field \"dependencies\" was too long")
47104710- }
47114711-47124712- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("dependencies"))); err != nil {
44344434+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Engine))); err != nil {
47134435 return err
47144436 }
47154715- if _, err := cw.WriteString(string("dependencies")); err != nil {
44374437+ if _, err := cw.WriteString(string(t.Engine)); err != nil {
47164438 return err
47174717- }
47184718-47194719- if len(t.Dependencies) > 8192 {
47204720- return xerrors.Errorf("Slice value in field t.Dependencies was too long")
47214721- }
47224722-47234723- if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Dependencies))); err != nil {
47244724- return err
47254725- }
47264726- for _, v := range t.Dependencies {
47274727- if err := v.MarshalCBOR(cw); err != nil {
47284728- return err
47294729- }
47304730-47314439 }
47324440 return nil
47334441}
···4757446547584466 n := extra
4759446747604760- nameBuf := make([]byte, 12)
44684468+ nameBuf := make([]byte, 6)
47614469 for i := uint64(0); i < n; i++ {
47624470 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
47634471 if err != nil {
···47734481 }
4774448247754483 switch string(nameBuf[:nameLen]) {
47764776- // t.Name (string) (string)
44844484+ // t.Raw (string) (string)
44854485+ case "raw":
44864486+44874487+ {
44884488+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
44894489+ if err != nil {
44904490+ return err
44914491+ }
44924492+44934493+ t.Raw = string(sval)
44944494+ }
44954495+ // t.Name (string) (string)
47774496 case "name":
4778449747794498 {
···48044523 }
4805452448064525 }
48074807- // t.Steps ([]*tangled.Pipeline_Step) (slice)
48084808- case "steps":
45264526+ // t.Engine (string) (string)
45274527+ case "engine":
4809452848104810- maj, extra, err = cr.ReadHeader()
48114811- if err != nil {
48124812- return err
48134813- }
48144814-48154815- if extra > 8192 {
48164816- return fmt.Errorf("t.Steps: array too large (%d)", extra)
48174817- }
48184818-48194819- if maj != cbg.MajArray {
48204820- return fmt.Errorf("expected cbor array")
48214821- }
48224822-48234823- if extra > 0 {
48244824- t.Steps = make([]*Pipeline_Step, extra)
48254825- }
48264826-48274827- for i := 0; i < int(extra); i++ {
48284828- {
48294829- var maj byte
48304830- var extra uint64
48314831- var err error
48324832- _ = maj
48334833- _ = extra
48344834- _ = err
48354835-48364836- {
48374837-48384838- b, err := cr.ReadByte()
48394839- if err != nil {
48404840- return err
48414841- }
48424842- if b != cbg.CborNull[0] {
48434843- if err := cr.UnreadByte(); err != nil {
48444844- return err
48454845- }
48464846- t.Steps[i] = new(Pipeline_Step)
48474847- if err := t.Steps[i].UnmarshalCBOR(cr); err != nil {
48484848- return xerrors.Errorf("unmarshaling t.Steps[i] pointer: %w", err)
48494849- }
48504850- }
48514851-48524852- }
48534853-45294529+ {
45304530+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
45314531+ if err != nil {
45324532+ return err
48544533 }
48554855- }
48564856- // t.Environment ([]*tangled.Pipeline_Pair) (slice)
48574857- case "environment":
4858453448594859- maj, extra, err = cr.ReadHeader()
48604860- if err != nil {
48614861- return err
48624862- }
48634863-48644864- if extra > 8192 {
48654865- return fmt.Errorf("t.Environment: array too large (%d)", extra)
48664866- }
48674867-48684868- if maj != cbg.MajArray {
48694869- return fmt.Errorf("expected cbor array")
48704870- }
48714871-48724872- if extra > 0 {
48734873- t.Environment = make([]*Pipeline_Pair, extra)
48744874- }
48754875-48764876- for i := 0; i < int(extra); i++ {
48774877- {
48784878- var maj byte
48794879- var extra uint64
48804880- var err error
48814881- _ = maj
48824882- _ = extra
48834883- _ = err
48844884-48854885- {
48864886-48874887- b, err := cr.ReadByte()
48884888- if err != nil {
48894889- return err
48904890- }
48914891- if b != cbg.CborNull[0] {
48924892- if err := cr.UnreadByte(); err != nil {
48934893- return err
48944894- }
48954895- t.Environment[i] = new(Pipeline_Pair)
48964896- if err := t.Environment[i].UnmarshalCBOR(cr); err != nil {
48974897- return xerrors.Errorf("unmarshaling t.Environment[i] pointer: %w", err)
48984898- }
48994899- }
49004900-49014901- }
49024902-49034903- }
49044904- }
49054905- // t.Dependencies ([]*tangled.Pipeline_Dependency) (slice)
49064906- case "dependencies":
49074907-49084908- maj, extra, err = cr.ReadHeader()
49094909- if err != nil {
49104910- return err
49114911- }
49124912-49134913- if extra > 8192 {
49144914- return fmt.Errorf("t.Dependencies: array too large (%d)", extra)
49154915- }
49164916-49174917- if maj != cbg.MajArray {
49184918- return fmt.Errorf("expected cbor array")
49194919- }
49204920-49214921- if extra > 0 {
49224922- t.Dependencies = make([]*Pipeline_Dependency, extra)
49234923- }
49244924-49254925- for i := 0; i < int(extra); i++ {
49264926- {
49274927- var maj byte
49284928- var extra uint64
49294929- var err error
49304930- _ = maj
49314931- _ = extra
49324932- _ = err
49334933-49344934- {
49354935-49364936- b, err := cr.ReadByte()
49374937- if err != nil {
49384938- return err
49394939- }
49404940- if b != cbg.CborNull[0] {
49414941- if err := cr.UnreadByte(); err != nil {
49424942- return err
49434943- }
49444944- t.Dependencies[i] = new(Pipeline_Dependency)
49454945- if err := t.Dependencies[i].UnmarshalCBOR(cr); err != nil {
49464946- return xerrors.Errorf("unmarshaling t.Dependencies[i] pointer: %w", err)
49474947- }
49484948- }
49494949-49504950- }
49514951-49524952- }
45354535+ t.Engine = string(sval)
49534536 }
4954453749554538 default:
+34
api/tangled/repocreate.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package tangled
44+55+// schema: sh.tangled.repo.create
66+77+import (
88+ "context"
99+1010+ "github.com/bluesky-social/indigo/lex/util"
1111+)
1212+1313+const (
1414+ RepoCreateNSID = "sh.tangled.repo.create"
1515+)
1616+1717+// RepoCreate_Input is the input argument to a sh.tangled.repo.create call.
1818+type RepoCreate_Input struct {
1919+ // defaultBranch: Default branch to push to
2020+ DefaultBranch *string `json:"defaultBranch,omitempty" cborgen:"defaultBranch,omitempty"`
2121+ // rkey: Rkey of the repository record
2222+ Rkey string `json:"rkey" cborgen:"rkey"`
2323+ // source: A source URL to clone from, populate this when forking or importing a repository.
2424+ Source *string `json:"source,omitempty" cborgen:"source,omitempty"`
2525+}
2626+2727+// RepoCreate calls the XRPC method "sh.tangled.repo.create".
2828+func RepoCreate(ctx context.Context, c util.LexClient, input *RepoCreate_Input) error {
2929+ if err := c.LexDo(ctx, util.Procedure, "application/json", "sh.tangled.repo.create", nil, input, nil); err != nil {
3030+ return err
3131+ }
3232+3333+ return nil
3434+}
+34
api/tangled/repodelete.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package tangled
44+55+// schema: sh.tangled.repo.delete
66+77+import (
88+ "context"
99+1010+ "github.com/bluesky-social/indigo/lex/util"
1111+)
1212+1313+const (
1414+ RepoDeleteNSID = "sh.tangled.repo.delete"
1515+)
1616+1717+// RepoDelete_Input is the input argument to a sh.tangled.repo.delete call.
1818+type RepoDelete_Input struct {
1919+ // did: DID of the repository owner
2020+ Did string `json:"did" cborgen:"did"`
2121+ // name: Name of the repository to delete
2222+ Name string `json:"name" cborgen:"name"`
2323+ // rkey: Rkey of the repository record
2424+ Rkey string `json:"rkey" cborgen:"rkey"`
2525+}
2626+2727+// RepoDelete calls the XRPC method "sh.tangled.repo.delete".
2828+func RepoDelete(ctx context.Context, c util.LexClient, input *RepoDelete_Input) error {
2929+ if err := c.LexDo(ctx, util.Procedure, "application/json", "sh.tangled.repo.delete", nil, input, nil); err != nil {
3030+ return err
3131+ }
3232+3333+ return nil
3434+}
+45
api/tangled/repoforkStatus.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package tangled
44+55+// schema: sh.tangled.repo.forkStatus
66+77+import (
88+ "context"
99+1010+ "github.com/bluesky-social/indigo/lex/util"
1111+)
1212+1313+const (
1414+ RepoForkStatusNSID = "sh.tangled.repo.forkStatus"
1515+)
1616+1717+// RepoForkStatus_Input is the input argument to a sh.tangled.repo.forkStatus call.
1818+type RepoForkStatus_Input struct {
1919+ // branch: Branch to check status for
2020+ Branch string `json:"branch" cborgen:"branch"`
2121+ // did: DID of the fork owner
2222+ Did string `json:"did" cborgen:"did"`
2323+ // hiddenRef: Hidden ref to use for comparison
2424+ HiddenRef string `json:"hiddenRef" cborgen:"hiddenRef"`
2525+ // name: Name of the forked repository
2626+ Name string `json:"name" cborgen:"name"`
2727+ // source: Source repository URL
2828+ Source string `json:"source" cborgen:"source"`
2929+}
3030+3131+// RepoForkStatus_Output is the output of a sh.tangled.repo.forkStatus call.
3232+type RepoForkStatus_Output struct {
3333+ // status: Fork status: 0=UpToDate, 1=FastForwardable, 2=Conflict, 3=MissingBranch
3434+ Status int64 `json:"status" cborgen:"status"`
3535+}
3636+3737+// RepoForkStatus calls the XRPC method "sh.tangled.repo.forkStatus".
3838+func RepoForkStatus(ctx context.Context, c util.LexClient, input *RepoForkStatus_Input) (*RepoForkStatus_Output, error) {
3939+ var out RepoForkStatus_Output
4040+ if err := c.LexDo(ctx, util.Procedure, "application/json", "sh.tangled.repo.forkStatus", nil, input, &out); err != nil {
4141+ return nil, err
4242+ }
4343+4444+ return &out, nil
4545+}
+36
api/tangled/repoforkSync.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package tangled
44+55+// schema: sh.tangled.repo.forkSync
66+77+import (
88+ "context"
99+1010+ "github.com/bluesky-social/indigo/lex/util"
1111+)
1212+1313+const (
1414+ RepoForkSyncNSID = "sh.tangled.repo.forkSync"
1515+)
1616+1717+// RepoForkSync_Input is the input argument to a sh.tangled.repo.forkSync call.
1818+type RepoForkSync_Input struct {
1919+ // branch: Branch to sync
2020+ Branch string `json:"branch" cborgen:"branch"`
2121+ // did: DID of the fork owner
2222+ Did string `json:"did" cborgen:"did"`
2323+ // name: Name of the forked repository
2424+ Name string `json:"name" cborgen:"name"`
2525+ // source: AT-URI of the source repository
2626+ Source string `json:"source" cborgen:"source"`
2727+}
2828+2929+// RepoForkSync calls the XRPC method "sh.tangled.repo.forkSync".
3030+func RepoForkSync(ctx context.Context, c util.LexClient, input *RepoForkSync_Input) error {
3131+ if err := c.LexDo(ctx, util.Procedure, "application/json", "sh.tangled.repo.forkSync", nil, input, nil); err != nil {
3232+ return err
3333+ }
3434+3535+ return nil
3636+}
+45
api/tangled/repohiddenRef.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package tangled
44+55+// schema: sh.tangled.repo.hiddenRef
66+77+import (
88+ "context"
99+1010+ "github.com/bluesky-social/indigo/lex/util"
1111+)
1212+1313+const (
1414+ RepoHiddenRefNSID = "sh.tangled.repo.hiddenRef"
1515+)
1616+1717+// RepoHiddenRef_Input is the input argument to a sh.tangled.repo.hiddenRef call.
1818+type RepoHiddenRef_Input struct {
1919+ // forkRef: Fork reference name
2020+ ForkRef string `json:"forkRef" cborgen:"forkRef"`
2121+ // remoteRef: Remote reference name
2222+ RemoteRef string `json:"remoteRef" cborgen:"remoteRef"`
2323+ // repo: AT-URI of the repository
2424+ Repo string `json:"repo" cborgen:"repo"`
2525+}
2626+2727+// RepoHiddenRef_Output is the output of a sh.tangled.repo.hiddenRef call.
2828+type RepoHiddenRef_Output struct {
2929+ // error: Error message if creation failed
3030+ Error *string `json:"error,omitempty" cborgen:"error,omitempty"`
3131+ // ref: The created hidden ref name
3232+ Ref *string `json:"ref,omitempty" cborgen:"ref,omitempty"`
3333+ // success: Whether the hidden ref was created successfully
3434+ Success bool `json:"success" cborgen:"success"`
3535+}
3636+3737+// RepoHiddenRef calls the XRPC method "sh.tangled.repo.hiddenRef".
3838+func RepoHiddenRef(ctx context.Context, c util.LexClient, input *RepoHiddenRef_Input) (*RepoHiddenRef_Output, error) {
3939+ var out RepoHiddenRef_Output
4040+ if err := c.LexDo(ctx, util.Procedure, "application/json", "sh.tangled.repo.hiddenRef", nil, input, &out); err != nil {
4141+ return nil, err
4242+ }
4343+4444+ return &out, nil
4545+}
+44
api/tangled/repomerge.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package tangled
44+55+// schema: sh.tangled.repo.merge
66+77+import (
88+ "context"
99+1010+ "github.com/bluesky-social/indigo/lex/util"
1111+)
1212+1313+const (
1414+ RepoMergeNSID = "sh.tangled.repo.merge"
1515+)
1616+1717+// RepoMerge_Input is the input argument to a sh.tangled.repo.merge call.
1818+type RepoMerge_Input struct {
1919+ // authorEmail: Author email for the merge commit
2020+ AuthorEmail *string `json:"authorEmail,omitempty" cborgen:"authorEmail,omitempty"`
2121+ // authorName: Author name for the merge commit
2222+ AuthorName *string `json:"authorName,omitempty" cborgen:"authorName,omitempty"`
2323+ // branch: Target branch to merge into
2424+ Branch string `json:"branch" cborgen:"branch"`
2525+ // commitBody: Additional commit message body
2626+ CommitBody *string `json:"commitBody,omitempty" cborgen:"commitBody,omitempty"`
2727+ // commitMessage: Merge commit message
2828+ CommitMessage *string `json:"commitMessage,omitempty" cborgen:"commitMessage,omitempty"`
2929+ // did: DID of the repository owner
3030+ Did string `json:"did" cborgen:"did"`
3131+ // name: Name of the repository
3232+ Name string `json:"name" cborgen:"name"`
3333+ // patch: Patch content to merge
3434+ Patch string `json:"patch" cborgen:"patch"`
3535+}
3636+3737+// RepoMerge calls the XRPC method "sh.tangled.repo.merge".
3838+func RepoMerge(ctx context.Context, c util.LexClient, input *RepoMerge_Input) error {
3939+ if err := c.LexDo(ctx, util.Procedure, "application/json", "sh.tangled.repo.merge", nil, input, nil); err != nil {
4040+ return err
4141+ }
4242+4343+ return nil
4444+}
+57
api/tangled/repomergeCheck.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package tangled
44+55+// schema: sh.tangled.repo.mergeCheck
66+77+import (
88+ "context"
99+1010+ "github.com/bluesky-social/indigo/lex/util"
1111+)
1212+1313+const (
1414+ RepoMergeCheckNSID = "sh.tangled.repo.mergeCheck"
1515+)
1616+1717+// RepoMergeCheck_ConflictInfo is a "conflictInfo" in the sh.tangled.repo.mergeCheck schema.
1818+type RepoMergeCheck_ConflictInfo struct {
1919+ // filename: Name of the conflicted file
2020+ Filename string `json:"filename" cborgen:"filename"`
2121+ // reason: Reason for the conflict
2222+ Reason string `json:"reason" cborgen:"reason"`
2323+}
2424+2525+// RepoMergeCheck_Input is the input argument to a sh.tangled.repo.mergeCheck call.
2626+type RepoMergeCheck_Input struct {
2727+ // branch: Target branch to merge into
2828+ Branch string `json:"branch" cborgen:"branch"`
2929+ // did: DID of the repository owner
3030+ Did string `json:"did" cborgen:"did"`
3131+ // name: Name of the repository
3232+ Name string `json:"name" cborgen:"name"`
3333+ // patch: Patch or pull request to check for merge conflicts
3434+ Patch string `json:"patch" cborgen:"patch"`
3535+}
3636+3737+// RepoMergeCheck_Output is the output of a sh.tangled.repo.mergeCheck call.
3838+type RepoMergeCheck_Output struct {
3939+ // conflicts: List of files with merge conflicts
4040+ Conflicts []*RepoMergeCheck_ConflictInfo `json:"conflicts,omitempty" cborgen:"conflicts,omitempty"`
4141+ // error: Error message if check failed
4242+ Error *string `json:"error,omitempty" cborgen:"error,omitempty"`
4343+ // is_conflicted: Whether the merge has conflicts
4444+ Is_conflicted bool `json:"is_conflicted" cborgen:"is_conflicted"`
4545+ // message: Additional message about the merge check
4646+ Message *string `json:"message,omitempty" cborgen:"message,omitempty"`
4747+}
4848+4949+// RepoMergeCheck calls the XRPC method "sh.tangled.repo.mergeCheck".
5050+func RepoMergeCheck(ctx context.Context, c util.LexClient, input *RepoMergeCheck_Input) (*RepoMergeCheck_Output, error) {
5151+ var out RepoMergeCheck_Output
5252+ if err := c.LexDo(ctx, util.Procedure, "application/json", "sh.tangled.repo.mergeCheck", nil, input, &out); err != nil {
5353+ return nil, err
5454+ }
5555+5656+ return &out, nil
5757+}
···11+{{ define "knots/fragments/banner" }}
22+<div class="w-full px-6 py-2 -z-15 bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200 border border-yellow-200 dark:border-yellow-800 rounded-b drop-shadow-sm">
33+ A knot ({{range $i, $r := .Registrations}}{{if ne $i 0}}, {{end}}{{ $r.Domain }}{{ end }})
44+ that you administer is presently read-only. Consider upgrading this knot to
55+ continue creating repositories on it.
66+ <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/migrations/knot-1.7.0.md">Click to read the upgrade guide</a>.
77+</div>
88+{{ end }}
99+
···1111)
12121313func main() {
1414- db, err := sql.Open("sqlite3", "./appview.db")
1414+ db, err := sql.Open("sqlite3", "./appview.db?_foreign_keys=1")
1515 if err != nil {
1616 log.Fatal("Failed to open database:", err)
1717 }
+6
docs/contributing.md
···5555- Avoid noisy commit messages like "wip" or "final fix"โrewrite history
5656before submitting if necessary.
57575858+## code formatting
5959+6060+We use a variety of tools to format our code, and multiplex them with
6161+[`treefmt`](https://treefmt.com): all you need to do to format your changes
6262+is run `nix run .#fmt` (or just `treefmt` if you're in the devshell).
6363+5864## proposals for bigger changes
59656066Small fixes like typos, minor bugs, or trivial refactors can be
+19-19
docs/hacking.md
···5555quite cumbersome. So the nix flake provides a
5656`nixosConfiguration` to do so.
57575858-To begin, head to `http://localhost:3000/knots` in the browser
5959-and create a knot with hostname `localhost:6000`. This will
6060-generate a knot secret. Set `$TANGLED_VM_KNOT_SECRET` to it,
6161-ideally in a `.envrc` with [direnv](https://direnv.net) so you
6262-don't lose it.
5858+To begin, grab your DID from http://localhost:3000/settings.
5959+Then, set `TANGLED_VM_KNOT_OWNER` and
6060+`TANGLED_VM_SPINDLE_OWNER` to your DID.
63616464-You will also need to set the `$TANGLED_VM_SPINDLE_OWNER`
6565-variable to some value. If you don't want to [set up a
6666-spindle](#running-a-spindle), you can use any placeholder
6767-value.
6262+If you don't want to [set up a spindle](#running-a-spindle),
6363+you can use any placeholder value.
68646965You can now start a lightweight NixOS VM like so:
7066···7571```
76727773This starts a knot on port 6000, a spindle on port 6555
7878-with `ssh` exposed on port 2222. You can push repositories
7979-to this VM with this ssh config block on your main machine:
7474+with `ssh` exposed on port 2222.
7575+7676+Once the services are running, head to
7777+http://localhost:3000/knots and hit verify (and similarly,
7878+http://localhost:3000/spindles to verify your spindle). It
7979+should verify the ownership of the services instantly if
8080+everything went smoothly.
8181+8282+You can push repositories to this VM with this ssh config
8383+block on your main machine:
80848185```bash
8286Host nixos-shell
···959996100## running a spindle
971019898-You will need to find out your DID by entering your login handle into
9999-<https://pdsls.dev/>. Set `$TANGLED_VM_SPINDLE_OWNER` to your DID.
100100-101101-The above VM should already be running a spindle on `localhost:6555`.
102102-You can head to the spindle dashboard on `http://localhost:3000/spindles`,
103103-and register a spindle with hostname `localhost:6555`. It should instantly
104104-be verified. You can then configure each repository to use this spindle
105105-and run CI jobs.
102102+The above VM should already be running a spindle on
103103+`localhost:6555`. Head to http://localhost:3000/spindles and
104104+hit verify. You can then configure each repository to use
105105+this spindle and run CI jobs.
106106107107Of interest when debugging spindles:
108108
+7-5
docs/knot-hosting.md
···7373```
74747575Create `/home/git/.knot.env` with the following, updating the values as
7676-necessary. The `KNOT_SERVER_SECRET` can be obtained from the
7777-[/knots](https://tangled.sh/knots) page on Tangled.
7676+necessary. The `KNOT_SERVER_OWNER` should be set to your
7777+DID, you can find your DID in the [Settings](https://tangled.sh/settings) page.
78787979```
8080KNOT_REPO_SCAN_PATH=/home/git
8181KNOT_SERVER_HOSTNAME=knot.example.com
8282APPVIEW_ENDPOINT=https://tangled.sh
8383-KNOT_SERVER_SECRET=secret
8383+KNOT_SERVER_OWNER=did:plc:foobar
8484KNOT_SERVER_INTERNAL_LISTEN_ADDR=127.0.0.1:5444
8585KNOT_SERVER_LISTEN_ADDR=127.0.0.1:5555
8686```
···128128Remember to use Let's Encrypt or similar to procure a certificate for your
129129knot domain.
130130131131-You should now have a running knot server! You can finalize your registration by hitting the
132132-`initialize` button on the [/knots](https://tangled.sh/knots) page.
131131+You should now have a running knot server! You can finalize
132132+your registration by hitting the `verify` button on the
133133+[/knots](https://tangled.sh/knots) page. This simply creates
134134+a record on your PDS to announce the existence of the knot.
133135134136### custom paths
135137
+35
docs/migrations/knot-1.7.0.md
···11+# Upgrading from v1.7.0
22+33+After v1.7.0, knot secrets have been deprecated. You no
44+longer need a secret from the appview to run a knot. All
55+authorized commands to knots are managed via [Inter-Service
66+Authentication](https://atproto.com/specs/xrpc#inter-service-authentication-jwt).
77+Knots will be read-only until upgraded.
88+99+Upgrading is quite easy, in essence:
1010+1111+- `KNOT_SERVER_SECRET` is no more, you can remove this
1212+ environment variable entirely
1313+- `KNOT_SERVER_OWNER` is now required on boot, set this to
1414+ your DID. You can find your DID in the
1515+ [settings](https://tangled.sh/settings) page.
1616+- Restart your knot once you have replaced the environment
1717+ variable
1818+- Head to the [knot dashboard](https://tangled.sh/knots) and
1919+ hit the "retry" button to verify your knot. This simply
2020+ writes a `sh.tangled.knot` record to your PDS.
2121+2222+## Nix
2323+2424+If you use the nix module, simply bump the flake to the
2525+latest revision, and change your config block like so:
2626+2727+```diff
2828+ services.tangled-knot = {
2929+ enable = true;
3030+ server = {
3131+- secretFile = /path/to/secret;
3232++ owner = "did:plc:foo";
3333+ };
3434+ };
3535+```
+26-3
docs/spindle/pipeline.md
···44repo. Generally:
5566* Pipelines are defined in YAML.
77-* Dependencies can be specified from
88-[Nixpkgs](https://search.nixos.org) or custom registries.
99-* Environment variables can be set globally or per-step.
77+* Workflows can run using different *engines*.
88+99+The most barebones workflow looks like this:
1010+1111+```yaml
1212+when:
1313+ - event: ["push"]
1414+ branch: ["main"]
1515+1616+engine: "nixery"
1717+1818+# optional
1919+clone:
2020+ skip: false
2121+ depth: 50
2222+ submodules: true
2323+```
2424+2525+The `when` and `engine` fields are required, while every other aspect
2626+of how the definition is parsed is up to the engine. Currently, a spindle
2727+provides at least one of these built-in engines:
2828+2929+## `nixery`
3030+3131+The Nixery engine uses an instance of [Nixery](https://nixery.dev) to run
3232+steps that use dependencies from [Nixpkgs](https://github.com/NixOS/nixpkgs).
10331134Here's an example that uses all fields:
1235
···99// NewHandler sets up a new slog.Handler with the service name
1010// as an attribute
1111func NewHandler(name string) slog.Handler {
1212- handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{})
1212+ handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
1313+ Level: slog.LevelDebug,
1414+ })
13151416 var attrs []slog.Attr
1517 attrs = append(attrs, slog.Attr{Key: "service", Value: slog.StringValue(name)})
···7070 };
7171 # This is fine because any and all ports that are forwarded to host are explicitly marked above, we don't need a separate guest firewall
7272 networking.firewall.enable = false;
7373+ time.timeZone = "Europe/London";
7374 services.getty.autologinUser = "root";
7475 environment.systemPackages = with pkgs; [curl vim git sqlite litecli];
7576 services.tangled-knot = {
7677 enable = true;
7778 motd = "Welcome to the development knot!\n";
7879 server = {
7979- secretFile = builtins.toFile "knot-secret" ("KNOT_SERVER_SECRET=" + (envVar "TANGLED_VM_KNOT_SECRET"));
8080+ owner = envVar "TANGLED_VM_KNOT_OWNER";
8081 hostname = "localhost:6000";
8182 listenAddr = "0.0.0.0:6000";
8283 };