2025-11-11 21:47:42

最近写了几个 VSCode 扩展,为了方便分发,上架了应用市场。由于 Code 主要分官方的和开源社区的 IDE,需要上架 VS Code Marketplace(微软官方扩展市场)和 Open VSX(VSCodium、Gitpod 等使用)
本文将手把手带你完成两个平台的发布流程,让你的扩展真正上线可用。
在正式发布之前,你需要确保扩展已经具备以下内容, 这个是示例参考比较简单:
{
"name": "cnb-welcome",
"publisher": "cnbcool",
"displayName": "cnb-welcome",
"description": "cnb welcome",
"version": "0.2.8",
"icon": "src/images/logo.png",
"engines": {
"vscode": "^1.89.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onStartupFinished"
],
"main": "./dist/extension.js",
"repository": {
"type": "git",
"url": "https://cnb.cool/cnb/cool/cnb-welcome.git"
},
"contributes": {
"commands": [
{
"command": "cnb.welcome",
"title": "CNB Welcome"
},
{
"command": "extension.openTerminal",
"title": "CNB Open Terminal"
},
{
"command": "extension.resetIsFirstRun",
"title": "CNB ResetIsFirstRun"
}
]
},
"scripts": {
"build": "vsce package",
"vscode:prepublish": "npm run package",
"compile": "webpack",
"watch": "webpack --watch",
"package": "webpack --mode production --devtool hidden-source-map",
"compile-tests": "tsc -p . --outDir out",
"watch-tests": "tsc -p . -w --outDir out",
"pretest": "npm run compile-tests && npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "vscode-test"
},
"devDependencies": {
"@types/mocha": "^10.0.6",
"@types/node": "18.x",
"@types/vscode": "^1.89.0",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
"@vscode/test-cli": "^0.0.9",
"@vscode/test-electron": "^2.3.9",
"eslint": "^8.57.0",
"file-loader": "^6.2.0",
"ts-loader": "^9.5.1",
"typescript": "^5.4.5",
"vsce": "^2.15.0",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
},
"license": "MIT",
"dependencies": {
"axios": "^1.9.0",
"handlebars": "^4.7.8"
}
}
npm install -g @vscode/vsce
# 打包扩展, 会生成一个 .vsix 文件
vsce package
npm install -g ovsx
官方文档 发布扩展 很详细,根据步骤来就可以。
vsce 只能使用个人访问令牌发布扩展,默认使用 Github 登录就可以。
访问 aex.dev.azure.com,反正跳过来跳过去,主要入口就是 Azure DevOps

随便选择一下 Project 进入,打开您的个人资料图片旁边的用户设置下拉菜单,然后选择个人访问令牌:

在创建新的个人访问令牌模式中,选择令牌的以下详细信息:

方便起见,我设置全部权限,最长有效期为 1 年。
妥善保管好生成 Token
访问设置 Visual Studio Marketplace 发布者管理页面
只需要填 ID 和 Name,不重复就行,我保持一样。
先登录,按提示输入 PAT
vsce login <publisher-ID>
当然可以先本地测试, 构建出 vsix 文件,本地安装
vsce package

发布
vsce publish
成功的日志大概如下:
INFO Publishing 'gaeaflow.gaeaflow-gitspace v1.0.1'...
INFO Extension URL (might take a few minutes): https://marketplace.visualstudio.com/items?itemName=gaeaflow.gaeaflow-gitspace
INFO Hub URL: https://marketplace.visualstudio.com/manage/publishers/gaeaflow/extensions/gaeaflow-gitspace/hub
DONE Published gaeaflow.gaeaflow-gitspace v1.0.1.
注册账号打开 Open VSX 通过 GitHub 登录就可以了, 需要签一个 VSX Publisher Agreement 申明才能创建 Namespaces
相对来说比较简单,我直接后台上传构建出 vsix 文件

需要两个扩展同步发布,以便官方和第三方 IDE 安装
如果有使用 harness(原 gitness)的 Gitspace 功能的,可以使用我提供的插件,也可以使用官方插件。需要设置环境变量 GITNESS_IDE_VSCODE_Plugin_Name=gaeaflow.gaeaflow-gitspace
可以在应用市场直接安装 GaeaFlow Gitspace
下次有时间说说如何集成 k8s gitspace 环境限定版
2025-11-03 22:46:29

