@magpie-community/opencode-zcode-auth 0.1.16 → 0.1.18

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.
Files changed (2) hide show
  1. package/index.mjs +48 -4
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -19,7 +19,7 @@
19
19
  import { createDecipheriv, createHash } from "node:crypto"
20
20
  import { existsSync, readFileSync, readdirSync } from "node:fs"
21
21
  import { arch, homedir, release, userInfo } from "node:os"
22
- import { join } from "node:path"
22
+ import { isAbsolute, join } from "node:path"
23
23
  import PROMPT from "./prompt.mjs"
24
24
 
25
25
  const PROVIDER = "zcode"
@@ -933,8 +933,28 @@ async function authorize(site, log) {
933
933
  // team's plan. An account signed in "as ZCode" reads them for every
934
934
  // request, so it follows ZCode's own sign-in, its renewed session and its
935
935
  // switches between plans, as magpie's built-in did (zcode.go zcodeOwn).
936
+ //
937
+ // ZCode 3.14 can move its data (数据存储路径, "data storage path"): it copies
938
+ // ~/.zcode/v2 to <folder>/.zcode/v2, all but setting.json, and from its next
939
+ // start reads credentials.json and runtime/provider from there. The choice
940
+ // stays in the home folder's setting.json as dataBaseDir, which ZCode's main
941
+ // process reads before anything else (readBootstrapDataBaseDirFromDisk);
942
+ // setting.json itself, and the team plan it names, stay in the home folder.
943
+
944
+ // settingDir is where ZCode keeps setting.json, moved or not.
945
+ const settingDir = () => join(homedir(), ".zcode", "v2")
946
+
947
+ // dataIn is the folder ZCode keeps its .zcode data in: the home folder,
948
+ // unless dataBaseDir moved it. A value that isn't an absolute path is
949
+ // ignored, as magpie's built-in does (internal/appdir ZCodeDataIn).
950
+ function dataIn() {
951
+ const d = readJSON(join(settingDir(), "setting.json"))?.dataBaseDir
952
+ const t = typeof d === "string" ? d.trim() : ""
953
+ return t && isAbsolute(t) ? t : homedir()
954
+ }
936
955
 
937
- const zcodeDir = () => join(homedir(), ".zcode", "v2")
956
+ // zcodeDir is where ZCode keeps credentials.json and runtime/provider.
957
+ const zcodeDir = () => join(dataIn(), ".zcode", "v2")
938
958
 
939
959
  // secret is the key ZCode encrypts its credentials with.
940
960
  function secret() {
@@ -974,7 +994,7 @@ function readJSON(path) {
974
994
 
975
995
  // ownTeam is the team plan ZCode switched to, when it did.
976
996
  function ownTeam(store, key) {
977
- const set = readJSON(join(zcodeDir(), "setting.json"))
997
+ const set = readJSON(join(settingDir(), "setting.json"))
978
998
  if (!set) return null
979
999
  const families = set.providerFamilyDomain === "zai" || set.providerFamilyDomain === "bigmodel" ? [set.providerFamilyDomain] : ["zai", "bigmodel"]
980
1000
  for (const fam of families) {
@@ -1006,6 +1026,27 @@ function ownTeam(store, key) {
1006
1026
  return null
1007
1027
  }
1008
1028
 
1029
+ // configKey is the coding plan key ZCode's config.json gives its built-in
1030
+ // coding plan provider, Z.ai's first, as ZCode lists them; ZCode reads it
1031
+ // as it is, and one written encrypted is read too.
1032
+ function configKey(key) {
1033
+ const providers = readJSON(join(zcodeDir(), "config.json"))?.provider
1034
+ if (!providers || typeof providers !== "object") return null
1035
+ for (const [ids, base] of [
1036
+ [["builtin:zai-coding-plan", "account:zai-individual-coding-plan"], ZAI_BASE],
1037
+ [["builtin:bigmodel-coding-plan", "account:bigmodel-individual-coding-plan"], BIGMODEL_BASE],
1038
+ ]) {
1039
+ for (const id of ids) {
1040
+ let k = providers[id]?.options?.apiKey
1041
+ if (typeof k !== "string") continue
1042
+ k = k.trim()
1043
+ if (k.startsWith("enc:")) k = first(decrypt(key, k))
1044
+ if (k.includes(".") && !/[\s{$]/.test(k)) return { key: k, base }
1045
+ }
1046
+ }
1047
+ return null
1048
+ }
1049
+
1009
1050
  // ownSignIn is what ZCode is signed in to now: the account, its coding
1010
1051
  // plan key, ZCode's session token (the Start Plan's key) and the team plan
1011
1052
  // it is switched to; null when it has none of them.
@@ -1023,6 +1064,9 @@ function ownSignIn() {
1023
1064
  // Z.ai's first, as ZCode lists it
1024
1065
  if (!s.key || (base === ZAI_BASE && s.base !== ZAI_BASE)) s = { key: k, base }
1025
1066
  }
1067
+ // ZCode 3.15 keeps no plan key in its credentials; the one it uses sits
1068
+ // in config.json, the provider's options.apiKey (yetone/magpie#2130)
1069
+ if (!s.key) s = configKey(key) || s
1026
1070
  const jwt = first(first(decrypt(key, store.zcodejwttoken)).replace(/^Bearer /, ""))
1027
1071
  const team = ownTeam(store, key)
1028
1072
  if (team) s = { ...team, jwt }
@@ -1139,7 +1183,7 @@ function modelsOf(cfg, plan) {
1139
1183
  // localConfig is the latest provider config an installed ZCode has.
1140
1184
  function localConfig() {
1141
1185
  const files = []
1142
- const rt = join(homedir(), ".zcode", "v2", "runtime", "provider")
1186
+ const rt = join(zcodeDir(), "runtime", "provider")
1143
1187
  const walk = (dir, depth) => {
1144
1188
  let es = []
1145
1189
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magpie-community/opencode-zcode-auth",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "OpenCode provider plugin: signs in to Z.ai's or BigModel's (智谱) GLM Coding Plan as ZCode does, including team seats and ZCode's Start Plan",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",