Documentation
¶
Overview ¶
Package devops implements a read-only client for an on-prem Azure DevOps Server / TFS collection (v0.9.829).
DELIBERATELY NARROW: this is the connection layer only — settings persistence, an authenticated HTTP client, and a "does it answer?" probe. There is no repo mapping, no stack- frame → source resolution and no Copilot integration yet; those land in a later slice once the operator's repo-naming pattern is known. Nothing in Coremetry consumes this package today, so wiring it up changes no existing behaviour.
The secret contract is the tempo.Service one, verbatim: the PAT lives in Settings, never in Snapshot, never in an error string and never in an audit entry.
Index ¶
- Constants
- func BestPathForFrame(paths []string, f stackparse.Frame) string
- func BrowseURL(cfg Settings, repo, branch string) string
- func ClampCodeLookupLimit(n int) int
- func ClampCodeSearchLimit(n int) int
- func DefaultBranchOrder() []string
- func DefaultRepoPrefixes() []string
- func EnclosingSignature(lines []string, fromLine int) (string, int)
- func FileURL(cfg Settings, project, repo, branch, path string, line int) string
- func FormatCodeMissNote(class CodeOutcome, reason string) string
- func MaskCodeInPrompt(full, block, summary string) string
- func PickBranch(available []string, order []string) string
- func RecencyKey(project, repo string) string
- func SearchQueryForFrame(f stackparse.Frame) string
- func ShortBranch(ref string) string
- type CodeContext
- type CodeMissCount
- type CodeOutcome
- type CodeSearchHit
- func PickSearchHit(hits []CodeSearchHit, preferRepo string, frame stackparse.Frame, ...) (CodeSearchHit, bool)
- func PickSearchHitRecency(hits []CodeSearchHit, preferRepo string, frame stackparse.Frame, ...) (CodeSearchHit, bool)
- func SearchCode(ctx context.Context, cli *http.Client, cfg Settings, text string) ([]CodeSearchHit, error)
- type CodeStats
- type CodeWindow
- type DryRunResult
- type DryRunStep
- type FetchStats
- type PinRead
- type ProjectHint
- type RepoNameMatch
- type RepoResolution
- type ResolveConfig
- type Service
- func (s *Service) CodeObservability() CodeStats
- func (s *Service) Configure(cfg Settings)
- func (s *Service) Configured() bool
- func (s *Service) CurrentSettings() Settings
- func (s *Service) FetchCode(ctx context.Context, repo string, hint ProjectHint, frames []stackparse.Frame, ...) (out CodeContext)
- func (s *Service) LoadPersisted(ctx context.Context, store settingsStore) error
- func (s *Service) RecordCodeOutcome(class CodeOutcome, reason string)
- func (s *Service) ResolveConfig() ResolveConfig
- func (s *Service) ResolveDryRun(ctx context.Context, service string, pin PinRead) DryRunResult
- func (s *Service) SavePersisted(ctx context.Context, store settingsStore, cfg Settings) error
- func (s *Service) Snapshot() Snapshot
- func (s *Service) StartConfigRefresh(ctx context.Context, store settingsStore, interval time.Duration)
- func (s *Service) Test(ctx context.Context, cfg Settings) TestResult
- func (s *Service) TestConnection(ctx context.Context) TestResult
- type Settings
- type Snapshot
- type TestResult
Constants ¶
const ( FlavorAuto = "auto" FlavorServer = "azure-devops-server" FlavorTFS = "tfs" )
Flavor values. On-prem installs differ in which api-version they will answer: Azure DevOps Server (2019+) speaks 6.0, the older TFS line (2015-2018) tops out around 4.1 and 400s on a 6.0 request. "auto" probes rather than making the operator know which box they inherited.
const ( DefaultCodeLookupLimit = 6 MaxCodeLookupLimit = 30 // v0.10.353 — arama tavanı: eski sabit 2 idi (frame + hata-kodu ayrı ayrı); // operatörün açıklamasında 9 frame "eşleşmeyen" kalıyordu. 6 varsayılan, // 20 tavan (her arama ayrı bir DevOps çağrısı). DefaultCodeSearchLimit = 6 MaxCodeSearchLimit = 20 )
Deneme tavanı sınırları (v0.10.112). Varsayılan 6 = 3 pencere + 3 ıska payı (code.go codeLookupLimit gerekçesi); 30 = 60.000 yollu bir ağaçta bile açıklamayı dakikalara sürüklemeyecek üst sınır (codeFetchDeadline 25 sn zaten ikinci kapı).
const ( RepoRungExact = "exact" RepoRungFold = "fold" // yalnız harf yazımı farklı RepoRungLoose = "loose" // ayraçlar da soyulduktan sonra )
Eşleşme basamakları — testler ve hata mesajları bunları okur.
const ( RepoSourcePin = "pin" // service_metadata.repository RepoSourceConvention = "convention" // önek + ortam eki soyma RepoSourceNone = "" // çözülemedi )
Repo çözüm kaynakları — yanıtın altındaki kaynak satırı ve testler bunları okur.
const ( DryRunStepConnection = "connection" DryRunStepPin = "pin" DryRunStepRepo = "repo" DryRunStepProject = "project" DryRunStepBranch = chainStepBranch DryRunStepTree = chainStepTree DryRunStepSearch = "search" // v0.10.226 — yalnız bilgilendirme adımı )
Adım anahtarları — frontend rozetleri ve testler bunları okur.
const FrameMarker = frameMarker
FrameMarker — frameMarker'ın dışa açık adı (v0.10.112): prompt şablonu (copilot.CodeFrameMarker) ile tek yazım; api testi pinler.
const ProjectSourceSettings = "settings"
ProjectSourceSettings — projenin Ayarlar'daki açık alandan geldiğini söyleyen kaynak etiketi (v0.9.1242). Öbür iki değer RepoSourcePin / RepoSourceConvention; üçü birlikte "bu proje adı NEREDEN geldi" sorusunun tüm cevap kümesi.
Variables ¶
This section is empty.
Functions ¶
func BestPathForFrame ¶ added in v0.9.830
func BestPathForFrame(paths []string, f stackparse.Frame) string
BestPathForFrame — depo ağacındaki yollar arasından frame'in dosyasına en iyi eşleşen. Eşleşme yoksa "".
Kural: yol, "/" + dosya adı ile BİTMELİ (sonek eşleşmesi) — böylece CardService.java, MyCardService.java'yı yakalamaz. Birden çok aday varsa frame'in PAKET YOLUNA en çok benzeyen kazanır; eşitlikte KISA yol (üretilmiş/gölge kopyalar genelde daha derinde durur), o da eşitse alfabetik — sonuç deterministik olmak zorunda, yoksa aynı exception iki tıkta iki farklı dosya gösterir.
func ClampCodeLookupLimit ¶ added in v0.10.112
ClampCodeLookupLimit — PUT girdisi için tek yazım: 0 kalır (varsayılan demek), negatif 0'a, tavan üstü tavana. Saf; handler ve test okur.
func ClampCodeSearchLimit ¶ added in v0.10.353
ClampCodeSearchLimit — PUT girdisi: 0 kalır (varsayılan), negatif 0, tavan üstü tavan.
func DefaultBranchOrder ¶ added in v0.9.830
func DefaultBranchOrder() []string
func DefaultRepoPrefixes ¶ added in v0.9.830
func DefaultRepoPrefixes() []string
DefaultRepoPrefixes / DefaultBranchOrder — ayar boşken kullanılan varsayılanlar. Ayarın kendisi devops_connection blob'unda.
func EnclosingSignature ¶ added in v0.10.112
EnclosingSignature — lines içinde (1-tabanlı) fromLine'ın ÜSTÜNDEN yukarı doğru ilk metot/ctor bildirimini bulur. Saf; tablo-testli (code_window_signature_test.go). Bulamazsa ("", 0): dosya başı, yalnız alan/import satırları, tanınmayan dil.
Tarama tavanı 400 satır: devasa bir sınıfta imzayı bulamamak, yüzlerce satırı yanlış eşleşme riskiyle taramaktan iyidir.
func FileURL ¶ added in v0.10.353
BrowseURL — operatörün TARAYICIDA açabileceği depo linki (v0.10.60).
Operatör isteği: "Kodu incele … seçince incelerken git repo URL'ini de yazsın." Sebebi somut: kod çekimi bir depo + branş TAHMİNİNE dayanıyor (konvansiyon) ve operatörün o tahmini doğrulamasının tek yolu, linke tıklayıp gerçekten o depo mu diye bakmaktı — ama link hiçbir yerde yoktu.
Şekil `_apis` DEĞİL, `_git`: API kökü tarayıcıda JSON döker. Branş biliniyorsa `?version=GB<branş>` ekleniyor, ki açılan sayfa kodun OKUNDUĞU branş olsun; olmayan bir branşa gitmek operatörü yanlış dosyaya bakmaya iter.
Boş dönerse arayüz linki hiç çizmez: yanlış bir link, link olmamasından kötüdür. FileURL — v0.10.353 (operatör: "bulduğu satırın o dosyanın sonunda linki olsun"): DevOps web arayüzünde dosya + satır. project boşsa cfg.Project; path depo-içi tam yol (başında / olsun olmasın). line ≤ 0 → satırsız. Azure DevOps Server/TFS ve dev.azure.com aynı şekli okur:
{koleksiyon}/{proje}/_git/{depo}?path=/x/y.java&version=GB{branş}&line=N&lineEnd=N&lineStartColumn=1&lineEndColumn=1&_a=contents
func FormatCodeMissNote ¶ added in v0.9.1243
func FormatCodeMissNote(class CodeOutcome, reason string) string
FormatCodeMissNote — ıska işaretinin TEK yazımı. Saf; tablo-testli.
Sınıf varsa sınıf yazılır: taksonomi sabit bir sözlük, kayıtlar üzerinde gruplanabilir. Sınıf yoksa (çıkmaz FetchCode taksonomisinin dışında — ör. bağlam taşmasında kod bloğunun düşürülmesi) gerekçe metni tavanlanarak yazılır; ikisi de yoksa sessiz kalmak yerine "bilinmiyor" denir — işaretin YOKLUĞU "hiç istenmedi" demektir ve tam olarak bu karışıklığı kapatmaya çalışıyoruz.
func MaskCodeInPrompt ¶ added in v0.9.830
MaskCodeInPrompt — prompt'un LOG KOPYASINDA kod bloğunu özetiyle değiştirir. Saf.
Sağlayıcıya giden gerçek prompt'a DOKUNMAZ — çağıran bunu yalnız ai_calls kaydı için üretir. block prompt'un içinde bulunamazsa prompt aynen döner: maskeleme bir "en iyi çaba" değil, bir sözleşmedir; bulunamadığında sessizce yanlış bir şey yazmaktansa hiçbir şey değiştirmemek doğrudur (çağıran zaten bloğu kendi eklemiştir).
func PickBranch ¶ added in v0.9.830
PickBranch — sunucudan gelen branş adları arasından ayardaki SIRAYA göre ilk VAR OLANI seçer. Saf; tablo-testli.
available "refs/heads/master" ya da düz "master" olabilir — refs API tam ref adı döner, karşılaştırma son parça üzerinden yapılır. Hiçbiri yoksa "" döner ve çağıran deponun VARSAYILAN branşına düşer: "release yok, master yok" bir hata değil, farklı bir konvansiyondur.
v0.9.1236 — eşleşme HARF DUYARSIZ. Eskiden bayt-bayt eşleşiyordu ve "refs/heads/Release" taşıyan bir depo, ayardaki "release" ile hiç tutmuyordu: PickBranch "" dönüyor, çağıran sessizce deponun VARSAYILAN branşına (çoğunlukla Master/Develop) düşüyordu. Sonuç en kötü sınıftan bir hataydı — kod pencereleri YANLIŞ BRANŞTAN, yani yanlış satırlardan kesiliyor ve operatöre kanıt diye gösteriliyordu; hiçbir yerde bir uyarı yoktu.
Basamak sırası: aynı `want` için ÖNCE birebir, sonra harf duyarsız. Sunucunun KANONİK yazımı döner — git ref URL'i harf duyarlıdır, operatörün ayardaki yazımını geri vermek 404 üretirdi. Ayardaki SIRA semantiği korunur: dış döngü order, iç döngü basamak.
func RecencyKey ¶ added in v0.10.226
RecencyKey — (proje, depo) → harf-duyarsız anahtar (Azure DevOps adları harf-duyarsız çözülür).
func SearchQueryForFrame ¶ added in v0.10.74
func SearchQueryForFrame(f stackparse.Frame) string
SearchQueryForFrame — frame'den arama metni.
`Sınıf.metot` biçimi, operatörün elle yaptığı aramanın aynısı ve en seçici olanı: yalnız sınıf adı aramak, aynı adı taşıyan her dosyayı getirir; yalnız metot adı ise gürültü denizidir.
Sınıf adı paketten SOYULUYOR: arama motoru tam nitelikli adı gövdede nadiren görür (kod `EmailSender.getX()` yazar, `com.x.EmailSender.getX()` değil).
func ShortBranch ¶ added in v0.9.830
ShortBranch — "refs/heads/master" → "master". Zaten kısaysa aynen.
Types ¶
type CodeContext ¶ added in v0.9.830
type CodeContext struct {
Repo string `json:"repo,omitempty"`
Branch string `json:"branch,omitempty"`
Source string `json:"source,omitempty"` // pin | convention
// BrowseURL (v0.10.60, operatör isteği: "seçince incelerken git repo
// URL'ini de yazsın") — operatörün TARAYICIDA açabileceği depo linki.
//
// SUNUCU kuruyor, istemci DEĞİL: taban adres, koleksiyon ve proje
// yalnız burada biliniyor ve aynı URL mantığını ön yüzde ikinci kez
// yazmak, ikisinin sessizce ayrışmasına izin vermek olurdu (bu gece
// tekrar eden sınıf).
BrowseURL string `json:"browseUrl,omitempty"`
Windows []CodeWindow `json:"windows,omitempty"`
Reason string `json:"reason,omitempty"`
// Outcome — bu denemenin SINIFI (v0.9.1243), sayaçlarla BİREBİR
// aynı taksonomi. v0.9.1241'de sınıf yalnız sayaca gidiyordu; tek
// bir çağrının kaydına (ai_calls maskeli kopyası) hangi çıkmaza
// düşüldüğü yazılamıyordu. Sınıfı Reason METNİNDEN çıkarmak
// alternatifti ve reddedildi: metin operatöre hitap eden, serbestçe
// değişen bir cümle; sınıf bir sözleşme.
Outcome CodeOutcome `json:"outcome,omitempty"`
// Trimmed (v0.10.112) — bütçe kırpması/düşmesi OLDUYSA modele
// söylenecek tek satır. Reason'dan AYRI: Reason operatör ekranına ve
// kayda gider (depo düzeltme izi, ıska listesi, süre…); modelin
// bilmesi gereken yalnız "elindeki kod eksik". Operatör direktifi
// 2026-08-28: "kırpma yapıldıysa modele bildir".
Trimmed string `json:"trimmed,omitempty"`
// Stats (v0.10.112) — sayılar; bkz. FetchStats.
Stats FetchStats `json:"stats,omitempty"`
}
CodeContext — bir stacktrace için toplanan tüm kod bağlamı.
Windows boşsa Reason DOLU olmalı: "kod yok" cevabının yanında "neden yok" olmadan operatör entegrasyonun bozuk mu yoksa sadece eşleşme mi bulamadığını ayırt edemez.
func (CodeContext) Empty ¶ added in v0.9.830
func (c CodeContext) Empty() bool
Empty — kod bağlamı yok mu?
func (CodeContext) Halved ¶ added in v0.9.831
func (c CodeContext) Halved() CodeContext
Halved — kod bütçesini YARIYA indirir (v0.9.831).
Sağlayıcı bağlam taşması 400'ü döndüğünde çağıran BİR kez bununla yeniden dener. Kod, prompt'a en son eklenen ve tek başına en büyük parçadır; taşmada ilk küçültülecek şey odur — exception bağlamının kendisi (stack, trace, loglar) kod olmadan da cevap üretebilir, tersi doğru değil.
Yeni bir ağ isteği YOK: eldeki pencereler kırpılır. v0.9.1243 — küçültme KAYIPTIR ve kayda öyle yazılır. Öncesinde yeniden denemenin maskeli kopyası, ilk denemeninkiyle aynı dilde "kod geldi" diyordu; oysa modele giden pencereler kırpılmış ya da düşmüştü. Not BAŞA yazılıyor: gerekçe tavana çarparsa kesilecek olan eski kuyruk olsun, yeni kayıp değil.
func (CodeContext) LogMissSummary ¶ added in v0.9.1243
func (c CodeContext) LogMissSummary() string
LogMissSummary — "kod İSTENDİ ama gelmedi" işareti (v0.9.1243).
Neden var: maskeli ai_calls kopyası, kod geldiğinde `[kod: …]` özetini taşıyor; gelmediğinde HİÇBİR ŞEY taşımıyordu. Yani bir ai_calls satırına bakan operatör "kod hiç istenmedi" ile "istendi, ıskaladı" hâllerini AYIRT EDEMİYORDU — /ai analizi ve her postmortem ıska yarısını sessizce eksik sayıyordu (isabet oranı olduğundan iyi görünüyordu; v0.9.1241 sayaçlarının çözdüğü sorunun satır-düzeyi ikizi).
Dolu bağlamda "" döner: işaret yalnız ıskanın işareti.
func (CodeContext) LogSummary ¶ added in v0.9.830
func (c CodeContext) LogSummary() string
LogSummary — maskeli ai_calls kaydına giren tek satırlık özet. Kod GÖVDESİ değil, yalnız nereden geldiği: `[kod: repo/dosya:aralık · N satır]`. Operatör hangi dosyanın modele gittiğini görür, kaynak kodun kendisi telemetri deposuna yazılmaz.
func (CodeContext) MissingBlock ¶ added in v0.10.112
func (c CodeContext) MissingBlock() string
MissingBlock — KOD İSTENDİ AMA ÇÖZÜLEMEDİ (v0.10.112, operatör direktifi 2026-08-28: "alıntı yoksa model 'kaynak çözülemedi: <path>' demeli, tahmin etmemeli").
v0.9.1243'ün TERSİNE çevrilen kararı: o gün "modele 'kod alınamadı' demek olmayan kanıt hakkında konuşmaya davetiye" diye yalnız kayda yazılmıştı. Prod gözlemi tersini gösterdi: model düz prompt'la stack'teki satır numarasını okuyup "X. satırda hata var" diye ALINTISIZ iddia üretiyor. Boşluğu söylemek, uydurmaktan iyidir; blok modele ne yapmayacağını da yazıyor. Pencere varsa boş döner.
func (CodeContext) PromptBlock ¶ added in v0.9.830
func (c CodeContext) PromptBlock() string
PromptBlock — kod bağlamının prompt'a giren metni. Boş bağlam → "".
Blok bir BÜTÜN olarak taşınır: ai_calls maskeleyicisi bu metni prompt'un içinde tek parça bulup özetiyle değiştirir (emsal: clampDrawerEvidence'in LogsBlock'u aynı şekilde tek parça geçer). v0.9.1239 — pencere içi İŞARET + konum etiketi + dile göre çit. Üçü de aynı boşluğu kapatıyor: modelin pencerede NEYE bakacağı. Öncesinde her satır tıpatıp aynı ("246| kod") görünüyordu ve pencereler sırasız bir yığındı; 4B'lik bir modelden başlıktaki ":246" ile satır önekini kendi eşleştirmesi ve pencere sırasının kök-nedene göre kurulduğunu tahmin etmesi bekleniyordu.
type CodeMissCount ¶ added in v0.9.1241
CodeMissCount — bir çıkmaz kovası. Slice olarak dönüyor (map değil): ekrandaki sıra deterministik olmalı, JSON map'i değil.
type CodeOutcome ¶ added in v0.9.1241
type CodeOutcome string
CodeOutcome — bir kod-çekme denemesinin sonucu.
İki başarı hâli + on bir çıkmaz. Sınıflar FetchCode'un (ve ondan önceki buildCodeContext adımlarının) gerçek çıkışlarıyla BİREBİR; her birinin operatör için farklı bir eylemi vardır — karıştırmak "kod gelmiyor" cevabını tek bir çaresiz kutuya indirirdi.
const ( // CodeOK — en az bir pencere geldi ve HİÇBİR kayıp yok. CodeOK CodeOutcome = "ok" // CodePartial — pencere geldi ama eksik: bütçe kesti, bir frame // ağaçta bulunamadı, süre/deneme tavanı doldu. Başarıyla aynı // kovaya koymak isabet oranını olduğundan iyi gösterirdi. CodePartial CodeOutcome = "partial" // CodeUnconfigured — DevOps bağlantısı yok/ayarlanmamış. // Eylem: Ayarlar → Kod entegrasyonu. CodeUnconfigured CodeOutcome = "unconfigured" // CodeRepoUnresolved — servis için depo ADI çözülemedi (katalogda // pin yok, konvansiyon tutmadı). Eylem: servis kataloğuna Repository. CodeRepoUnresolved CodeOutcome = "repo-unresolved" // CodeProjectDeadEnd — proje adı ne ayarda ne pinde ne de servis // önekinden türetilebiliyor (v0.9.1240 çıkmazı). CodeProjectDeadEnd CodeOutcome = "project-dead-end" // CodeNoStack — kayıtta stacktrace yok ya da dosya+satır taşıyan // uygulama frame'i yok. Eylem YOK: bu, entegrasyonun değil verinin // hâli. Ayrı kova olmasının tek sebebi bu — arıza sanılmasın. CodeNoStack CodeOutcome = "no-stack" // CodeCatalogError — servis kataloğu OKUNAMADI ve yanlış depoya // düşmemek için adım bilerek iptal edildi (fail-CLOSED, v0.9.1236). CodeCatalogError CodeOutcome = "catalog-error" // CodeEmptyTree — depo ağacı BOŞ döndü: proje/depo adı büyük // olasılıkla yanlış (ya da PAT'ın Code(Read) yetkisi yok). CodeEmptyTree CodeOutcome = "empty-tree" // CodeTreeMiss — ağaç geldi ama frame'lerin dosyası içinde yok. // Klasik sebep: yanlış depo ya da branş sürüm farkı. CodeTreeMiss CodeOutcome = "tree-miss" // CodeWindowFailed — dosya bulundu, okundu, ama pencere kurulamadı // (satır aralığı boş). Nadir; ayrı tutuluyor çünkü tree-miss'ten // TAMAMEN farklı bir hikâye. CodeWindowFailed CodeOutcome = "window-failed" // CodeDeadline — BİZİM süre tavanımız doldu (v0.9.1237). Suç // ayrımı korunuyor: çağıran vazgeçtiyse bu sınıf DEĞİL. CodeDeadline CodeOutcome = "deadline" // CodeCancelled — çağıran gitti (tarayıcı kapandı, üst ctx düştü). // DevOps'un yavaşlığı değil; deadline ile birleştirmek olmayan bir // yavaşlığın peşine düşürürdü. CodeCancelled CodeOutcome = "cancelled" // CodeBackendError — DevOps sunucusu hata döndü (401/404/5xx, ağ). // PAT süresi dolduğunda burası dolar: sessiz filo-çapında bozulmayı // gösteren TEK kova. CodeBackendError CodeOutcome = "backend-error" // CodeOther — sınıflandırılmamış çıkış. Sıfırdan farklı olması // KODDA bir eksik demek: FetchCode'a sınıf atamayan yeni bir çıkış // eklenmiş. Sessizce "ok" saymaktansa görünür bir kova. CodeOther CodeOutcome = "other" )
type CodeSearchHit ¶ added in v0.10.74
type CodeSearchHit struct {
Project string `json:"-"`
Repository string `json:"-"`
Path string `json:"path"`
// Branch — sonucun geldiği dal; boşsa çağıran deponun varsayılanına
// düşer.
Branch string `json:"-"`
// LastCommit — deponun son commit tarihi (v0.10.226); sıfır = bilinmiyor.
// Arama cevabı taşımaz; çağıran stampRecency ile doldurur.
LastCommit time.Time `json:"-"`
}
CodeSearchHit — arama sonucunun kullandığımız yarısı.
func PickSearchHit ¶ added in v0.10.74
func PickSearchHit(hits []CodeSearchHit, preferRepo string, frame stackparse.Frame, branchOrder []string) (CodeSearchHit, bool)
PickSearchHit — adaylardan en iyisini seçer. SAF.
preferRepo: konvansiyonun çözdüğü depo (boş olabilir). frame: paket yolu örtüşmesi için (Class'ından türer).
Hiçbir aday uygun değilse boş döner — çağıran o zaman "bulunamadı" der; uydurma bir eşleşme sunmaz.
func PickSearchHitRecency ¶ added in v0.10.226
func PickSearchHitRecency(hits []CodeSearchHit, preferRepo string, frame stackparse.Frame, branchOrder []string, recency map[string]time.Time) (CodeSearchHit, bool)
PickSearchHitRecency — PickSearchHit + tarih haritası (test/çağıran kolaylığı): haritadaki tarihleri isabetlere damgalar, sonra seçer.
func SearchCode ¶ added in v0.10.74
func SearchCode(ctx context.Context, cli *http.Client, cfg Settings, text string) ([]CodeSearchHit, error)
SearchCode — organizasyonda kod arar.
Hata durumunda BOŞ liste + hata döner ve çağıran sessizce devam eder: arama bir EK yol, kod bağlamının ön koşulu değil. Uzantı kurulu değilse (404) ya da PAT'in arama kapsamı yoksa (401) açıklama yine üretilmeli.
type CodeStats ¶ added in v0.9.1241
type CodeStats struct {
// Attempts — kod bağlamı İSTENEN her deneme (isabet + çıkmaz).
Attempts int64 `json:"attempts"`
// OK / Partial — tam ve kısmi isabet. İkisinin toplamı "kod geldi"
// demektir; isabet oranı bu toplam / Attempts.
OK int64 `json:"ok"`
Partial int64 `json:"partial"`
// Misses — çıkmaz kovaları, ÇOKTAN AZA sıralı; sıfır olanlar hiç
// yok. On bir boş kova göstermek asıl sinyali gömerdi.
Misses []CodeMissCount `json:"misses,omitempty"`
// LastUnix / LastOutcome — SON denemenin anı ve sınıfı.
LastUnix int64 `json:"lastUnix"`
LastOutcome string `json:"lastOutcome,omitempty"`
// LastError / LastErrorUnix — son BAŞARISIZ denemenin gerekçesi
// (yapışkan, bkz. codeObs.lastErr).
LastError string `json:"lastError,omitempty"`
LastErrorUnix int64 `json:"lastErrorUnix,omitempty"`
}
CodeStats — /admin/stats'ın gördüğü anlık görüntü. Tüm sayaçlar SÜREÇ BAŞLANGICINDAN beri; restart sıfırlar.
type CodeWindow ¶ added in v0.9.830
type CodeWindow struct {
Path string `json:"path"` // depo içi tam yol
Frame string `json:"frame"` // "com.x.Y.m(Y.java:246)"
Line int `json:"line"` // frame'in işaret ettiği satır
FromLine int `json:"fromLine"` // pencerenin ilk satırı (1-tabanlı)
ToLine int `json:"toLine"` // pencerenin son satırı
Content string `json:"content"` // satır numarası ÖNEKLİ kaynak
// Segment — frame'in "Caused by" zincirindeki derinliği
// (stackparse.Frame.Segment, v0.9.1235). 0 = en dış wrapper
// exception, 1+ = Caused by bölümleri. v0.9.1239'dan beri prompt
// başlığına yazılıyor: pencere sırası kök-nedene göre kuruluyor
// (AppFrames en derini başa alır) ama modele bu SIRA hiç
// söylenmiyordu — üç pencereyi eşit ağırlıkta okuyordu.
Segment int `json:"segment,omitempty"`
// Project/Repo/Branch/WebURL — v0.10.353: pencerenin GERÇEK kaynağı
// (arama isabeti başka depodan gelebilir) ve DevOps web arayüzünde
// dosya+satır linki (FileURL). Path arama isabetinde "depo:yol" taşır;
// URL kurulurken önek düşer.
Project string `json:"project,omitempty"`
Repo string `json:"repo,omitempty"`
Branch string `json:"branch,omitempty"`
WebURL string `json:"webUrl,omitempty"`
// Resource (v0.10.73) — bu pencere bir STACK FRAME'inden değil, hata
// metninin ANDIĞI kaynak dosyadan geliyor (mapper XML'i, SQL parçası).
//
// Ayrı bayrak, çünkü modele söylenmesi gereken şey farklı: frame
// penceresi "hata BURADA atıldı" der, kaynak penceresi "hatanın andığı
// tanım BU" der. İkisini aynı etiketle sunmak, modelin XML'de bir
// "hata satırı" aramasına yol açardı.
Resource bool `json:"resource,omitempty"`
// Signature / SignatureLine (v0.10.112) — pencerenin DIŞINDA kalan
// çevreleyen metot/ctor imzası ve satırı. ±30 satır çoğu metodu
// kapsar; uzun bir metodun ortasındaki hata satırında imza pencereden
// taşar ve model parametre adlarını/tiplerini göremez ("hedefin
// tanımı bu bağlamda yok"). Pencere imzayı zaten içeriyorsa boş.
Signature string `json:"signature,omitempty"`
SignatureLine int `json:"signatureLine,omitempty"`
}
CodeWindow — tek frame için çekilen kaynak penceresi.
func ClampCodeWindows ¶ added in v0.9.830
func ClampCodeWindows(ws []CodeWindow, maxRunes int) ([]CodeWindow, bool)
ClampCodeWindows — pencereleri TOPLAM rune bütçesine sığdırır. trimmed=true: en az bir pencere kısaldı ya da tümüyle düştü.
Sıra korunur: ilk pencere kök nedene en yakın olandır (AppFrames v0.9.1235'ten beri en derin "Caused by" segmentini başa koyuyor), bütçe daralınca düşecek olan SON penceredir — yani dıştaki wrapper/yeniden-fırlatma kodu. Kesme rune bazlı ve pencere içindeki SATIR sınırında yapılır — yarım satır kod, kod değildir.
Kesme MERKEZDEN yapılır (v0.9.1239) ¶
Pencere hata satırının ÜSTÜNDEN başlar (line-30). Kırpma baştan saymayla yapılırsa — v0.9.1239 öncesi hâli — kalan bütçe pencerenin yarısından azken korunan satırlar hata satırına VARMADAN biter: prompt başlığı hâlâ "… (Y.java:246)" diye satırı gösterir, o satır pencerede YOKTUR. Küçük model bunu "246 bu blokta bir yerde" diye okuyup gördüğü rastgele satırdan kök neden uydurur. Halved() bütçeyi 2000'e indirdiğinde ilk pencere bile merkezini kaybediyordu, yani taşma yeniden-denemesi tam da en çok kanıt gereken anda pencereyi işe yaramaz hâle getiriyordu.
Artık kırpma frame satırı MERKEZDE kalacak şekilde iki yandan daraltılır. Hata satırı tek başına bile bütçeye sığmıyorsa pencere DÜŞER: kullanılamaz bir pencere, hiç pencere olmamasından kötüdür (çağıran düşüşü Reason'a yazar). Line=0 olan pencerede (frame satırı bilinmiyor) eski baştan-kesme davranışı korunur.
func MapperStatementWindow ¶ added in v0.10.113
func MapperStatementWindow(body, id string, maxLines int) CodeWindow
MapperStatementWindow — XML gövdesinde `<select|insert|update|delete|sql id="ID">` bloğunu gerçek satır numaralarıyla keser (v0.10.113). Saf; tablo-testli (mapper_statement_test.go). Bulunamazsa sıfır pencere.
AST YOK: satır bazlı arama. Açılış etiketi satırı bulunur; kapanış `</tag>` içeren ilk satıra kadar (dahil) alınır; kapanış yoksa ya da blok tavanı aşarsa tavana kadar kesilir ve Frame'e "kırpıldı" düşer. CDATA/`<include>` içerik olarak aynen kalır — model onları görmeli.
func WindowAround ¶ added in v0.9.830
func WindowAround(content string, line, radius int) CodeWindow
WindowAround — dosya içeriğinden `line` merkezli ±radius satırlık pencere; satırlar numaralandırılır (" 246| kod"). Numaralar şart: modelin "246. satırdaki null kontrolü" diyebilmesi, operatörün de cevabı dosyada bulabilmesi için.
line dosyanın dışındaysa (kaynak stack'ten sonra değişmiş) pencere dosya sınırlarına kırpılır — boş dönmek yerine yakını göstermek daha faydalı, ve satır numaraları zaten gerçeği söylüyor.
type DryRunResult ¶ added in v0.9.1242
type DryRunResult struct {
Service string `json:"service"`
// OK — zincirin TAMAMI yürüdü mü (ağaç dahil).
OK bool `json:"ok"`
Steps []DryRunStep `json:"steps"`
// Özet alanlar — ekranın başlık satırı. Adımlardan türer;
// çözülemeyen alan boş kalır.
Repo string `json:"repo,omitempty"`
Project string `json:"project,omitempty"`
Branch string `json:"branch,omitempty"`
// Source — depo adının kaynağı (pin | convention).
Source string `json:"source,omitempty"`
// FileCount — ağaçtaki dosya sayısı. Yollar DÖNMEZ.
FileCount int `json:"fileCount,omitempty"`
}
DryRunResult — provanın tamamı. Steps SIRALI ve zincir nerede durduysa orada biter: yarısı yeşil, biri kırmızı, gerisi YOK. Koşmamış bir adımı "başarısız" göstermek, operatörü olmayan bir arızanın peşine düşürürdü.
type DryRunStep ¶ added in v0.9.1242
type DryRunStep struct {
Key string `json:"key"`
Label string `json:"label"`
OK bool `json:"ok"`
Detail string `json:"detail"`
// Derived (v0.10.58) — bu adım DEVOPS'A SORULMADAN, saf türetmeyle
// üretildi.
//
// ⚠ Operatör bildirdi: "Kodu incele dediğimde doğru repoyu bulmuyor."
// Ekranda "Depo adı ✓" ve "Proje ✓" görünüyordu — oysa ikisi de
// ResolveRepo'nun (saf, ağsız) ürettiği birer TAHMİN. Sunucuya hiçbir
// şey sorulmamıştı; ilk gerçek çağrı bir sonraki adımda.
//
// Yeşil tik operatöre "doğrulandı" der. Doğrulanmamış bir tahmine
// yeşil tik vermek, tam da bu ekranın çözmesi gereken soruyu
// ("depo doğru mu") cevaplamış gibi yapmaktır.
Derived bool `json:"derived,omitempty"`
}
DryRunStep — tek adımın sonucu. Detail her iki hâlde de DOLU: başarıda ne bulunduğu, başarısızlıkta neden bulunamadığı.
type FetchStats ¶ added in v0.10.112
type FetchStats struct {
FramesTotal int `json:"framesTotal,omitempty"` // ParseJava'nın verdiği tüm frame'ler
Candidates int `json:"candidates,omitempty"` // RankFrames adayları (≤ codeCandidateLimit)
Fetched int `json:"fetched,omitempty"` // gerçek dosya çekimi (tavandan düşen)
Resolved int `json:"resolved,omitempty"` // kesilen pencere (bütçe ÖNCESİ)
Missed int `json:"missed,omitempty"` // ağaçta/okumada ıskalanan frame
Untried int `json:"untried,omitempty"` // tavan/süre yüzünden hiç denenmeyen
Dupes int `json:"dupes,omitempty"` // birebir tekrar (bedava atlanan)
}
FetchStats — bir çekimin SAYILARI (v0.10.112, gözlemlenebilirlik). Reason metni operatöre hitap eder ve serbestçe değişir; span attribute'ları ve sayaçlar buradan okur. Sıfır değerler "hiç başlanmadı" demek olabilir — çağıran Outcome ile birlikte okur.
type PinRead ¶ added in v0.9.1242
type PinRead struct {
// Repo — katalogdaki `repository` alanı ("" = pin yok).
Repo string
// Abort — katalog OKUNAMADI, adım fail-CLOSED iptal edildi
// (v0.9.1236). Doluysa zincir burada durur; gerçek yolda da
// öyle durur.
Abort string
}
PinRead — servis kataloğu okumasının SONUCU.
devops paketi CH'yi bilmiyor (paket doc'u), o yüzden okumayı internal/api yapar ve sonucu buraya taşır. Şekil, gerçek yoldaki pinReadDecision'ın dönüşüyle birebir: (pin, iptal).
type ProjectHint ¶ added in v0.9.1240
type ProjectHint struct {
Value string // önerilen proje ("" = öneri yok)
Source string // RepoSourcePin | RepoSourceConvention | ""
Reason string // Value=="" iken pin + önek kaynaklarının durumu
}
ProjectHint — proje adı ÖNERİSİ, kaynağı ve (boşsa) neden boş kaldığı.
v0.9.1240 — üçüncü alan Reason yeni: proje çözülemediğinde çıkmazın nedeni ÜÇ kaynağa dağılmış durumda (pinin proje bileşeni, Ayarlar'daki Project, önek türetimi) ve ikisini yalnız burası bilir. FetchCode yalnız Ayarlar'ı görüyor, o yüzden tek başına yazdığı cümle ("servis adı bilinen bir önekle başlamıyor") pin kısa devresi yüzünden düpedüz YANLIŞ olabiliyordu: önek tutuyor, türetim hiç koşmuyordu.
type RepoNameMatch ¶ added in v0.9.1236
type RepoNameMatch struct {
Name string // sunucudaki kanonik ad ("" = eşleşme yok)
Rung string // exact | fold | loose
Alts []string // AYNI basamakta eşleşen diğer adaylar (deterministik)
Near []string // eşleşme yoksa en yakın adlar (≤ repoNearMax)
}
RepoNameMatch — istenen ad ↔ sunucudaki kanonik adlar eşleşmesi.
Name boşsa eşleşme yok ve Near doludur (varsa). Rung hangi basamağın tuttuğunu söyler — düzeltme izini yazan taraf bunu okumaz ama test okur: "fold" beklenen yerde "loose" tutuyorsa normalizasyon çok gevşemiş demektir.
func MatchRepoName ¶ added in v0.9.1236
func MatchRepoName(want string, have []string) RepoNameMatch
MatchRepoName — SAF eşleştirici; tablo-testli, ağ yok.
Basamaklar SIRAYLA denenir ve ilk DOLU basamak kazanır: harf-yazımı eşleşmesi varken ayraç-soyulmuş bir adaya geçmek, daha zayıf kanıtı daha güçlüsüne tercih etmek olurdu.
Aynı basamakta birden çok aday varsa seçim DETERMİNİSTİK: adlar sıralanır, ilki kazanır, kalanlar Alts'a düşer. Sunucunun liste sırasına güvenmek, aynı sorgunun iki farklı depoyu açması demekti — yanlış depodan kod göstermek bu özelliğin en pahalı hatası.
type RepoResolution ¶ added in v0.9.830
type RepoResolution struct {
Repo string
Source string
Reason string
// Project (v0.9.1183, operatör isteği: "service_name başında bsa-
// yazıyorsa direkt project BSA olduğunu anlasın") — DevOps proje
// ÖNERİSİ + önerinin kaynağı.
//
// Yalnız bir ÖNERİ: ayardaki açık Project her zaman kazanır (FetchCode
// sırası). Önek zaten "bu servis şu projeye ait" bilgisini taşıyor
// (kurulumun kendi adlandırma sözleşmesi), o yüzden aynı bilgiyi
// ikinci bir alana daha yazdırmak gereksiz bir el işiydi — ve boş
// bırakıldığında kod bağlamı sessizce hiç çalışmıyordu.
Project ProjectHint
}
RepoResolution — çözüm sonucu + NEDEN. Reason boş bir sonuçta operatöre gösterilir ("neden kod yok" sorusunun cevabı).
func ResolveRepo ¶ added in v0.9.830
func ResolveRepo(service, metaRepository string, cfg ResolveConfig) RepoResolution
ResolveRepo — servis adı + service_metadata.repository → depo adı.
metaRepository tam bir URL de olabilir (operatörler katalog alanına çoğunlukla depo linkini yapıştırır); son yol parçası alınır ve ".git" eki atılır. "_git/" segmenti varsa ondan SONRASI alınır — Azure DevOps depo linklerinin kanonik şekli budur.
Saf. Branş seçimi ayrıdır (PickBranch + refs API): branş varlığı sunucuya sorulmadan bilinemez.
type ResolveConfig ¶ added in v0.9.830
ResolveConfig — çözücünün ayarlanabilir kısmı. Boş alanlar varsayılana düşer, yani sıfır değer çalışır bir yapılandırmadır.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service holds the live config + a pooled HTTP client.
func (*Service) CodeObservability ¶ added in v0.9.1241
CodeObservability — sayaçların anlık görüntüsü; API sunucusu /admin/stats için çağırır (anomaly.BehaviorObservability muadili).
func (*Service) Configure ¶
Configure swaps the live config. Rebuilds the HTTP client when the TLS-verify flag flips so a connection pooled under the old certificate policy can't outlive the toggle. Any recorded detection is dropped — it described the PREVIOUS endpoint.
func (*Service) Configured ¶
Configured reports whether a server URL has been set.
func (*Service) CurrentSettings ¶
CurrentSettings returns the full config INCLUDING the PAT. Only for the settings handler's stored-secret merge — never call this from a path that writes its return value to the wire.
func (*Service) FetchCode ¶ added in v0.9.830
func (s *Service) FetchCode(ctx context.Context, repo string, hint ProjectHint, frames []stackparse.Frame, refs []stackparse.ResourceRef, errTokens []string) (out CodeContext)
FetchCode — bir depodaki frame'ler için kod pencereleri toplar.
repo boşsa ya da bağlantı yapılandırılmamışsa boş + Reason döner; HATA DÖNDÜRMEZ (fail-open sözleşmesi — imzada error yok ki çağıran yanlışlıkla açıklamayı düşürmesin). hint (v0.9.1183, v0.9.1240'ta yapılandırıldı) — proje ÖNERİSİ + önerinin kaynağı, öneri boşsa çıkmazın nedeni. Ayardaki açık Project boşsa kullanılır. Operatör isteği: "service_name başında bsa- yazıyorsa direkt project BSA olduğunu anlasın."
v0.9.1241 — her çıkış SAYILIR. Dönüş DEĞERİ adlandırıldı ve sayaç tek bir defer'den geçiyor: on dört çıkışın her birine elle sayaç eklemek, on beşinci eklendiğinde sessizce eksik kalırdı. Sınıfı atamayan bir dal "other" kovasına düşer — görünür bir eksik, sessiz bir "ok" değil. refs (v0.10.73) — hata METNİNİN andığı kaynak dosya adayları (stackparse.ResourceRefs). Boş geçilebilir: kaynak avı atlanır.
func (*Service) LoadPersisted ¶
LoadPersisted hydrates the in-memory config from system_settings. Missing blob = empty config (Configured reports false).
func (*Service) RecordCodeOutcome ¶ added in v0.9.1241
func (s *Service) RecordCodeOutcome(class CodeOutcome, reason string)
RecordCodeOutcome — kod-çekme sonucunu sayar. FetchCode'dan ÖNCEKİ adımlar (katalog okuması, depo çözümü — internal/api) da buradan geçer: sayaç "operatör kod istedi" anını ölçmeli, yalnız işin FetchCode'a kadar gelebilen kısmını değil.
nil-Service güvenli: kod entegrasyonu hiç kurulmamış bir sürecte çağıran ekstra bir muhafız yazmak zorunda kalmasın.
func (*Service) ResolveConfig ¶ added in v0.9.830
func (s *Service) ResolveConfig() ResolveConfig
ResolveConfig returns the service→repo convention with defaults already folded in, so callers never have to know what the fallback is. Safe on a nil Service (returns the bundled defaults).
func (*Service) ResolveDryRun ¶ added in v0.9.1242
ResolveDryRun — servis adı → depo/branş/ağaç, adım adım. LLM YOK, yazma YOK, sayaç YOK.
Zincir ilk kırmızıda DURUR. Bağlantı yoksa hiç başlamaz: türetilmiş bir depo adını sunucuya sormadan göstermek, doğrulanmamış bir tahmini cevap gibi sunmak olurdu — bu ekranın var olma sebebi tam da o yanılgıyı bitirmek.
func (*Service) SavePersisted ¶
SavePersisted writes the typed config to system_settings and swaps the live client. The handler merges the stored PAT in before calling this — see api.mergeDevOpsSettings.
func (*Service) StartConfigRefresh ¶
func (s *Service) StartConfigRefresh(ctx context.Context, store settingsStore, interval time.Duration)
StartConfigRefresh keeps peer pods converged on the shared blob (tempo/thanos template). interval ≤ 0 → 30s.
func (*Service) Test ¶
func (s *Service) Test(ctx context.Context, cfg Settings) TestResult
Test probes a CANDIDATE config without saving or swapping anything — the Settings tab's "Test connection" button. On success against the live endpoint it records the detected flavor so the Snapshot can report it.
func (*Service) TestConnection ¶
func (s *Service) TestConnection(ctx context.Context) TestResult
TestConnection probes the LIVE config.
type Settings ¶
type Settings struct {
// BaseURL is the server root, with or without the collection.
// e.g. https://devops.example.local/tfs
BaseURL string `json:"baseUrl"`
// Collection is the TFS collection / Azure DevOps organisation
// segment, e.g. "DefaultCollection". Empty is allowed for
// installs that already carry it inside BaseURL.
Collection string `json:"collection,omitempty"`
// CodeSearch (v0.10.74) — organizasyon geneli kod araması AÇIK mı.
//
// ⚠ VARSAYILAN KAPALI, bilinçli. Arama, kod yoluna YENİ bir ağ
// çağrısı ekliyor ve Azure DevOps'ta ayrı bir uzantı (Code Search)
// gerektiriyor — kurulu değilse uç 404 döner. Ayrıca API şekli
// yalnız operatörün örneğinde doğrulanabilir.
//
// Kapalıyken davranış bit-bit eskisi: konvansiyon + depo ağacı.
// Açıldığında yalnız İSKALAYAN frame'ler için devreye giriyor, yani
// bugün çalışan hiçbir çözümü değiştirmiyor.
CodeSearch bool `json:"codeSearch,omitempty"`
// Project is optional. When set, TestConnection verifies the
// project resolves as well as the collection.
Project string `json:"project,omitempty"`
// Username is optional. PAT auth conventionally sends an EMPTY
// username with the PAT as the password; NTLM-era TFS installs
// sometimes want a real account name alongside it.
Username string `json:"username,omitempty"`
// PAT is the personal access token — the secret. Never echoed
// in Snapshot(), never interpolated into an error string, never
// written to audit_log.
PAT string `json:"pat,omitempty"`
// Flavor — auto | azure-devops-server | tfs.
Flavor string `json:"flavor,omitempty"`
// InsecureSkipVerify relaxes TLS chain verification, for the
// internal CA / self-signed certs common on on-prem servers.
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
// RepoPrefixes / BranchOrder (v0.9.830) — the service→repo naming
// convention. Empty = the bundled defaults (see repo_resolve.go).
//
// These live in the SAME blob rather than a new settings key: one
// integration, one row (invariant 5's spirit — no new schema per
// surface). They are not secrets and DO round-trip through the
// snapshot, unlike the PAT — the secret contract is unchanged.
RepoPrefixes []string `json:"repoPrefixes,omitempty"`
BranchOrder []string `json:"branchOrder,omitempty"`
// AppPrefixes (v0.10.112) — UYGULAMA paket önekleri
// ("com.banka.odeme.", "com.banka.kart."). Kod çekicisi bu öneklerle
// başlayan frame'leri kurum-içi çerçeve/kütüphane frame'lerinden
// ÖNCE dener (stackparse.RankFrames); deneme tavanı önce onlara
// harcanır. Boş = eski davranış (yalnız JDK/Spring/JBoss elenir,
// kalan her frame eşit).
AppPrefixes []string `json:"appPrefixes,omitempty"`
// CodeLookupLimit (v0.10.112) — bir açıklama için en fazla kaç
// dosya ÇEKİMİ denenir. 0 = varsayılan (DefaultCodeLookupLimit);
// [1, MaxCodeLookupLimit] aralığına sıkıştırılır (lookupLimit()).
CodeLookupLimit int `json:"codeLookupLimit,omitempty"`
// CodeSearchLimit (v0.10.353, operatör: "arama tavanını yükseltelim") —
// bir açıklama için organizasyon geneli kod ARAMASI en fazla kaç frame /
// hata-kodu için denenir. 0 = varsayılan (DefaultCodeSearchLimit);
// [1, MaxCodeSearchLimit] aralığına sıkıştırılır (searchLimit()).
CodeSearchLimit int `json:"codeSearchLimit,omitempty"`
}
Settings is the persisted connection config, stored as a JSON blob under the system_settings key "devops_connection".
type Snapshot ¶
type Snapshot struct {
BaseURL string `json:"baseUrl"`
Collection string `json:"collection,omitempty"`
Project string `json:"project,omitempty"`
Username string `json:"username,omitempty"`
HasPAT bool `json:"hasPat"`
Flavor string `json:"flavor,omitempty"`
InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
// CodeSearch (v0.10.75) — organizasyon araması açık mı. Snapshot'ta,
// çünkü ekran kutunun DURUMUNU göstermek zorunda: kapalı bir ayarı
// açık göstermek, operatöre çalışmayan bir yolun çalıştığını sandırır.
CodeSearch bool `json:"codeSearch,omitempty"`
DetectedFlavor string `json:"detectedFlavor,omitempty"`
DetectedAPIVersion string `json:"detectedApiVersion,omitempty"`
// RepoPrefixes / BranchOrder (v0.9.830) — echoed back RESOLVED, i.e.
// the defaults appear when the operator saved nothing. The card
// would otherwise render two empty boxes next to a resolver that is
// quietly using "bsa-" and release→master, and the first question
// out of a failed lookup would be "but what IS it stripping?".
RepoPrefixes []string `json:"repoPrefixes,omitempty"`
BranchOrder []string `json:"branchOrder,omitempty"`
// AppPrefixes / CodeLookupLimit (v0.10.112) — olduğu gibi yankılanır;
// tavan 0 ise ekran "varsayılan 6" der, RESOLVED değer ayrıca
// EffectiveLookupLimit'te (kutu boşken bile yürürlükteki sayı görünsün).
AppPrefixes []string `json:"appPrefixes,omitempty"`
CodeLookupLimit int `json:"codeLookupLimit,omitempty"`
CodeSearchLimit int `json:"codeSearchLimit,omitempty"` // v0.10.353
EffectiveLookupLimit int `json:"effectiveLookupLimit"`
}
Snapshot is the public view returned by GET /api/settings/devops. Mirrors Settings with the PAT replaced by a HasPAT signal.
DetectedFlavor / DetectedAPIVersion report what the last successful probe of THIS config actually spoke. They are in-memory only and deliberately NOT persisted: re-detecting at boot costs one request and can never go stale, whereas a written-back guess survives a server upgrade and starts lying.
type TestResult ¶
type TestResult struct {
OK bool `json:"ok"`
DetectedFlavor string `json:"detectedFlavor,omitempty"`
APIVersion string `json:"apiVersion,omitempty"`
ProjectCount int `json:"projectCount"`
// ProjectChecked is true when Settings.Project was set and the
// project lookup ran, so the UI can say "collection + project OK"
// rather than implying it verified something it didn't.
ProjectChecked bool `json:"projectChecked,omitempty"`
Error string `json:"error,omitempty"`
}
TestResult is the POST /api/settings/devops/test response. Either OK with a project count, or a sanitised error string.