为了方便同事接入 AI,也方便同事可以自主申请 AI 账号
New API 作为一款「新一代大模型网关与 AI 资产管理平台」,提供丰富的模型接入、接口管理、计费统计等功能,非常适合在 Kubernetes 集群中进行部署。本文带你一步步完成在 K8s 环境中的部署。
内部服务使用 Caddy 作为 Ingress 入口网关轻轻松松,顺便解决证书问题;使用 openkruise cloneset 管理,对标 Deployment
官方文档还是比较清晰的,不需要额外拓展。默认部署在 newapi 命名空间下
吐槽一下 Bitnami,博通收啥黄啥。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: redis
name: redis
namespace: newapi
spec:
storageClassName: nas-sc
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
---
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
labels:
app: redis
name: redis
namespace: newapi
spec:
replicas: 1
selector:
matchLabels:
app: redis
updateStrategy:
type: InPlaceIfPossible
template:
metadata:
labels:
app: redis
spec:
initContainers:
- name: volume-permissions
image: ccr.ccs.tencentyun.com/k7scn/os-shell:bitnami-latest
imagePullPolicy: "IfNotPresent"
command:
- /bin/bash
- -ec
- |
chown -R 1001:1001 /data
securityContext:
runAsUser: 0
seLinuxOptions: {}
resources:
limits:
cpu: 150m
ephemeral-storage: 2Gi
memory: 192Mi
requests:
cpu: 100m
ephemeral-storage: 50Mi
memory: 128Mi
volumeMounts:
- name: redis
mountPath: /data
containers:
- image: ccr.ccs.tencentyun.com/k7scn/redis:bitnami-8.2
imagePullPolicy: IfNotPresent
name: redis
env:
- name: REDIS_PASSWORD
value: da06b1fa13bc643ede15newapi8anewapiacfed04ac12e8bf5e6b78406d9
- name: REDIS_DISABLE_COMMANDS
value: FLUSHALL
ports:
- containerPort: 6379
protocol: TCP
resources:
requests:
cpu: 500m
memory: 512Mi
volumeMounts:
- mountPath: /bitnami/redis/data
name: redis
restartPolicy: Always
volumes:
- name: redis
persistentVolumeClaim:
claimName: redis
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: newapi
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
name: redis
本来打算用 bitnami 的 mysql 折腾了一下初始化有点问题换成官方的了
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: mysql
name: mysql
namespace: newapi
spec:
storageClassName: nas-sc
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
---
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
labels:
app: mysql
name: mysql
namespace: newapi
spec:
replicas: 1
selector:
matchLabels:
app: mysql
updateStrategy:
type: InPlaceIfPossible
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: ccr.ccs.tencentyun.com/k7scn/mysql:hub-8.4.7
imagePullPolicy: IfNotPresent
name: mysql
env:
- name: MYSQL_USER
value: newapi
- name: MYSQL_PASSWORD
value: da06b1fa13bc6syzede15f3860b8newapiacfed04ac12e8bf5e6b78406d9
- name: MYSQL_ROOT_PASSWORD
value: oaPei9xoh7shipimoom0zysAhnewapi7iDair7EVie1Va0ahth8eu3row
- name: MYSQL_DATABASE
value: newapi
ports:
- containerPort: 3306
protocol: TCP
resources:
requests:
cpu: 500m
memory: 512Mi
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql
restartPolicy: Always
volumes:
- name: mysql
persistentVolumeClaim:
claimName: mysql
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: newapi
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
name: mysql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: newapi
name: newapi
namespace: newapi
spec:
storageClassName: nas-sc
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
---
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
labels:
app: newapi
name: newapi
namespace: newapi
spec:
replicas: 1
selector:
matchLabels:
app: newapi
updateStrategy:
type: InPlaceIfPossible
template:
metadata:
labels:
app: newapi
spec:
containers:
- image: ccr.ccs.tencentyun.com/k7scn/new-api:v0.9.15-patch.2
imagePullPolicy: IfNotPresent
name: newapi
env:
- name: SQL_DSN
value: newapi:da06b1fa13bc6syzede15f3860b8newapiacfed04ac12e8bf5e6b78406d9@tcp(mysql.newapi.svc:3306)/newapi?charset=utf8mb4&parseTime=True&loc=Local
- name: REDIS_CONN_STRING
value: redis://default:da06b1fa13bc643ede15newapi8anewapiacfed04ac12e8bf5e6b78406d9@redis.newapi.svc:6379
- name: TZ
value: Asia/Shanghai
- name: ERROR_LOG_ENABLED
value: "true"
- name: BATCH_UPDATE_ENABLED
value: "true"
- name: SESSION_SECRET
value: newapi-zysHuuch3joF9doe8dooviequuth4ohf6
- name: CRYPTO_SECRET
value: newapi-xeiRic0beuPaeQu7eanech3nai6iasyz
- name: FRONTEND_BASE_URL
value: https://newapi.ysicing.cloud
ports:
- containerPort: 3000
protocol: TCP
resources:
requests:
cpu: 500m
memory: 512Mi
volumeMounts:
- mountPath: /data
subPath: data
name: newapi
- mountPath: /app/logs
subPath: logs
name: newapi
restartPolicy: Always
volumes:
- name: newapi
persistentVolumeClaim:
claimName: newapi
---
apiVersion: v1
kind: Service
metadata:
name: newapi
namespace: newapi
spec:
selector:
app: newapi
ports:
- port: 3000
targetPort: 3000
name: newapi
由于官方不支持 LDAP,暂时只能折中使用 OIDC 方式支持,username 是 sAMAccountName 还是 uid 根据 ladp 实际情况配置,正常只需要调整我打码的部分,Dex 还是很灵活的,官方文档也很齐全
---
kind: ConfigMap
apiVersion: v1
metadata:
name: dex
namespace: newapi
data:
dex.yaml: |
issuer: https://newapi.ysicing.cloud/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
staticClients:
- id: newapi
redirectURIs:
- "https://newapi.ysicing.cloud/oidc/callback"
name: "newapi"
secret: newapi-secret
connectors:
- type: ldap
id: ldap
name: "LDAP"
config:
host: "ldap.ysicing.cloud:389"
insecureNoSSL: true
startTLS: false
bindDN: "****隐藏****"
bindPW: "****隐藏****"
userSearch:
baseDN: "****隐藏****"
filter: "(objectClass=person)"
username: "sAMAccountName"
idAttr: "sAMAccountName"
emailAttr: "mail"
nameAttr: "cn"
---
# apiVersion: apps/v1
# kind: Deployment
apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
name: dex
namespace: newapi
labels:
app: dex
spec:
selector:
matchLabels:
app: dex
replicas: 1
updateStrategy:
type: InPlaceIfPossible
inPlaceUpdateStrategy:
gracePeriodSeconds: 10
template:
metadata:
labels:
app: dex
spec:
containers:
- name: dex
image: ccr.ccs.tencentyun.com/k7scn/dex
args:
- dex
- serve
- /etc/dex/dex.yaml
resources:
requests:
cpu: 100m
memory: 100Mi
livenessProbe:
tcpSocket:
port: 5556
initialDelaySeconds: 5
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
periodSeconds: 10
ports:
- containerPort: 5556
name: dex
volumeMounts:
- name: dex
mountPath: /etc/dex
volumes:
- name: dex
configMap:
name: dex
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: dex
namespace: newapi
spec:
selector:
app: dex
type: ClusterIP
ports:
- name: dex
protocol: TCP
port: 5556
targetPort: 5556
由于是复用之前的 Caddy,这里只列出 newapi.caddy 配置
newapi.ysicing.cloud {
@dex {
path /dex*
}
import LOG /var/log/caddy/newapi.ysicing.cloud.log
import COMCFG
import TLS
handle @dex {
reverse_proxy dex.newapi.svc.cluster.local:5556
}
reverse_proxy newapi.newapi.svc.cluster.local:3000
}
第一次访问,走安装向导即可。
开启 OIDC 登录,需要允许新用户注册,不然登录会失败

