From 4760cd8c80b07f93cc9d02d79ebb66343d62c8a8 Mon Sep 17 00:00:00 2001 From: Snider Date: Sun, 15 Mar 2026 15:17:13 +0000 Subject: [PATCH 1/6] chore: bump core/go to v0.3.1 Co-Authored-By: Virgil --- go.mod | 62 ++++++++++++------------ go.sum | 146 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 105 insertions(+), 103 deletions(-) diff --git a/go.mod b/go.mod index a9d105b..2f33e1d 100644 --- a/go.mod +++ b/go.mod @@ -3,19 +3,19 @@ module forge.lthn.ai/core/go-process go 1.26.0 require ( - forge.lthn.ai/core/api v0.1.0 - forge.lthn.ai/core/go v0.3.0 - forge.lthn.ai/core/go-ws v0.1.3 + forge.lthn.ai/core/api v0.1.2 + forge.lthn.ai/core/go v0.3.1 + forge.lthn.ai/core/go-ws v0.2.0 github.com/gin-gonic/gin v1.12.0 github.com/stretchr/testify v1.11.1 ) require ( - github.com/99designs/gqlgen v0.17.87 // indirect + github.com/99designs/gqlgen v0.17.88 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/agnivade/levenshtein v1.2.1 // indirect github.com/andybalholm/brotli v1.2.0 // indirect - github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect + github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect github.com/bytedance/gopkg v0.1.3 // indirect github.com/bytedance/sonic v1.15.0 // indirect github.com/bytedance/sonic/loader v0.5.0 // indirect @@ -43,21 +43,21 @@ require ( github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.4 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/spec v0.22.0 // indirect - github.com/go-openapi/swag/conv v0.25.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.4 // indirect - github.com/go-openapi/swag/jsonutils v0.25.1 // indirect - github.com/go-openapi/swag/loading v0.25.1 // indirect - github.com/go-openapi/swag/stringutils v0.25.1 // indirect - github.com/go-openapi/swag/typeutils v0.25.1 // indirect - github.com/go-openapi/swag/yamlutils v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonreference v0.21.5 // indirect + github.com/go-openapi/spec v0.22.4 // indirect + github.com/go-openapi/swag/conv v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.25.5 // indirect + github.com/go-openapi/swag/jsonutils v0.25.5 // indirect + github.com/go-openapi/swag/loading v0.25.5 // indirect + github.com/go-openapi/swag/stringutils v0.25.5 // indirect + github.com/go-openapi/swag/typeutils v0.25.5 // indirect + github.com/go-openapi/swag/yamlutils v0.25.5 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.30.1 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect - github.com/goccy/go-json v0.10.5 // indirect + github.com/goccy/go-json v0.10.6 // indirect github.com/goccy/go-yaml v1.19.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/context v1.1.2 // indirect @@ -76,7 +76,7 @@ require ( github.com/quic-go/qpack v0.6.0 // indirect github.com/quic-go/quic-go v0.59.0 // indirect github.com/redis/go-redis/v9 v9.18.0 // indirect - github.com/sosodev/duration v1.3.1 // indirect + github.com/sosodev/duration v1.4.0 // indirect github.com/swaggo/files v1.0.1 // indirect github.com/swaggo/gin-swagger v1.6.1 // indirect github.com/swaggo/swag v1.16.6 // indirect @@ -85,22 +85,22 @@ require ( github.com/vektah/gqlparser/v2 v2.5.32 // indirect go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.65.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.67.0 // indirect + go.opentelemetry.io/otel v1.42.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/arch v0.23.0 // indirect - golang.org/x/crypto v0.48.0 // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/net v0.51.0 // indirect - golang.org/x/oauth2 v0.35.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/text v0.34.0 // indirect - golang.org/x/tools v0.42.0 // indirect + golang.org/x/arch v0.25.0 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/mod v0.34.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.35.0 // indirect + golang.org/x/tools v0.43.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 82fb176..188b322 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ -forge.lthn.ai/core/api v0.1.0 h1:ZKnQx+L9vxLQSEjwpsD1eNcIQrE4YKV1c2AlMtseM6o= -forge.lthn.ai/core/api v0.1.0/go.mod h1:c86Lk9AmaS0xbiRCEG/+du8s9KyYNHnp8RED35gR/Fo= -forge.lthn.ai/core/go v0.3.0 h1:mOG97ApMprwx9Ked62FdWVwXTGSF6JO6m0DrVpoH2Q4= -forge.lthn.ai/core/go v0.3.0/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= -forge.lthn.ai/core/go-ws v0.1.3 h1:TzqFpEcDYcZUFFmrTznfEuVcVdnp2jsRNwAGHeTyXN0= -forge.lthn.ai/core/go-ws v0.1.3/go.mod h1:iDbJuR1NT27czjtNIluxnEdLrnfsYQdEBIrsoZnpkCk= -github.com/99designs/gqlgen v0.17.87 h1:pSnCIMhBQezAE8bc1GNmfdLXFmnWtWl1GRDFEE/nHP8= -github.com/99designs/gqlgen v0.17.87/go.mod h1:fK05f1RqSNfQpd4CfW5qk/810Tqi4/56Wf6Nem0khAg= +forge.lthn.ai/core/api v0.1.2 h1:VKHOQhjWcNCG4Xf9lJfrABRwk/+1tp8YsdQzPNVxzek= +forge.lthn.ai/core/api v0.1.2/go.mod h1:vDkEihL/Cn1yKF8oA2jjf1CVOcd7kOP/WYWoIHIu2+E= +forge.lthn.ai/core/go v0.3.1 h1:5FMTsUhLcxSr07F9q3uG0Goy4zq4eLivoqi8shSY4UM= +forge.lthn.ai/core/go v0.3.1/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= +forge.lthn.ai/core/go-ws v0.2.0 h1:w1uG5MgUeGoWGu1hBh8liTXcsMJDrjvPGeIsg6fyvYk= +forge.lthn.ai/core/go-ws v0.2.0/go.mod h1:iDbJuR1NT27czjtNIluxnEdLrnfsYQdEBIrsoZnpkCk= +github.com/99designs/gqlgen v0.17.88 h1:neMQDgehMwT1vYIOx/w5ZYPUU/iMNAJzRO44I5Intoc= +github.com/99designs/gqlgen v0.17.88/go.mod h1:qeqYFEgOeSKqWedOjogPizimp2iu4E23bdPvl4jTYic= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/PuerkitoBio/goquery v1.11.0 h1:jZ7pwMQXIITcUXNH83LLk+txlaEy6NVOfTuP43xxfqw= @@ -21,8 +21,8 @@ github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmg github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE= -github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs= +github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -89,31 +89,33 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= -github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/spec v0.22.0 h1:xT/EsX4frL3U09QviRIZXvkh80yibxQmtoEvyqug0Tw= -github.com/go-openapi/spec v0.22.0/go.mod h1:K0FhKxkez8YNS94XzF8YKEMULbFrRw4m15i2YUht4L0= +github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= +github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= +github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= +github.com/go-openapi/spec v0.22.4 h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ= +github.com/go-openapi/spec v0.22.4/go.mod h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ= github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= -github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0= -github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs= -github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= -github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= -github.com/go-openapi/swag/jsonutils v0.25.1 h1:AihLHaD0brrkJoMqEZOBNzTLnk81Kg9cWr+SPtxtgl8= -github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1 h1:DSQGcdB6G0N9c/KhtpYc71PzzGEIc/fZ1no35x4/XBY= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1/go.mod h1:kjmweouyPwRUEYMSrbAidoLMGeJ5p6zdHi9BgZiqmsg= -github.com/go-openapi/swag/loading v0.25.1 h1:6OruqzjWoJyanZOim58iG2vj934TysYVptyaoXS24kw= -github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc= -github.com/go-openapi/swag/stringutils v0.25.1 h1:Xasqgjvk30eUe8VKdmyzKtjkVjeiXx1Iz0zDfMNpPbw= -github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg= -github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3I3ysiFZqukA= -github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= -github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk= -github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= -github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= -github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= +github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= +github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= +github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= +github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= +github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo= +github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= +github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= +github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= +github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= +github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= +github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= +github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= +github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0 h1:7SgOMTvJkM8yWrQlU8Jm18VeDPuAvB/xWrdxFJkoFag= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM= +github.com/go-openapi/testify/v2 v2.4.0 h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM= +github.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -124,8 +126,8 @@ github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy0 github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= -github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU= +github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= @@ -179,8 +181,8 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= -github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/sosodev/duration v1.4.0 h1:35ed0KiVFriGHHzZZJaZLgmTEEICIyt8Sx0RQfj9IjE= +github.com/sosodev/duration v1.4.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -213,22 +215,22 @@ go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.65.0 h1:LSJsvNqhj2sBNFb5NWHbyDK4QJ/skQ2ydjeOZ9OYNZ4= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.65.0/go.mod h1:0Q5ocj6h/+C6KYq8cnl4tDFVd4I1HBdsJ440aeagHos= -go.opentelemetry.io/contrib/propagators/b3 v1.40.0 h1:xariChe8OOVF3rNlfzGFgQc61npQmXhzZj/i82mxMfg= -go.opentelemetry.io/contrib/propagators/b3 v1.40.0/go.mod h1:72WvbdxbOfXaELEQfonFfOL6osvcVjI7uJEE8C2nkrs= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 h1:MzfofMZN8ulNqobCmCAVbqVL5syHw+eB2qPRkCMA/fQ= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0/go.mod h1:E73G9UFtKRXrxhBsHtG00TB5WxX57lpsQzogDkqBTz8= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.67.0 h1:E7DmskpIO7ZR6QI6zKSEKIDNUYoKw9oHXP23gzbCdU0= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.67.0/go.mod h1:WB2cS9y+AwqqKhoo9gw6/ZxlSjFBUQGZ8BQOaD3FVXM= +go.opentelemetry.io/contrib/propagators/b3 v1.42.0 h1:B2Pew5ufEtgkjLF+tSkXjgYZXQr9m7aCm1wLKB0URbU= +go.opentelemetry.io/contrib/propagators/b3 v1.42.0/go.mod h1:iPgUcSEF5DORW6+yNbdw/YevUy+QqJ508ncjhrRSCjc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -237,28 +239,28 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg= -golang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= +golang.org/x/arch v0.25.0 h1:qnk6Ksugpi5Bz32947rkUgDt9/s5qvqDPl/gBKdMJLE= +golang.org/x/arch v0.25.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= -golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -266,8 +268,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -275,14 +277,14 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= From c3b9374ae1ce7f1226c375161c5b606b83652bbc Mon Sep 17 00:00:00 2001 From: Snider Date: Sun, 15 Mar 2026 15:55:20 +0000 Subject: [PATCH 2/6] feat: add Detach option for process group isolation RunOptions.Detach creates the process in its own process group (Setpgid) and uses context.Background() instead of the parent context. Detached processes survive parent death. Co-Authored-By: Virgil --- service.go | 13 ++++++++++++- types.go | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/service.go b/service.go index 44ccfc6..661dac9 100644 --- a/service.go +++ b/service.go @@ -9,6 +9,7 @@ import ( "os/exec" "sync" "sync/atomic" + "syscall" "time" "forge.lthn.ai/core/go/pkg/core" @@ -96,7 +97,12 @@ func (s *Service) Start(ctx context.Context, command string, args ...string) (*P func (s *Service) StartWithOptions(ctx context.Context, opts RunOptions) (*Process, error) { id := fmt.Sprintf("proc-%d", s.idCounter.Add(1)) - procCtx, cancel := context.WithCancel(ctx) + // Detached processes use Background context so they survive parent death + parentCtx := ctx + if opts.Detach { + parentCtx = context.Background() + } + procCtx, cancel := context.WithCancel(parentCtx) cmd := exec.CommandContext(procCtx, opts.Command, opts.Args...) if opts.Dir != "" { @@ -106,6 +112,11 @@ func (s *Service) StartWithOptions(ctx context.Context, opts RunOptions) (*Proce cmd.Env = append(cmd.Environ(), opts.Env...) } + // Detached processes get their own process group + if opts.Detach { + cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + } + // Set up pipes stdout, err := cmd.StdoutPipe() if err != nil { diff --git a/types.go b/types.go index 4489af7..8589122 100644 --- a/types.go +++ b/types.go @@ -73,6 +73,10 @@ type RunOptions struct { // DisableCapture disables output buffering. // By default, output is captured to a ring buffer. DisableCapture bool + // Detach creates the process in its own process group (Setpgid). + // Detached processes survive parent death and context cancellation. + // The context is replaced with context.Background() when Detach is true. + Detach bool } // Info provides a snapshot of process state without internal fields. From 715c14f048e1c071dc9f697cb040f4c1c64f4d1d Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 18:27:34 +0000 Subject: [PATCH 3/6] refactor(process): replace os file ops with coreio.Local in pidfile and registry Replace all os.ReadFile, os.WriteFile, os.MkdirAll, os.Remove calls in pidfile.go and registry.go with coreio.Local equivalents (Read, Write, EnsureDir, Delete). Add forge.lthn.ai/core/go-io v0.1.2 as a direct dependency. Co-Authored-By: Virgil --- go.mod | 2 ++ go.sum | 4 ++++ pidfile.go | 18 ++++++++++-------- registry.go | 24 +++++++++++++----------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 2f33e1d..2d5e8f1 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,8 @@ require ( ) require ( + forge.lthn.ai/core/go-io v0.1.2 // indirect + forge.lthn.ai/core/go-log v0.0.2 // indirect github.com/99designs/gqlgen v0.17.88 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/agnivade/levenshtein v1.2.1 // indirect diff --git a/go.sum b/go.sum index 188b322..cfc0b77 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,10 @@ forge.lthn.ai/core/api v0.1.2 h1:VKHOQhjWcNCG4Xf9lJfrABRwk/+1tp8YsdQzPNVxzek= forge.lthn.ai/core/api v0.1.2/go.mod h1:vDkEihL/Cn1yKF8oA2jjf1CVOcd7kOP/WYWoIHIu2+E= forge.lthn.ai/core/go v0.3.1 h1:5FMTsUhLcxSr07F9q3uG0Goy4zq4eLivoqi8shSY4UM= forge.lthn.ai/core/go v0.3.1/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= +forge.lthn.ai/core/go-io v0.1.2 h1:q8hj2jtOFqAgHlBr5wsUAOXtaFkxy9gqGrQT/il0WYA= +forge.lthn.ai/core/go-io v0.1.2/go.mod h1:PbNKW1Q25ywSOoQXeGdQHbV5aiIrTXvHIQ5uhplA//g= +forge.lthn.ai/core/go-log v0.0.2 h1:zJEgbajs5AjvhYzsbyybzn+S2Titiv56r3BG5E1cNUo= +forge.lthn.ai/core/go-log v0.0.2/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw= forge.lthn.ai/core/go-ws v0.2.0 h1:w1uG5MgUeGoWGu1hBh8liTXcsMJDrjvPGeIsg6fyvYk= forge.lthn.ai/core/go-ws v0.2.0/go.mod h1:iDbJuR1NT27czjtNIluxnEdLrnfsYQdEBIrsoZnpkCk= github.com/99designs/gqlgen v0.17.88 h1:neMQDgehMwT1vYIOx/w5ZYPUU/iMNAJzRO44I5Intoc= diff --git a/pidfile.go b/pidfile.go index 3a2083e..96e7d5b 100644 --- a/pidfile.go +++ b/pidfile.go @@ -8,6 +8,8 @@ import ( "strings" "sync" "syscall" + + coreio "forge.lthn.ai/core/go-io" ) // PIDFile manages a process ID file for single-instance enforcement. @@ -27,8 +29,8 @@ func (p *PIDFile) Acquire() error { p.mu.Lock() defer p.mu.Unlock() - if data, err := os.ReadFile(p.path); err == nil { - pid, err := strconv.Atoi(strings.TrimSpace(string(data))) + if data, err := coreio.Local.Read(p.path); err == nil { + pid, err := strconv.Atoi(strings.TrimSpace(data)) if err == nil && pid > 0 { if proc, err := os.FindProcess(pid); err == nil { if err := proc.Signal(syscall.Signal(0)); err == nil { @@ -36,17 +38,17 @@ func (p *PIDFile) Acquire() error { } } } - _ = os.Remove(p.path) + _ = coreio.Local.Delete(p.path) } if dir := filepath.Dir(p.path); dir != "." { - if err := os.MkdirAll(dir, 0755); err != nil { + if err := coreio.Local.EnsureDir(dir); err != nil { return fmt.Errorf("failed to create PID directory: %w", err) } } pid := os.Getpid() - if err := os.WriteFile(p.path, []byte(strconv.Itoa(pid)), 0644); err != nil { + if err := coreio.Local.Write(p.path, strconv.Itoa(pid)); err != nil { return fmt.Errorf("failed to write PID file: %w", err) } @@ -57,7 +59,7 @@ func (p *PIDFile) Acquire() error { func (p *PIDFile) Release() error { p.mu.Lock() defer p.mu.Unlock() - return os.Remove(p.path) + return coreio.Local.Delete(p.path) } // Path returns the PID file path. @@ -69,12 +71,12 @@ func (p *PIDFile) Path() string { // Returns (pid, true) if the process is alive, (pid, false) if dead/stale, // or (0, false) if the file doesn't exist or is invalid. func ReadPID(path string) (int, bool) { - data, err := os.ReadFile(path) + data, err := coreio.Local.Read(path) if err != nil { return 0, false } - pid, err := strconv.Atoi(strings.TrimSpace(string(data))) + pid, err := strconv.Atoi(strings.TrimSpace(data)) if err != nil || pid <= 0 { return 0, false } diff --git a/registry.go b/registry.go index 0f87ddf..fca2399 100644 --- a/registry.go +++ b/registry.go @@ -7,6 +7,8 @@ import ( "strings" "syscall" "time" + + coreio "forge.lthn.ai/core/go-io" ) // DaemonEntry records a running daemon in the registry. @@ -47,7 +49,7 @@ func (r *Registry) Register(entry DaemonEntry) error { entry.Started = time.Now() } - if err := os.MkdirAll(r.dir, 0755); err != nil { + if err := coreio.Local.EnsureDir(r.dir); err != nil { return err } @@ -56,12 +58,12 @@ func (r *Registry) Register(entry DaemonEntry) error { return err } - return os.WriteFile(r.entryPath(entry.Code, entry.Daemon), data, 0644) + return coreio.Local.Write(r.entryPath(entry.Code, entry.Daemon), string(data)) } // Unregister removes a daemon entry from the registry. func (r *Registry) Unregister(code, daemon string) error { - return os.Remove(r.entryPath(code, daemon)) + return coreio.Local.Delete(r.entryPath(code, daemon)) } // Get reads a single daemon entry and checks whether its process is alive. @@ -69,19 +71,19 @@ func (r *Registry) Unregister(code, daemon string) error { func (r *Registry) Get(code, daemon string) (*DaemonEntry, bool) { path := r.entryPath(code, daemon) - data, err := os.ReadFile(path) + data, err := coreio.Local.Read(path) if err != nil { return nil, false } var entry DaemonEntry - if err := json.Unmarshal(data, &entry); err != nil { - _ = os.Remove(path) + if err := json.Unmarshal([]byte(data), &entry); err != nil { + _ = coreio.Local.Delete(path) return nil, false } if !isAlive(entry.PID) { - _ = os.Remove(path) + _ = coreio.Local.Delete(path) return nil, false } @@ -97,19 +99,19 @@ func (r *Registry) List() ([]DaemonEntry, error) { var alive []DaemonEntry for _, path := range matches { - data, err := os.ReadFile(path) + data, err := coreio.Local.Read(path) if err != nil { continue } var entry DaemonEntry - if err := json.Unmarshal(data, &entry); err != nil { - _ = os.Remove(path) + if err := json.Unmarshal([]byte(data), &entry); err != nil { + _ = coreio.Local.Delete(path) continue } if !isAlive(entry.PID) { - _ = os.Remove(path) + _ = coreio.Local.Delete(path) continue } From 10adcbe2893f869244ab68a99015b0668a8986a7 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 18:41:56 +0000 Subject: [PATCH 4/6] fix(test): SetDefault returns error not panic, update test Co-Authored-By: Virgil --- global_test.go | 7 +++---- go.mod | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/global_test.go b/global_test.go index 5aa99e0..eb334fb 100644 --- a/global_test.go +++ b/global_test.go @@ -65,10 +65,9 @@ func TestGlobal_SetDefault(t *testing.T) { assert.Equal(t, svc, Default()) }) - t.Run("panics on nil", func(t *testing.T) { - assert.Panics(t, func() { - SetDefault(nil) - }) + t.Run("errors on nil", func(t *testing.T) { + err := SetDefault(nil) + assert.Error(t, err) }) } diff --git a/go.mod b/go.mod index 2d5e8f1..3a0b343 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,13 @@ go 1.26.0 require ( forge.lthn.ai/core/api v0.1.2 forge.lthn.ai/core/go v0.3.1 + forge.lthn.ai/core/go-io v0.1.2 forge.lthn.ai/core/go-ws v0.2.0 github.com/gin-gonic/gin v1.12.0 github.com/stretchr/testify v1.11.1 ) require ( - forge.lthn.ai/core/go-io v0.1.2 // indirect forge.lthn.ai/core/go-log v0.0.2 // indirect github.com/99designs/gqlgen v0.17.88 // indirect github.com/KyleBanks/depth v1.2.1 // indirect From d73dfa3d7361d827b06e25432111929525376d9e Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 20:34:23 +0000 Subject: [PATCH 5/6] refactor(process): replace fmt.Errorf and errors.New with coreerr.E() Replace all 27 instances of fmt.Errorf/errors.New in production code with coreerr.E() from forge.lthn.ai/core/go-log for structured error context (op, message, cause). Promote go-log from indirect to direct dependency in go.mod. Co-Authored-By: Virgil --- daemon.go | 13 +++++++------ exec/exec.go | 8 +++++--- go.mod | 2 +- health.go | 4 +++- pidfile.go | 7 ++++--- process.go | 8 +++++--- runner.go | 7 ++++--- service.go | 21 +++++++++++---------- 8 files changed, 40 insertions(+), 30 deletions(-) diff --git a/daemon.go b/daemon.go index ffa71bf..f0565ac 100644 --- a/daemon.go +++ b/daemon.go @@ -3,10 +3,11 @@ package process import ( "context" "errors" - "fmt" "os" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // DaemonOptions configures daemon mode execution. @@ -72,7 +73,7 @@ func (d *Daemon) Start() error { defer d.mu.Unlock() if d.running { - return errors.New("daemon already running") + return coreerr.E("Daemon.Start", "daemon already running", nil) } if d.pid != nil { @@ -100,7 +101,7 @@ func (d *Daemon) Start() error { entry.Health = d.health.Addr() } if err := d.opts.Registry.Register(entry); err != nil { - return fmt.Errorf("registry: %w", err) + return coreerr.E("Daemon.Start", "registry", err) } } @@ -112,7 +113,7 @@ func (d *Daemon) Run(ctx context.Context) error { d.mu.Lock() if !d.running { d.mu.Unlock() - return errors.New("daemon not started - call Start() first") + return coreerr.E("Daemon.Run", "daemon not started - call Start() first", nil) } d.mu.Unlock() @@ -138,13 +139,13 @@ func (d *Daemon) Stop() error { if d.health != nil { d.health.SetReady(false) if err := d.health.Stop(shutdownCtx); err != nil { - errs = append(errs, fmt.Errorf("health server: %w", err)) + errs = append(errs, coreerr.E("Daemon.Stop", "health server", err)) } } if d.pid != nil { if err := d.pid.Release(); err != nil && !os.IsNotExist(err) { - errs = append(errs, fmt.Errorf("pid file: %w", err)) + errs = append(errs, coreerr.E("Daemon.Stop", "pid file", err)) } } diff --git a/exec/exec.go b/exec/exec.go index 21978a9..ae875a0 100644 --- a/exec/exec.go +++ b/exec/exec.go @@ -8,6 +8,8 @@ import ( "os" "os/exec" "strings" + + coreerr "forge.lthn.ai/core/go-log" ) // Options configuration for command execution @@ -147,7 +149,7 @@ func RunQuiet(ctx context.Context, name string, args ...string) error { cmd := Command(ctx, name, args...).WithStderr(&stderr) if err := cmd.Run(); err != nil { // Include stderr in error message - return fmt.Errorf("%w: %s", err, strings.TrimSpace(stderr.String())) + return coreerr.E("RunQuiet", strings.TrimSpace(stderr.String()), err) } return nil } @@ -155,9 +157,9 @@ func RunQuiet(ctx context.Context, name string, args ...string) error { func wrapError(err error, name string, args []string) error { cmdStr := name + " " + strings.Join(args, " ") if exitErr, ok := err.(*exec.ExitError); ok { - return fmt.Errorf("command %q failed with exit code %d: %w", cmdStr, exitErr.ExitCode(), err) + return coreerr.E("wrapError", fmt.Sprintf("command %q failed with exit code %d", cmdStr, exitErr.ExitCode()), err) } - return fmt.Errorf("failed to execute %q: %w", cmdStr, err) + return coreerr.E("wrapError", fmt.Sprintf("failed to execute %q", cmdStr), err) } func (c *Cmd) getLogger() Logger { diff --git a/go.mod b/go.mod index 3a0b343..4e5072c 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,13 @@ require ( forge.lthn.ai/core/api v0.1.2 forge.lthn.ai/core/go v0.3.1 forge.lthn.ai/core/go-io v0.1.2 + forge.lthn.ai/core/go-log v0.0.2 forge.lthn.ai/core/go-ws v0.2.0 github.com/gin-gonic/gin v1.12.0 github.com/stretchr/testify v1.11.1 ) require ( - forge.lthn.ai/core/go-log v0.0.2 // indirect github.com/99designs/gqlgen v0.17.88 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/agnivade/levenshtein v1.2.1 // indirect diff --git a/health.go b/health.go index 0f8563a..98ecdd3 100644 --- a/health.go +++ b/health.go @@ -7,6 +7,8 @@ import ( "net/http" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // HealthCheck is a function that returns nil if healthy. @@ -82,7 +84,7 @@ func (h *HealthServer) Start() error { listener, err := net.Listen("tcp", h.addr) if err != nil { - return fmt.Errorf("failed to listen on %s: %w", h.addr, err) + return coreerr.E("HealthServer.Start", fmt.Sprintf("failed to listen on %s", h.addr), err) } h.listener = listener diff --git a/pidfile.go b/pidfile.go index 96e7d5b..240c44c 100644 --- a/pidfile.go +++ b/pidfile.go @@ -10,6 +10,7 @@ import ( "syscall" coreio "forge.lthn.ai/core/go-io" + coreerr "forge.lthn.ai/core/go-log" ) // PIDFile manages a process ID file for single-instance enforcement. @@ -34,7 +35,7 @@ func (p *PIDFile) Acquire() error { if err == nil && pid > 0 { if proc, err := os.FindProcess(pid); err == nil { if err := proc.Signal(syscall.Signal(0)); err == nil { - return fmt.Errorf("another instance is running (PID %d)", pid) + return coreerr.E("PIDFile.Acquire", fmt.Sprintf("another instance is running (PID %d)", pid), nil) } } } @@ -43,13 +44,13 @@ func (p *PIDFile) Acquire() error { if dir := filepath.Dir(p.path); dir != "." { if err := coreio.Local.EnsureDir(dir); err != nil { - return fmt.Errorf("failed to create PID directory: %w", err) + return coreerr.E("PIDFile.Acquire", "failed to create PID directory", err) } } pid := os.Getpid() if err := coreio.Local.Write(p.path, strconv.Itoa(pid)); err != nil { - return fmt.Errorf("failed to write PID file: %w", err) + return coreerr.E("PIDFile.Acquire", "failed to write PID file", err) } return nil diff --git a/process.go b/process.go index e69c5ee..f9cc222 100644 --- a/process.go +++ b/process.go @@ -8,6 +8,8 @@ import ( "os/exec" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // Process represents a managed external process. @@ -87,13 +89,13 @@ func (p *Process) Wait() error { p.mu.RLock() defer p.mu.RUnlock() if p.Status == StatusFailed { - return fmt.Errorf("process failed to start: %s", p.ID) + return coreerr.E("Process.Wait", fmt.Sprintf("process failed to start: %s", p.ID), nil) } if p.Status == StatusKilled { - return fmt.Errorf("process was killed: %s", p.ID) + return coreerr.E("Process.Wait", fmt.Sprintf("process was killed: %s", p.ID), nil) } if p.ExitCode != 0 { - return fmt.Errorf("process exited with code %d", p.ExitCode) + return coreerr.E("Process.Wait", fmt.Sprintf("process exited with code %d", p.ExitCode), nil) } return nil } diff --git a/runner.go b/runner.go index 8eb1fd5..61eed29 100644 --- a/runner.go +++ b/runner.go @@ -2,9 +2,10 @@ package process import ( "context" - "errors" "sync" "time" + + coreerr "forge.lthn.ai/core/go-log" ) // Runner orchestrates multiple processes with dependencies. @@ -104,7 +105,7 @@ func (r *Runner) RunAll(ctx context.Context, specs []RunSpec) (*RunAllResult, er Name: name, Spec: remaining[name], Skipped: true, - Error: errors.New("circular dependency or missing dependency"), + Error: coreerr.E("Runner.RunAll", "circular dependency or missing dependency", nil), }) } break @@ -136,7 +137,7 @@ func (r *Runner) RunAll(ctx context.Context, specs []RunSpec) (*RunAllResult, er Name: spec.Name, Spec: spec, Skipped: true, - Error: errors.New("skipped due to dependency failure"), + Error: coreerr.E("Runner.RunAll", "skipped due to dependency failure", nil), } } else { result = r.runSpec(ctx, spec) diff --git a/service.go b/service.go index 661dac9..461d0e1 100644 --- a/service.go +++ b/service.go @@ -13,6 +13,7 @@ import ( "time" "forge.lthn.ai/core/go/pkg/core" + coreerr "forge.lthn.ai/core/go-log" ) // Default buffer size for process output (1MB). @@ -20,9 +21,9 @@ const DefaultBufferSize = 1024 * 1024 // Errors var ( - ErrProcessNotFound = errors.New("process not found") - ErrProcessNotRunning = errors.New("process is not running") - ErrStdinNotAvailable = errors.New("stdin not available") + ErrProcessNotFound = coreerr.E("", "process not found", nil) + ErrProcessNotRunning = coreerr.E("", "process is not running", nil) + ErrStdinNotAvailable = coreerr.E("", "stdin not available", nil) ) // Service manages process execution with Core IPC integration. @@ -121,19 +122,19 @@ func (s *Service) StartWithOptions(ctx context.Context, opts RunOptions) (*Proce stdout, err := cmd.StdoutPipe() if err != nil { cancel() - return nil, fmt.Errorf("failed to create stdout pipe: %w", err) + return nil, coreerr.E("Service.StartWithOptions", "failed to create stdout pipe", err) } stderr, err := cmd.StderrPipe() if err != nil { cancel() - return nil, fmt.Errorf("failed to create stderr pipe: %w", err) + return nil, coreerr.E("Service.StartWithOptions", "failed to create stderr pipe", err) } stdin, err := cmd.StdinPipe() if err != nil { cancel() - return nil, fmt.Errorf("failed to create stdin pipe: %w", err) + return nil, coreerr.E("Service.StartWithOptions", "failed to create stdin pipe", err) } // Create output buffer (enabled by default) @@ -161,7 +162,7 @@ func (s *Service) StartWithOptions(ctx context.Context, opts RunOptions) (*Proce // Start the process if err := cmd.Start(); err != nil { cancel() - return nil, fmt.Errorf("failed to start process: %w", err) + return nil, coreerr.E("Service.StartWithOptions", "failed to start process", err) } // Store process @@ -327,7 +328,7 @@ func (s *Service) Remove(id string) error { } if proc.IsRunning() { - return errors.New("cannot remove running process") + return coreerr.E("Service.Remove", "cannot remove running process", nil) } delete(s.processes, id) @@ -367,7 +368,7 @@ func (s *Service) Run(ctx context.Context, command string, args ...string) (stri output := proc.Output() if proc.ExitCode != 0 { - return output, fmt.Errorf("process exited with code %d", proc.ExitCode) + return output, coreerr.E("Service.Run", fmt.Sprintf("process exited with code %d", proc.ExitCode), nil) } return output, nil } @@ -383,7 +384,7 @@ func (s *Service) RunWithOptions(ctx context.Context, opts RunOptions) (string, output := proc.Output() if proc.ExitCode != 0 { - return output, fmt.Errorf("process exited with code %d", proc.ExitCode) + return output, coreerr.E("Service.RunWithOptions", fmt.Sprintf("process exited with code %d", proc.ExitCode), nil) } return output, nil } From d955ffc0e7ac1bb13ceb1580faa397950b85c634 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 22:17:52 +0000 Subject: [PATCH 6/6] chore: sync dependencies for v0.2.7 Co-Authored-By: Virgil --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 4e5072c..d9ceace 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,11 @@ module forge.lthn.ai/core/go-process go 1.26.0 require ( - forge.lthn.ai/core/api v0.1.2 + forge.lthn.ai/core/api v0.1.3 forge.lthn.ai/core/go v0.3.1 - forge.lthn.ai/core/go-io v0.1.2 - forge.lthn.ai/core/go-log v0.0.2 - forge.lthn.ai/core/go-ws v0.2.0 + forge.lthn.ai/core/go-io v0.1.5 + forge.lthn.ai/core/go-log v0.0.4 + forge.lthn.ai/core/go-ws v0.2.2 github.com/gin-gonic/gin v1.12.0 github.com/stretchr/testify v1.11.1 ) diff --git a/go.sum b/go.sum index cfc0b77..7c4b511 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,13 @@ -forge.lthn.ai/core/api v0.1.2 h1:VKHOQhjWcNCG4Xf9lJfrABRwk/+1tp8YsdQzPNVxzek= -forge.lthn.ai/core/api v0.1.2/go.mod h1:vDkEihL/Cn1yKF8oA2jjf1CVOcd7kOP/WYWoIHIu2+E= +forge.lthn.ai/core/api v0.1.3 h1:iYmNP6zK5SiNRunYEsXPvjppTh3bQADkMyoCC8lEs48= +forge.lthn.ai/core/api v0.1.3/go.mod h1:dBOZc6DS0HdnTfCJZ8FkZxWJio2cIf0d1UrCAlDanrA= forge.lthn.ai/core/go v0.3.1 h1:5FMTsUhLcxSr07F9q3uG0Goy4zq4eLivoqi8shSY4UM= forge.lthn.ai/core/go v0.3.1/go.mod h1:gE6c8h+PJ2287qNhVUJ5SOe1kopEwHEquvinstpuyJc= -forge.lthn.ai/core/go-io v0.1.2 h1:q8hj2jtOFqAgHlBr5wsUAOXtaFkxy9gqGrQT/il0WYA= -forge.lthn.ai/core/go-io v0.1.2/go.mod h1:PbNKW1Q25ywSOoQXeGdQHbV5aiIrTXvHIQ5uhplA//g= -forge.lthn.ai/core/go-log v0.0.2 h1:zJEgbajs5AjvhYzsbyybzn+S2Titiv56r3BG5E1cNUo= -forge.lthn.ai/core/go-log v0.0.2/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw= -forge.lthn.ai/core/go-ws v0.2.0 h1:w1uG5MgUeGoWGu1hBh8liTXcsMJDrjvPGeIsg6fyvYk= -forge.lthn.ai/core/go-ws v0.2.0/go.mod h1:iDbJuR1NT27czjtNIluxnEdLrnfsYQdEBIrsoZnpkCk= +forge.lthn.ai/core/go-io v0.1.5 h1:+XJ1YhaGGFLGtcNbPtVlndTjk+pO0Ydi2hRDj5/cHOM= +forge.lthn.ai/core/go-io v0.1.5/go.mod h1:FRtXSsi8W+U9vewCU+LBAqqbIj3wjXA4dBdSv3SAtWI= +forge.lthn.ai/core/go-log v0.0.4 h1:KTuCEPgFmuM8KJfnyQ8vPOU1Jg654W74h8IJvfQMfv0= +forge.lthn.ai/core/go-log v0.0.4/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw= +forge.lthn.ai/core/go-ws v0.2.2 h1:hXhIJaTy7w/VxfIymeeHSHAN33YcvtITtfFcZ0DWL40= +forge.lthn.ai/core/go-ws v0.2.2/go.mod h1:+AwN/Am6KWZUDtY/RZaHjf51BwvSrwSHWIGiOrjSrV0= github.com/99designs/gqlgen v0.17.88 h1:neMQDgehMwT1vYIOx/w5ZYPUU/iMNAJzRO44I5Intoc= github.com/99designs/gqlgen v0.17.88/go.mod h1:qeqYFEgOeSKqWedOjogPizimp2iu4E23bdPvl4jTYic= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=