@ai-workbench/network 0.4.5 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +6 -0
- package/README.md +22 -6
- package/client/index.cjs +54 -0
- package/cordis.patch.yml +2 -0
- package/helpers/darwin-arm64/NOTICE.md +6 -0
- package/helpers/darwin-arm64/bin/aw-net +0 -0
- package/helpers/darwin-arm64/helper-manifest.json +1 -1
- package/helpers/darwin-arm64/licenses-manifest.json +160 -160
- package/helpers/darwin-arm64/package.json +1 -1
- package/helpers/darwin-x64/NOTICE.md +6 -0
- package/helpers/darwin-x64/bin/aw-net +0 -0
- package/helpers/darwin-x64/helper-manifest.json +1 -1
- package/helpers/darwin-x64/licenses-manifest.json +152 -152
- package/helpers/darwin-x64/package.json +1 -1
- package/lib/activation.js +76 -7
- package/lib/api.d.ts +3 -0
- package/lib/index.js +4 -1
- package/lib/network.d.ts +2 -1
- package/lib/network.js +59 -18
- package/lib/policy-management.d.ts +113 -0
- package/lib/policy-management.js +123 -0
- package/lib/settings-host.d.ts +3 -0
- package/lib/settings-host.js +12 -0
- package/lib/settings.d.ts +14 -2
- package/lib/settings.js +10 -1
- package/package.json +17 -2
|
@@ -778,21 +778,169 @@
|
|
|
778
778
|
"module": "golang.org/x/crypto@v0.57.0",
|
|
779
779
|
"package": "ssh/knownhosts"
|
|
780
780
|
},
|
|
781
|
+
{
|
|
782
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
783
|
+
"package": "pkg/gohacks"
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
787
|
+
"package": "pkg/sync"
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
791
|
+
"package": "pkg/state/wire"
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
795
|
+
"package": "pkg/state"
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
799
|
+
"package": "pkg/atomicbitops"
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
"module": "golang.org/x/exp@v0.0.0-20260908205506-85c1c2202aba",
|
|
803
|
+
"package": "constraints"
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
807
|
+
"package": "pkg/bits"
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
"module": "golang.org/x/time@v0.16.0",
|
|
811
|
+
"package": "rate"
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
815
|
+
"package": "pkg/linewriter"
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
819
|
+
"package": "pkg/log"
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
823
|
+
"package": "pkg/waiter"
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
827
|
+
"package": "pkg/context"
|
|
828
|
+
},
|
|
829
|
+
{
|
|
830
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
831
|
+
"package": "pkg/refs"
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
835
|
+
"package": "pkg/tcpip/checksum"
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
839
|
+
"package": "pkg/buffer"
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
843
|
+
"package": "pkg/rand"
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
847
|
+
"package": "pkg/tcpip"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
851
|
+
"package": "pkg/sync/locking"
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
855
|
+
"package": "pkg/tcpip/hash/jenkins"
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
859
|
+
"package": "pkg/tcpip/seqnum"
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
863
|
+
"package": "pkg/tcpip/header"
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
867
|
+
"package": "pkg/tcpip/ports"
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
871
|
+
"package": "pkg/tcpip/transport/tcpconntrack"
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
875
|
+
"package": "pkg/tcpip/stack"
|
|
876
|
+
},
|
|
781
877
|
{
|
|
782
878
|
"module": "Go go1.27.3",
|
|
783
|
-
"package": "src/
|
|
879
|
+
"package": "src/container/heap"
|
|
784
880
|
},
|
|
785
881
|
{
|
|
786
882
|
"module": "Go go1.27.3",
|
|
787
|
-
"package": "src/
|
|
883
|
+
"package": "src/container/list"
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
"module": "github.com/google/btree@v1.1.3",
|
|
887
|
+
"package": ""
|
|
888
|
+
},
|
|
889
|
+
{
|
|
890
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
891
|
+
"package": "pkg/sleep"
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
895
|
+
"package": "pkg/tcpip/header/parse"
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
899
|
+
"package": "pkg/tcpip/internal/tcp"
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
903
|
+
"package": "pkg/tcpip/transport"
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
907
|
+
"package": "pkg/tcpip/transport/internal/network"
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
911
|
+
"package": "pkg/tcpip/transport/internal/noop"
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
915
|
+
"package": "pkg/tcpip/transport/packet"
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
919
|
+
"package": "pkg/tcpip/transport/raw"
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
923
|
+
"package": "pkg/tcpip/transport/tcp"
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
927
|
+
"package": "pkg/tcpip/transport/udp"
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
931
|
+
"package": "pkg/tcpip/adapters/gonet"
|
|
788
932
|
},
|
|
789
933
|
{
|
|
790
934
|
"module": "Go go1.27.3",
|
|
791
|
-
"package": "src/compress/
|
|
935
|
+
"package": "src/compress/flate"
|
|
792
936
|
},
|
|
793
937
|
{
|
|
794
938
|
"module": "Go go1.27.3",
|
|
795
|
-
"package": "src/
|
|
939
|
+
"package": "src/hash/crc32"
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
"module": "Go go1.27.3",
|
|
943
|
+
"package": "src/compress/gzip"
|
|
796
944
|
},
|
|
797
945
|
{
|
|
798
946
|
"module": "Go go1.27.3",
|
|
@@ -1002,10 +1150,6 @@
|
|
|
1002
1150
|
"module": "tailscale.com@v1.104.1",
|
|
1003
1151
|
"package": "util/bufiox"
|
|
1004
1152
|
},
|
|
1005
|
-
{
|
|
1006
|
-
"module": "golang.org/x/exp@v0.0.0-20260908205506-85c1c2202aba",
|
|
1007
|
-
"package": "constraints"
|
|
1008
|
-
},
|
|
1009
1153
|
{
|
|
1010
1154
|
"module": "tailscale.com@v1.104.1",
|
|
1011
1155
|
"package": "util/mak"
|
|
@@ -1726,98 +1870,6 @@
|
|
|
1726
1870
|
"module": "github.com/tailscale/wireguard-go@v0.0.0-20260928213032-417aef361226",
|
|
1727
1871
|
"package": "device"
|
|
1728
1872
|
},
|
|
1729
|
-
{
|
|
1730
|
-
"module": "golang.org/x/time@v0.16.0",
|
|
1731
|
-
"package": "rate"
|
|
1732
|
-
},
|
|
1733
|
-
{
|
|
1734
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1735
|
-
"package": "pkg/gohacks"
|
|
1736
|
-
},
|
|
1737
|
-
{
|
|
1738
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1739
|
-
"package": "pkg/state/wire"
|
|
1740
|
-
},
|
|
1741
|
-
{
|
|
1742
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1743
|
-
"package": "pkg/state"
|
|
1744
|
-
},
|
|
1745
|
-
{
|
|
1746
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1747
|
-
"package": "pkg/sync"
|
|
1748
|
-
},
|
|
1749
|
-
{
|
|
1750
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1751
|
-
"package": "pkg/atomicbitops"
|
|
1752
|
-
},
|
|
1753
|
-
{
|
|
1754
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1755
|
-
"package": "pkg/bits"
|
|
1756
|
-
},
|
|
1757
|
-
{
|
|
1758
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1759
|
-
"package": "pkg/linewriter"
|
|
1760
|
-
},
|
|
1761
|
-
{
|
|
1762
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1763
|
-
"package": "pkg/log"
|
|
1764
|
-
},
|
|
1765
|
-
{
|
|
1766
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1767
|
-
"package": "pkg/waiter"
|
|
1768
|
-
},
|
|
1769
|
-
{
|
|
1770
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1771
|
-
"package": "pkg/context"
|
|
1772
|
-
},
|
|
1773
|
-
{
|
|
1774
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1775
|
-
"package": "pkg/refs"
|
|
1776
|
-
},
|
|
1777
|
-
{
|
|
1778
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1779
|
-
"package": "pkg/tcpip/checksum"
|
|
1780
|
-
},
|
|
1781
|
-
{
|
|
1782
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1783
|
-
"package": "pkg/buffer"
|
|
1784
|
-
},
|
|
1785
|
-
{
|
|
1786
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1787
|
-
"package": "pkg/rand"
|
|
1788
|
-
},
|
|
1789
|
-
{
|
|
1790
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1791
|
-
"package": "pkg/sync/locking"
|
|
1792
|
-
},
|
|
1793
|
-
{
|
|
1794
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1795
|
-
"package": "pkg/tcpip"
|
|
1796
|
-
},
|
|
1797
|
-
{
|
|
1798
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1799
|
-
"package": "pkg/tcpip/hash/jenkins"
|
|
1800
|
-
},
|
|
1801
|
-
{
|
|
1802
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1803
|
-
"package": "pkg/tcpip/seqnum"
|
|
1804
|
-
},
|
|
1805
|
-
{
|
|
1806
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1807
|
-
"package": "pkg/tcpip/header"
|
|
1808
|
-
},
|
|
1809
|
-
{
|
|
1810
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1811
|
-
"package": "pkg/tcpip/ports"
|
|
1812
|
-
},
|
|
1813
|
-
{
|
|
1814
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1815
|
-
"package": "pkg/tcpip/transport/tcpconntrack"
|
|
1816
|
-
},
|
|
1817
|
-
{
|
|
1818
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1819
|
-
"package": "pkg/tcpip/stack"
|
|
1820
|
-
},
|
|
1821
1873
|
{
|
|
1822
1874
|
"module": "tailscale.com@v1.104.1",
|
|
1823
1875
|
"package": "disco"
|
|
@@ -1842,10 +1894,6 @@
|
|
|
1842
1894
|
"module": "tailscale.com@v1.104.1",
|
|
1843
1895
|
"package": "types/netlogfunc"
|
|
1844
1896
|
},
|
|
1845
|
-
{
|
|
1846
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1847
|
-
"package": "pkg/tcpip/header/parse"
|
|
1848
|
-
},
|
|
1849
1897
|
{
|
|
1850
1898
|
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
1851
1899
|
"package": "pkg/tcpip/stack/gro"
|
|
@@ -2214,54 +2262,6 @@
|
|
|
2214
2262
|
"module": "tailscale.com@v1.104.1",
|
|
2215
2263
|
"package": "net/socks5"
|
|
2216
2264
|
},
|
|
2217
|
-
{
|
|
2218
|
-
"module": "Go go1.27.3",
|
|
2219
|
-
"package": "src/container/heap"
|
|
2220
|
-
},
|
|
2221
|
-
{
|
|
2222
|
-
"module": "github.com/google/btree@v1.1.3",
|
|
2223
|
-
"package": ""
|
|
2224
|
-
},
|
|
2225
|
-
{
|
|
2226
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2227
|
-
"package": "pkg/sleep"
|
|
2228
|
-
},
|
|
2229
|
-
{
|
|
2230
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2231
|
-
"package": "pkg/tcpip/internal/tcp"
|
|
2232
|
-
},
|
|
2233
|
-
{
|
|
2234
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2235
|
-
"package": "pkg/tcpip/transport"
|
|
2236
|
-
},
|
|
2237
|
-
{
|
|
2238
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2239
|
-
"package": "pkg/tcpip/transport/internal/network"
|
|
2240
|
-
},
|
|
2241
|
-
{
|
|
2242
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2243
|
-
"package": "pkg/tcpip/transport/internal/noop"
|
|
2244
|
-
},
|
|
2245
|
-
{
|
|
2246
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2247
|
-
"package": "pkg/tcpip/transport/packet"
|
|
2248
|
-
},
|
|
2249
|
-
{
|
|
2250
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2251
|
-
"package": "pkg/tcpip/transport/raw"
|
|
2252
|
-
},
|
|
2253
|
-
{
|
|
2254
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2255
|
-
"package": "pkg/tcpip/transport/tcp"
|
|
2256
|
-
},
|
|
2257
|
-
{
|
|
2258
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2259
|
-
"package": "pkg/tcpip/transport/udp"
|
|
2260
|
-
},
|
|
2261
|
-
{
|
|
2262
|
-
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2263
|
-
"package": "pkg/tcpip/adapters/gonet"
|
|
2264
|
-
},
|
|
2265
2265
|
{
|
|
2266
2266
|
"module": "gvisor.dev/gvisor@v0.0.0-20260915211658-a6f909f08a72",
|
|
2267
2267
|
"package": "pkg/tcpip/network/hash"
|
package/lib/activation.js
CHANGED
|
@@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { isAbsolute } from 'node:path';
|
|
3
3
|
import { createNetwork } from "./network.js";
|
|
4
4
|
import { fail, ok } from "./api.js";
|
|
5
|
-
import { settingsFields as fields, validHelperPolicy, mergedSettings } from "./settings.js";
|
|
5
|
+
import { settingsFields as fields, validHelperPolicy, validRecoveryPolicy, recoveryPolicy, mergedSettings } from "./settings.js";
|
|
6
6
|
import { createEmployeeEndpointController } from "./employee-endpoint.js";
|
|
7
7
|
function normalized(s) {
|
|
8
8
|
if (!s || typeof s !== 'object' || Object.keys(s).some(k => !fields.includes(k)))
|
|
@@ -14,7 +14,7 @@ function normalized(s) {
|
|
|
14
14
|
return;
|
|
15
15
|
if (!Number.isSafeInteger(s.controlResponseMaxBytes) || s.controlResponseMaxBytes <= 0 || !Number.isSafeInteger(s.downloadMaxRedirects) || s.downloadMaxRedirects < 0)
|
|
16
16
|
return;
|
|
17
|
-
if (!validHelperPolicy(s))
|
|
17
|
+
if (!validHelperPolicy(s) || !validRecoveryPolicy(s))
|
|
18
18
|
return;
|
|
19
19
|
return Object.fromEntries(fields.filter(k => s[k] !== undefined).map(k => [k, s[k]]));
|
|
20
20
|
}
|
|
@@ -23,6 +23,9 @@ export function createActivationService(initial, executable, emit = () => { }, f
|
|
|
23
23
|
let network = { phase: 'blocked', error: { code: 'SETTINGS_REQUIRED', message: '我需要导入连接资料。', needs: '在设置 → 远程主机连接 导入连接资料', actor: 'network' } };
|
|
24
24
|
let activation = { instanceId: randomUUID(), revision: 0, phase: 'unconfigured', receipt: null, error: network.error };
|
|
25
25
|
let runtime, selected, disposed = false, disposing, handoff, generation = 0, handedOff = false, consumerOnline = false;
|
|
26
|
+
let recoveryTimer, stableTimer, recovering;
|
|
27
|
+
let recoveryAttempts = 0, recoverAgain = false, handledFailure, lastFailure, policy = recoveryPolicy(initial);
|
|
28
|
+
const processFailures = new Set(['HELPER_EXITED', 'HELPER_PROCESS_FAILED', 'HELPER_START_FAILED', 'HELPER_STARTUP_EXPIRED']);
|
|
26
29
|
const listeners = new Set(), edges = new Set(), updates = new Set();
|
|
27
30
|
const snapshot = () => structuredClone(activation);
|
|
28
31
|
const employee = createEmployeeEndpointController({ getConnect, getRuntime: () => activation.phase === 'active' ? runtime : undefined, getState: () => network, connect: (target, signal) => api.connect(target, signal) });
|
|
@@ -72,7 +75,7 @@ export function createActivationService(initial, executable, emit = () => { }, f
|
|
|
72
75
|
return;
|
|
73
76
|
}
|
|
74
77
|
handedOff = true;
|
|
75
|
-
install(JSON.parse(selected));
|
|
78
|
+
install(JSON.parse(selected), true);
|
|
76
79
|
launch();
|
|
77
80
|
}).catch(() => observed({ phase: 'blocked', error: { code: 'HELPER_HANDOFF_FAILED', message: '网络身份交接失败,根因未查明。', needs: '保留身份并检查私有日志;不要重交密钥', actor: 'network' } }));
|
|
78
81
|
}
|
|
@@ -94,15 +97,77 @@ export function createActivationService(initial, executable, emit = () => { }, f
|
|
|
94
97
|
catch {
|
|
95
98
|
console.error('NETWORK_OBSERVER_FAILED');
|
|
96
99
|
}
|
|
100
|
+
if (next.phase === 'online') {
|
|
101
|
+
if (recoveryAttempts > 0 && !stableTimer) {
|
|
102
|
+
const ownGeneration = generation;
|
|
103
|
+
stableTimer = setTimeout(() => { stableTimer = undefined; if (!disposed && generation === ownGeneration && network.phase === 'online')
|
|
104
|
+
recoveryAttempts = 0; }, policy.helperRecoveryStableSeconds * 1000);
|
|
105
|
+
stableTimer.unref?.();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else if (stableTimer) {
|
|
109
|
+
clearTimeout(stableTimer);
|
|
110
|
+
stableTimer = undefined;
|
|
111
|
+
}
|
|
112
|
+
const resumable = current?.identity === 'resumable' && (current.cleanup === 'complete' || current.cleanup === 'not-required') && (current.session === 'identity' || handedOff);
|
|
113
|
+
if (next.error && processFailures.has(next.error.code) && resumable && runtime && handledFailure !== runtime) {
|
|
114
|
+
handledFailure = runtime;
|
|
115
|
+
lastFailure = next.error;
|
|
116
|
+
if (recovering || recoveryTimer)
|
|
117
|
+
recoverAgain = true;
|
|
118
|
+
else
|
|
119
|
+
scheduleRecovery(next.error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function recoveryState(error) {
|
|
123
|
+
const status = network.status ? { ...network.status, enrollment: 'error', host: { ...network.status.host, online: null, observedAt: null }, error } : undefined;
|
|
124
|
+
observed({ phase: error.code === 'HELPER_RECOVERING' ? 'starting' : 'blocked', ...status ? { status } : {}, error });
|
|
125
|
+
}
|
|
126
|
+
function scheduleRecovery(cause) {
|
|
127
|
+
if (disposed)
|
|
128
|
+
return;
|
|
129
|
+
const detail = [cause.code, cause.message, cause.cause].filter(Boolean).join(';');
|
|
130
|
+
if (recoveryAttempts >= policy.helperRecoveryMaxAttempts) {
|
|
131
|
+
recoveryState({ code: policy.helperRecoveryMaxAttempts === 0 ? 'HELPER_RECOVERY_DISABLED' : 'HELPER_RECOVERY_EXHAUSTED', message: policy.helperRecoveryMaxAttempts === 0 ? '网络组件意外退出;自动恢复已关闭。' : `网络组件连续恢复${recoveryAttempts}次仍未稳定,已停止自动恢复。`, needs: `请管理员检查网络组件退出日志与原身份;helperRecoveryMaxAttempts=${policy.helperRecoveryMaxAttempts},连续在线helperRecoveryStableSeconds=${policy.helperRecoveryStableSeconds}秒后才清零;排查后正常重载插件,不重交密钥。`, actor: 'network', cause: detail });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
recoveryAttempts++;
|
|
135
|
+
recoveryState({ code: 'HELPER_RECOVERING', message: `网络组件意外退出,正在第${recoveryAttempts}/${policy.helperRecoveryMaxAttempts}次恢复。`, needs: `等待helperRecoveryDelaySeconds=${policy.helperRecoveryDelaySeconds}秒后按原配置恢复;原连接已撤回,请在恢复后发起新操作,旧请求不会重放。`, actor: 'network', cause: detail });
|
|
136
|
+
if (disposed)
|
|
137
|
+
return;
|
|
138
|
+
recoveryTimer = setTimeout(() => {
|
|
139
|
+
recoveryTimer = undefined;
|
|
140
|
+
const owned = runtime;
|
|
141
|
+
generation++;
|
|
142
|
+
recovering = Promise.resolve().then(async () => {
|
|
143
|
+
await owned.dispose();
|
|
144
|
+
if (disposed)
|
|
145
|
+
return;
|
|
146
|
+
const error = owned.getState().error;
|
|
147
|
+
if (error) {
|
|
148
|
+
recoveryState({ ...error, cause: [error.cause, detail].filter(Boolean).join(';') });
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
install(JSON.parse(selected), true, owned.getRecoveryConfigSHA256?.());
|
|
152
|
+
await launch();
|
|
153
|
+
}).catch(() => recoveryState({ code: 'HELPER_RECOVERY_FAILED', message: '网络组件恢复未能完成,已停止自动恢复;根因未查明。', needs: '管理员检查私有日志、旧实例清理及安装状态;不启动第二个同身份实例,不重交密钥。', actor: 'network', cause: detail })).finally(() => {
|
|
154
|
+
recovering = undefined;
|
|
155
|
+
if (!disposed && recoverAgain) {
|
|
156
|
+
recoverAgain = false;
|
|
157
|
+
scheduleRecovery(lastFailure);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}, policy.helperRecoveryDelaySeconds * 1000);
|
|
161
|
+
recoveryTimer.unref?.();
|
|
97
162
|
}
|
|
98
|
-
function install(config) {
|
|
163
|
+
function install(config, resumeIdentityOnly = false, expectedConfigSHA256) {
|
|
99
164
|
const ownGeneration = ++generation;
|
|
100
165
|
runtime = factory(config, executable, next => { if (ownGeneration === generation)
|
|
101
|
-
observed(next); });
|
|
166
|
+
observed(next); }, undefined, resumeIdentityOnly, expectedConfigSHA256);
|
|
102
167
|
}
|
|
103
168
|
function launch() {
|
|
104
169
|
const owned = runtime, ownGeneration = generation;
|
|
105
|
-
|
|
170
|
+
return owned.start().then(() => {
|
|
106
171
|
if (!disposed && ownGeneration === generation && !network.error && !network.status?.receipt)
|
|
107
172
|
observed({ phase: 'blocked', error: { code: 'ENROLLMENT_RECEIPT_REQUIRED', message: '网络组件缺少消费确认。', needs: '管理员核对插件与helper版本', actor: 'network' } });
|
|
108
173
|
}).catch(() => { if (ownGeneration === generation)
|
|
@@ -129,6 +194,7 @@ export function createActivationService(initial, executable, emit = () => { }, f
|
|
|
129
194
|
return fail('ACTIVATION_CONFLICT', '已有连接激活,不能替换身份。', '管理员核对当前开通上下文');
|
|
130
195
|
if (!runtime) {
|
|
131
196
|
selected = key;
|
|
197
|
+
policy = recoveryPolicy(config);
|
|
132
198
|
install(config);
|
|
133
199
|
publish('activating', null);
|
|
134
200
|
if (!disposed)
|
|
@@ -152,12 +218,15 @@ export function createActivationService(initial, executable, emit = () => { }, f
|
|
|
152
218
|
async download(source, signal) { if (disposed)
|
|
153
219
|
return fail('DISPOSED', '网络服务已停止。', '重新加载插件'); return activation.phase === 'active' && runtime ? runtime.download(source, signal) : { ok: false, error: network.error ?? { code: 'NETWORK_NOT_READY', message: '连接尚未就绪。', needs: '等待N身份交接完成', actor: 'network' } }; },
|
|
154
220
|
dispose() { if (disposing)
|
|
155
|
-
return disposing; disposed = true;
|
|
221
|
+
return disposing; disposed = true; if (recoveryTimer)
|
|
222
|
+
clearTimeout(recoveryTimer); if (stableTimer)
|
|
223
|
+
clearTimeout(stableTimer); return disposing = Promise.resolve().then(async () => { publish('stopped', activation.error); try {
|
|
156
224
|
await employee.dispose();
|
|
157
225
|
}
|
|
158
226
|
finally {
|
|
159
227
|
await runtime?.dispose();
|
|
160
228
|
await handoff;
|
|
229
|
+
await recovering;
|
|
161
230
|
network = runtime?.getState() ?? { phase: 'stopped' };
|
|
162
231
|
emit(structuredClone(network));
|
|
163
232
|
publish('stopped', network.error ?? null);
|
package/lib/api.d.ts
CHANGED
|
@@ -129,6 +129,9 @@ export interface PluginSettings {
|
|
|
129
129
|
shutdownObservationSeconds?: number;
|
|
130
130
|
controlResponseMaxBytes?: number;
|
|
131
131
|
downloadMaxRedirects?: number;
|
|
132
|
+
helperRecoveryMaxAttempts?: number;
|
|
133
|
+
helperRecoveryDelaySeconds?: number;
|
|
134
|
+
helperRecoveryStableSeconds?: number;
|
|
132
135
|
statusRefreshIntervalSeconds?: number;
|
|
133
136
|
dialTimeoutSeconds?: number;
|
|
134
137
|
headerTimeoutSeconds?: number;
|
package/lib/index.js
CHANGED
|
@@ -12,13 +12,16 @@ export const Config = z.object({
|
|
|
12
12
|
shutdownObservationSeconds: positive().description('退出观察 shutdownObservationSeconds(秒):默认未设,沿开通值(现值10);等待自有组件正常退出,仅为可观测性;增大清理等更久,减小可能强制结束并报告;无关闭值,不终止未知进程'),
|
|
13
13
|
controlResponseMaxBytes: bytes().description('控制响应上限 controlResponseMaxBytes(字节):默认未设,沿开通值(现值65536);控制JSON、ready及代理首帧,也约束员工端点私有控制请求/响应和主机桥首帧;增大增加内存,减小可能拒绝合法帧;无关闭或无限值,不限制下载或SFTP正文'),
|
|
14
14
|
downloadMaxRedirects: z.number().step(1).min(0).max(Number.MAX_SAFE_INTEGER).description('下载重定向上限 downloadMaxRedirects:默认未设,沿开通值(现值3);增大允许更多HTTPS跳转,减小可能拒绝下载,0关闭跳转;不自动换源'),
|
|
15
|
+
helperRecoveryMaxAttempts: z.number().step(1).min(0).max(Number.MAX_SAFE_INTEGER).description('组件自动恢复次数 helperRecoveryMaxAttempts:默认3;仅复用已有身份恢复意外退出的自有helper,不重放SSH或模型请求。增大允许更多连续恢复,减小更早停止;0关闭自动恢复。次数耗尽停止并显示退出原因,需要管理员排查后正常重载插件;不重交密钥'),
|
|
16
|
+
helperRecoveryDelaySeconds: positive().description('组件恢复间隔 helperRecoveryDelaySeconds(秒):默认1;增大减少频繁拉起但恢复更慢,减小恢复更快且增加连续启动开销;无关闭值,关闭自动恢复请将helperRecoveryMaxAttempts设为0'),
|
|
17
|
+
helperRecoveryStableSeconds: positive().description('组件恢复计数清零 helperRecoveryStableSeconds(秒):默认60;连续在线达到此时长才清零。增大更严格识别反复崩溃,减小更快清零但可能把短暂在线当成稳定;无关闭值,不以刚收到ready立即清零'),
|
|
15
18
|
statusRefreshIntervalSeconds: positive().description('状态刷新间隔 statusRefreshIntervalSeconds(秒):默认沿已开通配置(现值2);影响组件状态查询及插件轮询;增大提示更迟,减小增加查询开销;无关闭值,不代表失败重试已修复'),
|
|
16
19
|
dialTimeoutSeconds: positive().description('拨号观察 dialTimeoutSeconds(秒):默认沿已开通配置(现值20);远端TCP/SSH、控制响应头、下载CONNECT/响应头;Node请求采用阶段空闲观察,仅为可观测性,增大等更久,减小可能提前中止;无关闭值,超时说明等待事项、已等时长、下一步检查,不是修复'),
|
|
17
20
|
headerTimeoutSeconds: z.number().min(1e-9).max(9223372036.854774).description('请求头观察 headerTimeoutSeconds(秒):默认沿已开通配置(现值10);本机控制与登录代理请求头;仅为可观测性,增大保留连接更久,减小可能拒绝慢请求头;无关闭值,超时在私有日志说明等待事项、已等时长、下一步检查'),
|
|
18
21
|
enrollmentObservationSeconds: z.number().min(1e-9).max(9223372036.854774).description('首次入网观察 enrollmentObservationSeconds(秒):默认沿已开通配置(现值30);仅观察首次开通结果,不用于删除已有身份;增大等更久,减小可能更早报未知;无关闭值,超时说明等待事项、已等时长、下一步检查,不重交开通材料'),
|
|
19
22
|
httpMaxHeaderBytes: bytes().description('本机HTTP头上限 httpMaxHeaderBytes(字节):默认沿已开通配置(现值1048576);控制/登录代理请求头及控制响应头;增大增加解析内存,减小可能拒绝合法头;无关闭或无限值,不是正文上限'),
|
|
20
23
|
httpMaxResponseHeaderBytes: bytes().description('下载HTTP响应头上限 httpMaxResponseHeaderBytes(字节):默认沿已开通配置(现值1048576);主机代理及下载响应头/CONNECT头;增大增加解析内存,减小可能拒绝合法头;无关闭或无限值,不是正文上限'),
|
|
21
|
-
}).description('运行策略优先级:本插件显式值 > 开通方传入值 >
|
|
24
|
+
}).description('运行策略优先级:本插件显式值 > 开通方传入值 > 原私有配置;既有策略未设置沿用原值。新增组件恢复策略未设时分别为3次/1秒/连续在线60秒,均在本页可改;不写回私有配置。活动连接改策略须正常重载插件,不重交开通材料。固定正确性约束不可关闭:macOS控制socket路径≤103字节、端口1–65535、计时器/整数可表示范围、私有700/600权限、当前用户与单身份隔离、SHA256及加密随机凭据强度。');
|
|
22
25
|
export function register(ctx, api) {
|
|
23
26
|
ctx.provide('aiWorkbenchNetwork', api);
|
|
24
27
|
ctx.effect(() => { void api.start(); return () => api.dispose(); });
|
package/lib/network.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface Executable {
|
|
|
7
7
|
platform: string;
|
|
8
8
|
arch: string;
|
|
9
9
|
}
|
|
10
|
-
export declare function createNetwork(settings: PluginSettings, executable: Executable, emit?: (state: NetworkState) => void, controlIO?: typeof control): NetworkChannels & EmployeeRuntime & {
|
|
10
|
+
export declare function createNetwork(settings: PluginSettings, executable: Executable, emit?: (state: NetworkState) => void, controlIO?: typeof control, resumeIdentityOnly?: boolean, expectedConfigSHA256?: string): NetworkChannels & EmployeeRuntime & {
|
|
11
11
|
start(): Promise<void>;
|
|
12
|
+
getRecoveryConfigSHA256?(): string | undefined;
|
|
12
13
|
};
|