OIDC 配置页,只需要配置 3 个
- Well-Known URL: https://newapi.ysicing.cloud/dex/.well-known/openid-configuration
- Client ID: newapi
- Client Secret: newapi-secret
51
需要开启透传,还需要重写 UA, 请求头覆写
{
"User-Agent": "claude-cli/2.0.31 (external, cli)"
}
改完要记得保存 😂, 如果你的环境没要求,其实 compose 部署也比较简单
2025-11-01 11:52:44

我已经配置了,由于我的网络最近过于流畅没法体验,没有经过 peer relay 节点 😂,整体操作是没有问题,可以放心食用
在使用 Tailscale 的过程中,我们经常会遇到这样的问题:
上面的还需要依赖 DERP 中继,但是最近 Tailscale Peer Relay(对等中继)提供公开测试,
它允许你在自己的 Tailnet 中选一台网络条件好的节点,作为专属中继,让其他设备通过它转发流量,从而实现更快、更稳定的内网穿透体验。免费用户也可以有两个中继节点
一句话解释:
Peer Relay 是你自己控制的私有中继节点,它替代官方 DERP,为 Tailnet 内部节点中转加密流量。
这意味着你可以在靠近设备的地区部署中继,减少绕行路径,让连接速度更快。
具体可以查阅官方邮件公告 Introducing Tailscale Peer Relays
你需要:
如果 Debian 系安装 Tailscale 有问题可以参考 tailscale 部署加速
执行命令(以 UDP 44400 端口为例):
tailscale set --relay-server-port 44400
由于使用的腾讯云锐驰机器,还需要单独放行 UDP44400 端口,其他云也类似

完成后请确保:
这样,锐驰 A 就具备了中继能力
打开 Tailscale 管理后台,编辑 Access controls。
在 ACL 文件中添加以下配置:
在锐驰 A 上给它打上标签:
tailscale up --advertise-tags=tag:relay
然后在 Access Controls 中添加规则
{
"grants": [
{
"src": ["tag:mjj"],
"dst": ["tag:relay"],
"app": {
"tailscale.com/cap/relay": []
}
}
]
}
配置说明:
这种方式可扩展性最好。后续新增中继节点时,只需打上 tag:relay 即可自动生效。
我个人推荐使用,不建议使用 Tag,tag 标签功能会影响 tailscale file, 这个是我最常用功能之一。
如果你想让使用单个中继节点,可以写成:
"grants": [
{
"src": ["*"], // Devices that can be accessed through the peer relay
"dst": ["100.90.80.20"], // Devices functioning as peer relays for the src devices
"app": {
"tailscale.com/cap/relay": [], // The relay capability doesn't require any parameters
},
},
]

配置说明:
主要参考官方文档 kb/1591/peer-relays
tailscale ping <目标节点>
如果输出中出现 “via peer-relay”,表示连接确实经过中继节点。
找一台网络最好的节点,开启 Peer Relay, 让你的 Tailscale 网络快如闪电
2025-10-29 21:28:20

今天刷 L 站,发现好多人安利,由于跟风试试,感觉效果要比 GLM 要好
如果你是开发者、程序员,或者对 AI 辅助编码感兴趣,这个 MiniMax M2 + Claude Code 搭配绝对能让你眼前一亮。为什么?因为它不只性能强劲,还超级亲民:MiniMax M2 以 Claude Sonnet 8% 的价格,提供 2 倍速度,最近还限时免费!
本文大部分数据来源 L 站[MiniMax] M2 简单实战测评:Java 多模块 bug 修复、小项目生成,文档来源于官网。
官网使用手册很详细了,分国内站和国际站,总体没啥区别。


在不当人的某 A,确实 T0 级别,如果 Codex 能提提速也是不错的选择。
默认以国内站为示例,使用手机号注册,暂时好像不需要实名。
PS: 他们家短信验证码发送有点滞后,大概需要 20s 左右才能收到。
登录成功后访问接口密钥,或者下面这个地址
https://platform.minimaxi.com/user-center/basic-information/interface-key
创建密钥,记得保存后续留用。

官方文档也是很详细,这里简单说下。
默认已经安装了 Claude Code,或者参考如下安装
npm install -g @anthropic-ai/claude-code
Linux 配置 ~/.claude/settings.json
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.minimaxi.com/anthropic",
"ANTHROPIC_AUTH_TOKEN": "<需要替换为你申请的token>",
"API_TIMEOUT_MS": "3000000",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1,
"ANTHROPIC_MODEL": "MiniMax-M2",
"ANTHROPIC_SMALL_FAST_MODEL": "MiniMax-M2",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "MiniMax-M2",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "MiniMax-M2",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "MiniMax-M2"
}
}
macOS 我使用佬友写的 CCS(cc-switch)
配置大概如下所示

配置完成,可以直接开干。
MiniMax M2 模型 API 限时免费调用!活动截止时间:2025 年 11 月 7 日 上午 08:00
在 AI 浪潮下,MiniMax M2 的出现,让高性能编码工具不再是奢侈品。搭配 Claude Code,它不只适合专业开发者,也完美契合初学者。想体验普惠智能,现在就行动吧。最后在文尾安利一下 Zeus 的中转服务,让我实现了付费上班哈哈哈。
让我也吃一下 AFF
https://www.packyapi.com/register?aff=NnSl
2025-10-20 22:16:08

周末闲来无事,听说北京朝阳馆的茶博会正热火朝天地进行中(2025 北京国际秋季茶业交易博览会,从 10 月 16 日到 19 日,在中国国际展览中心朝阳馆举办),赶紧拉上茶友去转转。没想到这一逛,就是简单的一逛!今天就来给大家分享我的闲逛笔记,带你云游这场茶的盛宴
这是今年第三场茶博会了我记得没错的话,规格算比较小的了,11 月还有一场在国家会议中心,爱喝茶的可以约起来。
可圈可点,主要为云南福建等地区地方茶偏多。绿茶只有一家皖南的,茶香肆意,忘记名字了。皖南的名茶太多了,几乎每个市县都有自己的特色地方茶,这里打个广告安利一下我们的桐城小花,从小喝到大。不太好找,在珠宝展后面,问了几次路。
真是败笔,有个展馆入口是卖鱼干的(巧了不是,我比较不耐受这种味道)。然后选择先去看了茶具,由于地方不大,卖茶具的也不多,品质把玩了一下感觉还行。价格也不便宜,砍价也砍不动,只能看看摸摸上上手。

比较喜欢这种小杯子

目标价位 6-8 块,没砍下来哈哈哈
逛着逛着,我被一个云南地方茶茶摊吸引住了。摊主是个有点懵的小姐姐,别人都是焖好了茶等人,小姐姐直接给你现在开泡哈哈哈。
入坑的摊位
野不野生咱不知道,但是第一口入口挺特别的,回甘比较慢。湖南地方特色茶

第一次喝,后面也搜了一下
莓茶不含茶碱、咖啡因,饮后不会兴奋,能改善并提高睡眠质量,老少皆宜。莓茶所含活性黄酮能杀灭细菌,沏泡一周仍可饮用,不会变馊(nb)
摊位试了几杯,感觉还行。云南高黎问候品牌
老实说,买完出门就后悔了哈哈哈,感觉没刀好了高了。
哦,对了,只看到一个美女茶艺师哈哈哈。
总之,这次周末闲逛朝阳馆茶博会,从忙碌的工作中抽身,也挺好的。茶不只是一种饮品,更是生活态度。如果你也爱茶,不妨约下个月展会一起去转转!
2025-09-30 11:55:55

上周抽空将 GitHub Spec Kit 移植到了 code-pilot, 新的大型项目使用起来体验还不错,就是特别耗 token,不过今天有了转机了 Claude 4.5 发布了
这里不细说了,类似介绍的文章有很多,核心工作原理是让规范成为工程流程的中心。
git clone https://github.com/ysicing/code-pilot.git ~/.claude
cd .claude
cp CLAUDE.md.example CLAUDE.md
记得将模型从 Opus 切到推荐模型 Sonnet 4.5
/spec-kit:specify [你的需求]
# 澄清需求
/spec-kit:clarify
# 后面一直输入 继续 继续 继续 就可以了

新模型确实很能打,没有降智,还便宜。减少了阿谀奉承、欺骗、权力追求和鼓励妄想思维等相关行为

欢迎关注,可以看看我郑再打工每天都在折腾什么。