nolo-cli 0.204.0-alpha.3 → 0.205.0-alpha.2

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 (88) hide show
  1. package/{_executeModel-ZUESBV6T.js → _executeModel-U2XB3H4R.js} +17 -17
  2. package/{agentDeleteCommand-INOBZ3HP.js → agentDeleteCommand-PPB6JA5Y.js} +24 -24
  3. package/{agentEmailCommands-J6UTZBJC.js → agentEmailCommands-XHDV5OQ2.js} +26 -26
  4. package/{agentListCommands-6344UIVZ.js → agentListCommands-66ZCC36P.js} +16 -16
  5. package/{agentMachineCommands-TE6IRTIB.js → agentMachineCommands-XHM2USMU.js} +11 -11
  6. package/{agentProviderCommands-MEFUIECN.js → agentProviderCommands-SKW4L6NN.js} +2 -2
  7. package/{agentRecordCommands-34MHHVFX.js → agentRecordCommands-X5YU4AGX.js} +24 -24
  8. package/{agentRunCommand-7OMDQBRA.js → agentRunCommand-SINW3FLJ.js} +25 -25
  9. package/{agentRuntimeLocal-EO6WCTF2.js → agentRuntimeLocal-TLV4MITB.js} +9 -9
  10. package/{agentSlice-HUFGX25R.js → agentSlice-6XXGHTPP.js} +1 -1
  11. package/{appDeleteCommands-3DCLKVYC.js → appDeleteCommands-3WZVRCAN.js} +13 -13
  12. package/{appDeployCommands-X3MUBDOP.js → appDeployCommands-HQGQR2FV.js} +13 -13
  13. package/{appDeployStatusCommands-PXC3EHHS.js → appDeployStatusCommands-XWK7B6VD.js} +13 -13
  14. package/{appGetCommands-ETPPE6H7.js → appGetCommands-NR2SFXAG.js} +13 -13
  15. package/{appListCommands-OFIDLALN.js → appListCommands-UREKGWAC.js} +13 -13
  16. package/{authCommand-KPTIANH2.js → authCommand-NZC3H2EN.js} +62 -8
  17. package/{chromeOpsCommands-O4J346EQ.js → chromeOpsCommands-ECVS6CAO.js} +1 -1
  18. package/{chunk-YPYNRTWB.js → chunk-2GKUVGRT.js} +4 -4
  19. package/{chunk-77GDSGRM.js → chunk-3KUSLYEV.js} +31 -14
  20. package/{chunk-NGJWYWCF.js → chunk-4RERKW4Q.js} +5 -5
  21. package/{chunk-VXZ4YYNK.js → chunk-5EOHW7K3.js} +54 -39
  22. package/{chunk-33W4IFUU.js → chunk-5MXA4LWL.js} +1 -1
  23. package/{chunk-SXMTSDFS.js → chunk-5OJDQAJ2.js} +2 -2
  24. package/{chunk-E4KACSRR.js → chunk-5OV4MVQK.js} +2 -2
  25. package/{chunk-SZXJVQ7L.js → chunk-5XNUQGLF.js} +7 -7
  26. package/{chunk-IK6AAUGM.js → chunk-6AMR3AE6.js} +2 -2
  27. package/{chunk-QUJ3IHEK.js → chunk-767YOSGT.js} +2 -2
  28. package/{chunk-CJ37ZMCQ.js → chunk-7C45ONOU.js} +1 -1
  29. package/{chunk-RXX262QX.js → chunk-7LJEJV4F.js} +33 -6
  30. package/{chunk-CQHMBWZH.js → chunk-7NMNKOW5.js} +1 -1
  31. package/{chunk-EPJFGQYO.js → chunk-7T5TLIY4.js} +1 -1
  32. package/{chunk-266E37EL.js → chunk-CDGCIP2L.js} +3 -3
  33. package/{chunk-DQ7PCRZ6.js → chunk-DDERKP4L.js} +4 -4
  34. package/{chunk-UMIQZ7PX.js → chunk-DGCIYDMU.js} +4 -4
  35. package/{chunk-M43VXSMX.js → chunk-IAYMBPDZ.js} +2 -2
  36. package/{chunk-VCFU3BO5.js → chunk-JASKVAYJ.js} +2 -2
  37. package/{chunk-6I7ZP7KJ.js → chunk-JBWLZ3CB.js} +2 -2
  38. package/{chunk-SEEXRWNB.js → chunk-K7ZZPUNO.js} +27 -21
  39. package/{chunk-JH7KMNGT.js → chunk-L5FZUSB6.js} +2 -2
  40. package/{chunk-BC4UX4EZ.js → chunk-LDPZBAQK.js} +2 -2
  41. package/{chunk-G7RFM5QA.js → chunk-LKV5K7PW.js} +2 -2
  42. package/{chunk-4KPB3KWX.js → chunk-LTI5T3A6.js} +309 -82
  43. package/{chunk-MZXWSY4E.js → chunk-MNWKNN6V.js} +1 -1
  44. package/{chunk-3MXJWFLO.js → chunk-NUAQ3QHF.js} +1 -1
  45. package/{chunk-H7HWWNJB.js → chunk-PJILX6KS.js} +1 -1
  46. package/{chunk-E4LYPSYM.js → chunk-PPCUXO3E.js} +12 -0
  47. package/{chunk-KCYY5F2P.js → chunk-QSAUX2Q2.js} +2 -2
  48. package/{chunk-IZLXIV5L.js → chunk-SEOM7GLZ.js} +1 -1
  49. package/{chunk-6KWPMJ5C.js → chunk-TYKUYQDP.js} +6 -6
  50. package/{chunk-HAB2UDLT.js → chunk-W45PCJHS.js} +1 -1
  51. package/{chunk-P4YLK2OD.js → chunk-XNOILBHV.js} +1 -1
  52. package/{chunk-YR4MRACW.js → chunk-Y3ASVJWL.js} +3 -3
  53. package/{chunk-VEUSD6OF.js → chunk-YF4ZRVP3.js} +5 -1
  54. package/{chunk-JL3YTCPQ.js → chunk-YHT3ZONH.js} +2 -2
  55. package/{chunk-BER2RSTL.js → chunk-YJ6UWOO5.js} +2 -2
  56. package/{chunk-NTLJGRAT.js → chunk-YT65GYRP.js} +1 -1
  57. package/{chunk-HNO2SEYI.js → chunk-ZCKXJTCW.js} +8 -8
  58. package/{commandRegistry-XBZJWVTJ.js → commandRegistry-F5V2QBJ5.js} +59 -59
  59. package/{contentThunks-V5NBNTC5.js → contentThunks-IXBWQP4P.js} +3 -3
  60. package/{cooldownCommands-BLRMLW7Q.js → cooldownCommands-I4ETQ4AO.js} +3 -3
  61. package/{createAgentAutomationAction-4TXJ366P.js → createAgentAutomationAction-7O7PFPDO.js} +3 -3
  62. package/{createDialogAction-4SPT75DB.js → createDialogAction-DRHO4XCF.js} +4 -4
  63. package/{createPageAction-D4GMHUPC.js → createPageAction-TFGJRDZX.js} +3 -3
  64. package/{dialogCommands-6RRP5KUH.js → dialogCommands-X3GNU6DC.js} +13 -13
  65. package/{dialogSlice-IGPTWSPB.js → dialogSlice-CXIZ5UTI.js} +2 -2
  66. package/{docCreateCommands-7ODYDGRL.js → docCreateCommands-YDXECDNF.js} +12 -12
  67. package/{docDeleteCommands-OEIRM3CC.js → docDeleteCommands-DPMHSXK7.js} +13 -13
  68. package/{docReadCommands-W56GNAWP.js → docReadCommands-HH4TTBSR.js} +12 -12
  69. package/{docStore-HEAGW26W.js → docStore-5AHNSAEI.js} +1 -1
  70. package/{docUpdateCommands-33Q3SEG7.js → docUpdateCommands-74I6RA7U.js} +12 -12
  71. package/{handleSendMessageAction-R2E7VYHQ.js → handleSendMessageAction-SO3PD3YA.js} +10 -10
  72. package/index.js +7 -7
  73. package/{localRuntimeAdapter-J5GD66XZ.js → localRuntimeAdapter-5BG42C3L.js} +22 -22
  74. package/{machineCommands-AT7B4LFO.js → machineCommands-HOOU3DI7.js} +23 -23
  75. package/{machineWsRunDispatch-CRDELH46.js → machineWsRunDispatch-KUSLW2GE.js} +23 -23
  76. package/package.json +1 -1
  77. package/{providerPresetApply-HBBUUVJD.js → providerPresetApply-EQESXT6X.js} +1 -1
  78. package/{providerRegistry-5LK2NXYE.js → providerRegistry-PZ56P43E.js} +1 -1
  79. package/{readlineWorkspace-FPHZGNZP.js → readlineWorkspace-GBI2NFXY.js} +30 -30
  80. package/{runAgentClientLoop-6AAA5HNQ.js → runAgentClientLoop-ERVJ4LFY.js} +15 -15
  81. package/{secretCommands-S2DDPIQ4.js → secretCommands-RLIO3QK5.js} +1 -1
  82. package/{spaceCommands-LPKHBCPU.js → spaceCommands-SJJPZL7J.js} +11 -11
  83. package/{streamAgentChatTurn-WNNXYOLC.js → streamAgentChatTurn-2M4L7PF4.js} +19 -19
  84. package/{tools-QLURHFLS.js → tools-GINHFGST.js} +10 -10
  85. package/{tuiSummaryLlmCaller-73QO3HAD.js → tuiSummaryLlmCaller-CEIZAKUV.js} +4 -4
  86. package/{updateCommands-LEJRRVBB.js → updateCommands-N7K7TEU4.js} +3 -3
  87. package/{updateDialogTitleAction-5UVS3ADT.js → updateDialogTitleAction-4EIHKTKR.js} +3 -3
  88. package/{windowsSelfUpdate-LSSQLXVS.js → windowsSelfUpdate-SVJKL6VH.js} +2 -2
@@ -14,7 +14,7 @@ import {
14
14
  getAntigravityUserAgent,
15
15
  normalizeAntigravityTokenPayload,
16
16
  refreshAntigravityToken
17
- } from "./chunk-VEUSD6OF.js";
17
+ } from "./chunk-YF4ZRVP3.js";
18
18
  import {
19
19
  toErrorMessage
20
20
  } from "./chunk-HNMXYYJR.js";
@@ -844,6 +844,309 @@ var refreshOpenAiCodexToken2 = async (credential, deps = {}) => {
844
844
  });
845
845
  };
846
846
 
847
+ // packages/agent-runtime/anthropicClaudeCodeFingerprint.ts
848
+ var DEFAULT_CLAUDE_CODE_VERSION = "2.1.294";
849
+ var SEMVER_REGEX = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
850
+ var adoptedClaudeCodeVersion = null;
851
+ function parseSemver(v) {
852
+ const match = v.trim().match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/);
853
+ if (!match) return null;
854
+ return {
855
+ major: Number(match[1]),
856
+ minor: Number(match[2]),
857
+ patch: Number(match[3]),
858
+ prerelease: match[4]
859
+ };
860
+ }
861
+ function compareSemver(a, b) {
862
+ const parsedA = parseSemver(a);
863
+ const parsedB = parseSemver(b);
864
+ if (!parsedA || !parsedB) {
865
+ return a.localeCompare(b);
866
+ }
867
+ if (parsedA.major !== parsedB.major) return parsedA.major - parsedB.major;
868
+ if (parsedA.minor !== parsedB.minor) return parsedA.minor - parsedB.minor;
869
+ if (parsedA.patch !== parsedB.patch) return parsedA.patch - parsedB.patch;
870
+ if (!parsedA.prerelease && parsedB.prerelease) return 1;
871
+ if (parsedA.prerelease && !parsedB.prerelease) return -1;
872
+ if (!parsedA.prerelease && !parsedB.prerelease) return 0;
873
+ const partsA = parsedA.prerelease.split(".");
874
+ const partsB = parsedB.prerelease.split(".");
875
+ const maxLen = Math.max(partsA.length, partsB.length);
876
+ for (let i = 0; i < maxLen; i++) {
877
+ const pA = partsA[i];
878
+ const pB = partsB[i];
879
+ if (pA === void 0) return -1;
880
+ if (pB === void 0) return 1;
881
+ if (pA === pB) continue;
882
+ const numA = Number(pA);
883
+ const numB = Number(pB);
884
+ const aIsNum = Number.isInteger(numA) && String(numA) === pA;
885
+ const bIsNum = Number.isInteger(numB) && String(numB) === pB;
886
+ if (aIsNum && bIsNum) return numA - numB;
887
+ if (aIsNum && !bIsNum) return -1;
888
+ if (!aIsNum && bIsNum) return 1;
889
+ return pA.localeCompare(pB);
890
+ }
891
+ return 0;
892
+ }
893
+ function getEnvPinnedVersion(rawEnv) {
894
+ const envVal = rawEnv !== void 0 ? rawEnv : process.env.NOLO_CLAUDE_CODE_VERSION ?? process.env.CLAUDE_CODE_VERSION;
895
+ if (envVal === void 0) return void 0;
896
+ const trimmed = envVal.trim();
897
+ if (!trimmed) return void 0;
898
+ return SEMVER_REGEX.test(trimmed) ? trimmed : void 0;
899
+ }
900
+ function isClaudeCodeVersionEnvPinned() {
901
+ return getEnvPinnedVersion() !== void 0;
902
+ }
903
+ function resolveClaudeCodeVersion(rawEnv) {
904
+ const envPinned = getEnvPinnedVersion(rawEnv);
905
+ if (envPinned !== void 0) {
906
+ return envPinned;
907
+ }
908
+ return adoptedClaudeCodeVersion ?? DEFAULT_CLAUDE_CODE_VERSION;
909
+ }
910
+ function getClaudeCodeUserAgent() {
911
+ const version = resolveClaudeCodeVersion();
912
+ return `claude-cli/${version} (external, local-agent, agent-sdk/0.1.0)`;
913
+ }
914
+ function extractErrorText(error) {
915
+ if (typeof error === "string") return error;
916
+ if (!error) return "";
917
+ if (error instanceof Error) {
918
+ let s = `${error.name}: ${error.message}`;
919
+ const extra = error;
920
+ if (typeof extra.body === "string") s += " " + extra.body;
921
+ else if (extra.body && typeof extra.body === "object") {
922
+ try {
923
+ s += " " + JSON.stringify(extra.body);
924
+ } catch {
925
+ }
926
+ }
927
+ return s;
928
+ }
929
+ if (typeof error === "object") {
930
+ try {
931
+ return JSON.stringify(error);
932
+ } catch {
933
+ return String(error);
934
+ }
935
+ }
936
+ return String(error);
937
+ }
938
+ function adoptRequiredClaudeCodeVersion(error) {
939
+ if (isClaudeCodeVersionEnvPinned()) {
940
+ return false;
941
+ }
942
+ const text = extractErrorText(error);
943
+ if (!text) return false;
944
+ let requiredVersion = null;
945
+ if (typeof error === "object" && error !== null) {
946
+ const errObj = error;
947
+ const nested = errObj.error && typeof errObj.error === "object" ? errObj.error : errObj;
948
+ const hasTooOldCode = /claude_code_version_too_old/i.test(text);
949
+ const direct = nested.required_version ?? nested.requiredVersion ?? nested.minimum_version ?? nested.minVersion ?? (hasTooOldCode ? nested.version : void 0);
950
+ if (typeof direct === "string" && SEMVER_REGEX.test(direct.trim())) {
951
+ requiredVersion = direct.trim();
952
+ }
953
+ }
954
+ if (!requiredVersion) {
955
+ const phrase = text.match(/version\s+(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\s+or\s+(?:newer|above|higher)\s+is\s+required/i) ?? text.match(/(?:minimum|required)\s+version\s+(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/i);
956
+ if (phrase) requiredVersion = phrase[1];
957
+ }
958
+ if (!requiredVersion) return false;
959
+ const currentVersion = resolveClaudeCodeVersion();
960
+ if (compareSemver(requiredVersion, currentVersion) > 0) {
961
+ adoptedClaudeCodeVersion = requiredVersion;
962
+ return true;
963
+ }
964
+ return false;
965
+ }
966
+
967
+ // packages/agent-runtime/anthropicOAuth.ts
968
+ var ANTHROPIC_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
969
+ var ANTHROPIC_OAUTH_AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
970
+ var ANTHROPIC_OAUTH_TOKEN_URL = "https://api.anthropic.com/v1/oauth/token";
971
+ var ANTHROPIC_OAUTH_CALLBACK_PORT = 54545;
972
+ var ANTHROPIC_OAUTH_REDIRECT_URI = `http://localhost:${ANTHROPIC_OAUTH_CALLBACK_PORT}/callback`;
973
+ var ANTHROPIC_OAUTH_SCOPES = [
974
+ "org:create_api_key",
975
+ "user:profile",
976
+ "user:inference",
977
+ "user:sessions:claude_code",
978
+ "user:mcp_servers",
979
+ "user:file_upload"
980
+ ];
981
+ var ANTHROPIC_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
982
+ var ANTHROPIC_OAUTH_BETA = "oauth-2025-04-20";
983
+ var ANTHROPIC_BOOTSTRAP_URL = "https://api.anthropic.com/api/claude_cli/bootstrap";
984
+ var ANTHROPIC_OAUTH_GRANT_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
985
+ var ANTHROPIC_IDENTITY_RECHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
986
+ function anthropicGrantRemainingMs(credential, now = Date.now()) {
987
+ const rawGrantedAt = credential?.metadata?.grantedAt;
988
+ if (typeof rawGrantedAt !== "number" || !Number.isFinite(rawGrantedAt)) {
989
+ return void 0;
990
+ }
991
+ return rawGrantedAt + ANTHROPIC_OAUTH_GRANT_TTL_MS - now;
992
+ }
993
+ async function fetchAnthropicBootstrapIdentity(accessToken, fetchImpl = fetch, debugLog) {
994
+ if (!accessToken || typeof accessToken !== "string") {
995
+ return {};
996
+ }
997
+ try {
998
+ const response = await fetchImpl(ANTHROPIC_BOOTSTRAP_URL, {
999
+ method: "GET",
1000
+ headers: {
1001
+ Authorization: `Bearer ${accessToken.trim()}`,
1002
+ // UA 版本必须走 fingerprint 单一真源:400 自愈 adopt 新版本后,
1003
+ // 这里若自带一份 pin,就会继续发旧版本,上游抬门槛时身份回填会静默失效。
1004
+ "User-Agent": getClaudeCodeUserAgent(),
1005
+ Accept: "application/json"
1006
+ },
1007
+ signal: AbortSignal.timeout(1e4)
1008
+ });
1009
+ if (!response.ok) {
1010
+ debugLog?.(`Claude bootstrap identity returned HTTP ${response.status}`);
1011
+ return {};
1012
+ }
1013
+ const data = await response.json().catch(() => ({}));
1014
+ const account = data?.oauth_account;
1015
+ const identity = {};
1016
+ if (typeof account?.account_uuid === "string" && account.account_uuid.trim()) {
1017
+ identity.accountId = account.account_uuid.trim();
1018
+ }
1019
+ if (typeof account?.account_email === "string" && account.account_email.trim()) {
1020
+ identity.email = account.account_email.trim();
1021
+ }
1022
+ if (typeof account?.organization_uuid === "string" && account.organization_uuid.trim()) {
1023
+ identity.orgId = account.organization_uuid.trim();
1024
+ }
1025
+ if (typeof account?.organization_name === "string" && account.organization_name.trim()) {
1026
+ identity.orgName = account.organization_name.trim();
1027
+ }
1028
+ return identity;
1029
+ } catch (err) {
1030
+ debugLog?.("Claude bootstrap identity fetch failed", err);
1031
+ return {};
1032
+ }
1033
+ }
1034
+ function normalizeAnthropicTokenPayload(args) {
1035
+ const { payload, baseCredential, now = Date.now() } = args;
1036
+ if (typeof payload.access_token !== "string" || !payload.access_token.trim()) {
1037
+ throw new Error("Claude OAuth token response missing access_token");
1038
+ }
1039
+ const expiresIn = asOptionalFiniteNumber(payload.expires_in);
1040
+ const accountId = typeof payload.account?.uuid === "string" && payload.account.uuid ? payload.account.uuid : baseCredential?.accountId;
1041
+ const email = typeof payload.account?.email_address === "string" && payload.account.email_address ? payload.account.email_address : baseCredential?.metadata?.email;
1042
+ const organizationId = typeof payload.organization?.uuid === "string" && payload.organization.uuid ? payload.organization.uuid : baseCredential?.metadata?.organizationId;
1043
+ const organizationName = typeof payload.organization?.name === "string" && payload.organization.name ? payload.organization.name : baseCredential?.metadata?.organizationName;
1044
+ const refreshToken = typeof payload.refresh_token === "string" && payload.refresh_token.trim() ? payload.refresh_token.trim() : baseCredential?.refreshToken;
1045
+ const scope = typeof payload.scope === "string" && payload.scope ? payload.scope : baseCredential?.scope;
1046
+ const isInteractiveLogin = args.isInitialLogin ?? baseCredential === void 0;
1047
+ const grantedAt = isInteractiveLogin ? now : typeof baseCredential?.metadata?.grantedAt === "number" && Number.isFinite(baseCredential.metadata.grantedAt) ? baseCredential.metadata.grantedAt : void 0;
1048
+ const metadata = {
1049
+ ...baseCredential?.metadata ?? {},
1050
+ ...email ? { email } : {},
1051
+ ...organizationId ? { organizationId } : {},
1052
+ ...organizationName ? { organizationName } : {},
1053
+ ...grantedAt !== void 0 ? { grantedAt } : {}
1054
+ };
1055
+ return {
1056
+ ...baseCredential,
1057
+ provider: "claude",
1058
+ accessToken: payload.access_token.trim(),
1059
+ ...refreshToken ? { refreshToken } : {},
1060
+ ...expiresIn !== void 0 ? { expiresAt: now + expiresIn * 1e3 - ANTHROPIC_ACCESS_TOKEN_CLIENT_SKEW_MS } : baseCredential?.expiresAt !== void 0 ? { expiresAt: baseCredential.expiresAt } : {},
1061
+ ...scope ? { scope } : {},
1062
+ ...accountId ? { accountId } : {},
1063
+ ...Object.keys(metadata).length > 0 ? { metadata } : {},
1064
+ obtainedAt: now
1065
+ };
1066
+ }
1067
+ async function refreshAnthropicToken(credential, deps = {}) {
1068
+ if (!credential.refreshToken) {
1069
+ throw new Error("Claude credential has no refresh_token");
1070
+ }
1071
+ const fetchImpl = deps.fetchImpl ?? fetch;
1072
+ const now = deps.now?.() ?? Date.now();
1073
+ const warn = deps.warn ?? console.warn;
1074
+ const response = await fetchImpl(ANTHROPIC_OAUTH_TOKEN_URL, {
1075
+ method: "POST",
1076
+ headers: {
1077
+ "Content-Type": "application/json",
1078
+ "anthropic-beta": ANTHROPIC_OAUTH_BETA,
1079
+ "User-Agent": "nolo-cli userOAuthProvider"
1080
+ },
1081
+ body: JSON.stringify({
1082
+ grant_type: "refresh_token",
1083
+ client_id: ANTHROPIC_OAUTH_CLIENT_ID,
1084
+ refresh_token: credential.refreshToken
1085
+ }),
1086
+ signal: AbortSignal.timeout(3e4)
1087
+ });
1088
+ const payload = await response.json().catch(() => ({}));
1089
+ if (!response.ok) {
1090
+ throw classifyOAuthRefreshHttpFailure(response.status, payload, response.headers);
1091
+ }
1092
+ if (typeof payload.access_token !== "string" || !payload.access_token.trim()) {
1093
+ throw new OAuthRefreshError("bad_response");
1094
+ }
1095
+ const identityCheckedAt = asOptionalFiniteNumber(credential.metadata?.identityCheckedAt);
1096
+ const identityIncomplete = !credential.accountId || !credential.metadata?.email || !credential.metadata?.organizationId;
1097
+ const orgNameMissing = !credential.metadata?.organizationName;
1098
+ const identityStale = identityCheckedAt === void 0 || now - identityCheckedAt >= ANTHROPIC_IDENTITY_RECHECK_INTERVAL_MS;
1099
+ const shouldCheck = identityIncomplete || identityStale || orgNameMissing && identityStale;
1100
+ const bootstrap = shouldCheck ? await fetchAnthropicBootstrapIdentity(payload.access_token, fetchImpl) : {};
1101
+ const updatedMetadata = {
1102
+ ...credential.metadata ?? {}
1103
+ };
1104
+ if (shouldCheck) {
1105
+ updatedMetadata.identityCheckedAt = now;
1106
+ }
1107
+ if (bootstrap.accountId && bootstrap.accountId !== credential.accountId) {
1108
+ payload.account = { ...payload.account, uuid: bootstrap.accountId };
1109
+ }
1110
+ if (bootstrap.email && bootstrap.email !== credential.metadata?.email) {
1111
+ payload.account = { ...payload.account, email_address: bootstrap.email };
1112
+ updatedMetadata.email = bootstrap.email;
1113
+ }
1114
+ const existingOrgId = credential.metadata?.organizationId;
1115
+ if (!bootstrap.orgId) {
1116
+ delete payload.organization;
1117
+ }
1118
+ if (bootstrap.orgId) {
1119
+ if (existingOrgId && existingOrgId !== bootstrap.orgId) {
1120
+ updatedMetadata.previousOrgId = existingOrgId;
1121
+ updatedMetadata.orgChangedAt = now;
1122
+ warn(
1123
+ `[anthropicOAuth] \u7EC4\u7EC7\u5F52\u5C5E\u5DF2\u968F\u4E0A\u6E38 bootstrap \u53D8\u66F4: ${existingOrgId} -> ${bootstrap.orgId}`
1124
+ );
1125
+ }
1126
+ payload.organization = {
1127
+ ...payload.organization,
1128
+ uuid: bootstrap.orgId,
1129
+ ...bootstrap.orgName ? { name: bootstrap.orgName } : {}
1130
+ };
1131
+ updatedMetadata.organizationId = bootstrap.orgId;
1132
+ if (bootstrap.orgName) {
1133
+ updatedMetadata.organizationName = bootstrap.orgName;
1134
+ }
1135
+ }
1136
+ return normalizeAnthropicTokenPayload({
1137
+ payload,
1138
+ baseCredential: {
1139
+ ...credential,
1140
+ ...Object.keys(updatedMetadata).length > 0 ? { metadata: updatedMetadata } : { metadata: void 0 }
1141
+ },
1142
+ now,
1143
+ // 显式声明是刷新:grantedAt 必须沿用已存值,绝不因为「这次拿到了新 token」
1144
+ // 就把 30 天寿命重新起算——refresh 轮换不延长 grant 家族寿命。
1145
+ isInitialLogin: false
1146
+ });
1147
+ }
1148
+ var anthropicRefresh = refreshAnthropicToken;
1149
+
847
1150
  // packages/cli/oauth/serverSyncConfig.ts
848
1151
  function resolveServerSyncConfig() {
849
1152
  const envServer = process.env.NOLO_SERVER?.trim() || process.env.NOLO_SERVER_URL?.trim() || process.env.BASE_URL?.trim() || "";
@@ -1076,87 +1379,6 @@ async function refreshXaiToken(credential, deps = {}) {
1076
1379
  }
1077
1380
  var xaiRefresh = refreshXaiToken;
1078
1381
 
1079
- // packages/agent-runtime/anthropicOAuth.ts
1080
- var ANTHROPIC_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
1081
- var ANTHROPIC_OAUTH_AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
1082
- var ANTHROPIC_OAUTH_TOKEN_URL = "https://api.anthropic.com/v1/oauth/token";
1083
- var ANTHROPIC_OAUTH_CALLBACK_PORT = 54545;
1084
- var ANTHROPIC_OAUTH_REDIRECT_URI = `http://localhost:${ANTHROPIC_OAUTH_CALLBACK_PORT}/callback`;
1085
- var ANTHROPIC_OAUTH_SCOPES = [
1086
- "org:create_api_key",
1087
- "user:profile",
1088
- "user:inference",
1089
- "user:sessions:claude_code",
1090
- "user:mcp_servers",
1091
- "user:file_upload"
1092
- ];
1093
- var ANTHROPIC_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
1094
- var ANTHROPIC_OAUTH_BETA = "oauth-2025-04-20";
1095
- function normalizeAnthropicTokenPayload(args) {
1096
- const { payload, baseCredential, now = Date.now() } = args;
1097
- if (typeof payload.access_token !== "string" || !payload.access_token.trim()) {
1098
- throw new Error("Claude OAuth token response missing access_token");
1099
- }
1100
- const expiresIn = asOptionalFiniteNumber(payload.expires_in);
1101
- const accountId = typeof payload.account?.uuid === "string" && payload.account.uuid ? payload.account.uuid : baseCredential?.accountId;
1102
- const email = typeof payload.account?.email_address === "string" && payload.account.email_address ? payload.account.email_address : baseCredential?.metadata?.email;
1103
- const organizationId = typeof payload.organization?.uuid === "string" && payload.organization.uuid ? payload.organization.uuid : baseCredential?.metadata?.organizationId;
1104
- const organizationName = typeof payload.organization?.name === "string" && payload.organization.name ? payload.organization.name : baseCredential?.metadata?.organizationName;
1105
- const refreshToken = typeof payload.refresh_token === "string" && payload.refresh_token.trim() ? payload.refresh_token.trim() : baseCredential?.refreshToken;
1106
- const scope = typeof payload.scope === "string" && payload.scope ? payload.scope : baseCredential?.scope;
1107
- const metadata = {
1108
- ...baseCredential?.metadata ?? {},
1109
- ...email ? { email } : {},
1110
- ...organizationId ? { organizationId } : {},
1111
- ...organizationName ? { organizationName } : {}
1112
- };
1113
- return {
1114
- ...baseCredential,
1115
- provider: "claude",
1116
- accessToken: payload.access_token.trim(),
1117
- ...refreshToken ? { refreshToken } : {},
1118
- ...expiresIn !== void 0 ? { expiresAt: now + expiresIn * 1e3 - ANTHROPIC_ACCESS_TOKEN_CLIENT_SKEW_MS } : baseCredential?.expiresAt !== void 0 ? { expiresAt: baseCredential.expiresAt } : {},
1119
- ...scope ? { scope } : {},
1120
- ...accountId ? { accountId } : {},
1121
- ...Object.keys(metadata).length > 0 ? { metadata } : {},
1122
- obtainedAt: now
1123
- };
1124
- }
1125
- async function refreshAnthropicToken(credential, deps = {}) {
1126
- if (!credential.refreshToken) {
1127
- throw new Error("Claude credential has no refresh_token");
1128
- }
1129
- const fetchImpl = deps.fetchImpl ?? fetch;
1130
- const response = await fetchImpl(ANTHROPIC_OAUTH_TOKEN_URL, {
1131
- method: "POST",
1132
- headers: {
1133
- "Content-Type": "application/json",
1134
- "anthropic-beta": ANTHROPIC_OAUTH_BETA,
1135
- "User-Agent": "nolo-cli userOAuthProvider"
1136
- },
1137
- body: JSON.stringify({
1138
- grant_type: "refresh_token",
1139
- client_id: ANTHROPIC_OAUTH_CLIENT_ID,
1140
- refresh_token: credential.refreshToken
1141
- }),
1142
- signal: AbortSignal.timeout(3e4)
1143
- });
1144
- const payload = await response.json().catch(() => ({}));
1145
- if (!response.ok) {
1146
- throw classifyOAuthRefreshHttpFailure(response.status, payload, response.headers);
1147
- }
1148
- if (typeof payload.access_token !== "string" || !payload.access_token.trim()) {
1149
- throw new OAuthRefreshError("bad_response");
1150
- }
1151
- const now = deps.now?.() ?? Date.now();
1152
- return normalizeAnthropicTokenPayload({
1153
- payload,
1154
- baseCredential: credential,
1155
- now
1156
- });
1157
- }
1158
- var anthropicRefresh = refreshAnthropicToken;
1159
-
1160
1382
  // packages/agent-runtime/cursorOAuth.ts
1161
1383
  var CURSOR_LOGIN_URL = "https://cursor.com/loginDeepControl";
1162
1384
  var CURSOR_POLL_URL = "https://api2.cursor.sh/auth/poll";
@@ -1246,6 +1468,9 @@ async function refreshCursorToken(credential, deps = {}) {
1246
1468
  var cursorRefresh = refreshCursorToken;
1247
1469
 
1248
1470
  export {
1471
+ resolveClaudeCodeVersion,
1472
+ getClaudeCodeUserAgent,
1473
+ adoptRequiredClaudeCodeVersion,
1249
1474
  startCallbackServer,
1250
1475
  runAntigravityOAuthLogin,
1251
1476
  refreshAntigravityOAuthToken,
@@ -1277,6 +1502,8 @@ export {
1277
1502
  ANTHROPIC_OAUTH_CALLBACK_PORT,
1278
1503
  ANTHROPIC_OAUTH_REDIRECT_URI,
1279
1504
  ANTHROPIC_OAUTH_SCOPES,
1505
+ anthropicGrantRemainingMs,
1506
+ fetchAnthropicBootstrapIdentity,
1280
1507
  normalizeAnthropicTokenPayload,
1281
1508
  anthropicRefresh,
1282
1509
  CURSOR_LOGIN_URL,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveAgentImageInputSupport
3
- } from "./chunk-6I7ZP7KJ.js";
3
+ } from "./chunk-JBWLZ3CB.js";
4
4
  import {
5
5
  TOOL_HAD_IMAGES,
6
6
  hadToolImages
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-NBTY7YJF.js";
6
6
  import {
7
7
  resolveCliLocalRuntimeKeyCapability
8
- } from "./chunk-SEEXRWNB.js";
8
+ } from "./chunk-K7ZZPUNO.js";
9
9
  import {
10
10
  HIGH_RISK_MUTATION_TOOL_NAMES
11
11
  } from "./chunk-2Q3LOAFE.js";
@@ -2,7 +2,7 @@ import {
2
2
  deleteDbRecord,
3
3
  queryUserRecords,
4
4
  readDbRecord
5
- } from "./chunk-CJ37ZMCQ.js";
5
+ } from "./chunk-7C45ONOU.js";
6
6
  import {
7
7
  mergeAndDedupUserData
8
8
  } from "./chunk-OXME3PEE.js";
@@ -913,6 +913,18 @@ var authStrings = {
913
913
  "auth.envUpdated": {
914
914
  en: "[nolo] Updated {0} with CLOUDFLARE_EMAIL_ROUTING_API_TOKEN.",
915
915
  zh: "[nolo] \u5DF2\u66F4\u65B0 {0} \u91CC\u7684 CLOUDFLARE_EMAIL_ROUTING_API_TOKEN\u3002"
916
+ },
917
+ "auth.claudeGrantExpired": {
918
+ en: "[nolo] Claude OAuth grant has expired. Interactive login is required (run: nolo auth claude).",
919
+ zh: "[nolo] Claude OAuth grant \u5DF2\u8FC7\u671F\uFF0C\u5FC5\u987B\u91CD\u65B0\u4EA4\u4E92\u5F0F\u767B\u5F55\uFF08\u8FD0\u884C\uFF1Anolo auth claude\uFF09\u3002"
920
+ },
921
+ "auth.claudeGrantExpiringSoon": {
922
+ en: "[nolo] Claude OAuth grant expires in {0} day(s). Re-authenticate soon with: nolo auth claude.",
923
+ zh: "[nolo] Claude OAuth grant \u5C06\u5728 {0} \u5929\u5185\u8FC7\u671F\uFF0C\u8BF7\u5C3D\u5FEB\u91CD\u65B0\u767B\u5F55\uFF1Anolo auth claude\u3002"
924
+ },
925
+ "auth.claudeGrantValidDays": {
926
+ en: "[nolo] Claude OAuth grant valid for about {0} day(s).",
927
+ zh: "[nolo] Claude OAuth grant \u9884\u8BA1\u8FD8\u5269\u7EA6 {0} \u5929\u6709\u6548\u3002"
916
928
  }
917
929
  };
918
930
 
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-RXUKDHS5.js";
17
17
  import {
18
18
  fetchAndCacheTableRows
19
- } from "./chunk-IZLXIV5L.js";
19
+ } from "./chunk-SEOM7GLZ.js";
20
20
  import {
21
21
  createSpaceKey
22
22
  } from "./chunk-UAD2WT54.js";
@@ -783,7 +783,7 @@ var executeToolRun = createAsyncThunk(
783
783
  if (!executionInput) {
784
784
  throw new Error(`ToolRun ${id} has no input to execute with.`);
785
785
  }
786
- const { findToolExecutor } = await import("./tools-QLURHFLS.js");
786
+ const { findToolExecutor } = await import("./tools-GINHFGST.js");
787
787
  const { executor } = findToolExecutor(run.toolName);
788
788
  toolRunStarted({
789
789
  id: run.id,
@@ -7,7 +7,7 @@ import {
7
7
  deleteDialog,
8
8
  runtime_default,
9
9
  toast
10
- } from "./chunk-HNO2SEYI.js";
10
+ } from "./chunk-ZCKXJTCW.js";
11
11
  import {
12
12
  UNCATEGORIZED_ID,
13
13
  addContentAction,
@@ -2,7 +2,7 @@ import {
2
2
  DEVIN_CONNECT_URL,
3
3
  parseSseDataLineJson,
4
4
  parseSseDataLineObject
5
- } from "./chunk-VCFU3BO5.js";
5
+ } from "./chunk-JASKVAYJ.js";
6
6
  import {
7
7
  applyChatCompletionDelta,
8
8
  applyResponsesToolEvent,
@@ -11,7 +11,7 @@ import {
11
11
  flushChatCompletionStream,
12
12
  providerHttpFailure,
13
13
  throwIfChatCompletionStreamFailed
14
- } from "./chunk-CQHMBWZH.js";
14
+ } from "./chunk-7NMNKOW5.js";
15
15
  import {
16
16
  readSseFrames
17
17
  } from "./chunk-HNUWUO75.js";
@@ -29,7 +29,7 @@ import {
29
29
  import {
30
30
  hasImageInRuntimeMessages,
31
31
  stripImagePartsFromMessages
32
- } from "./chunk-MZXWSY4E.js";
32
+ } from "./chunk-MNWKNN6V.js";
33
33
  import {
34
34
  clipToolText,
35
35
  resolveHistoricalToolContentCap,
@@ -38,7 +38,7 @@ import {
38
38
  import {
39
39
  resolveAgentImageInputSupport,
40
40
  resolveToolImagePolicy
41
- } from "./chunk-6I7ZP7KJ.js";
41
+ } from "./chunk-JBWLZ3CB.js";
42
42
  import {
43
43
  applyShapingCounts,
44
44
  attachProjectionFacts,
@@ -73,7 +73,7 @@ import {
73
73
  hashStablePrefixContent,
74
74
  resolveResponseGuidelines,
75
75
  resolveToolGuidedSections
76
- } from "./chunk-IK6AAUGM.js";
76
+ } from "./chunk-6AMR3AE6.js";
77
77
  import {
78
78
  classifyUnparsableToolArgs,
79
79
  collectStablePromptPrefix,
@@ -16060,7 +16060,7 @@ function buildTaskStopTool() {
16060
16060
  type: "function",
16061
16061
  function: {
16062
16062
  name: "taskStop",
16063
- description: 'Stop a background task: SIGTERM to its process group, then SIGKILL if it is still alive after a short grace window. Returns {outcome, status, signal, escalated}: outcome "stopped" with status "stopped" on success, or outcome "not-stoppable" (already finished, or a foreground command that is not a background task) or "not-found". Never reports success without signalling.',
16063
+ description: 'Stop a background task: SIGTERM to its process group, then SIGKILL if it is still alive after a short grace window. Returns {outcome, status, signal, escalated}: outcome "stopped" with status "stopped" on success, or outcome "not-stoppable" (already finished, or a foreground command that is not a background task) or "not-found". Never reports success without signalling. Note: taskId is the handle returned by launchProcess or a detached execShell result (e.g. "ptask-..."). To stop an agent run, use controlAgentRun(action: "stop", runId: "...") instead; do not pass runId or empty strings to taskStop.',
16064
16064
  parameters: {
16065
16065
  type: "object",
16066
16066
  properties: {
@@ -2,7 +2,7 @@ import {
2
2
  mergeAvailabilityDeadline,
3
3
  resolveCredentialCandidateKeys,
4
4
  resolveCredentialKeyWithFallback
5
- } from "./chunk-RXX262QX.js";
5
+ } from "./chunk-7LJEJV4F.js";
6
6
 
7
7
  // packages/agent-runtime/credentialAvailability.ts
8
8
  import { homedir } from "node:os";
@@ -5,7 +5,7 @@ import {
5
5
  ANTIGRAVITY_CLOUD_CODE_BASE_URL,
6
6
  isAntigravityCloudCodeBaseUrl,
7
7
  isAntigravityOAuthAgent
8
- } from "./chunk-VEUSD6OF.js";
8
+ } from "./chunk-YF4ZRVP3.js";
9
9
  import {
10
10
  isOpenAiResponsesModel,
11
11
  resolvePlatformChatCompletionsEndpoint,
@@ -458,7 +458,7 @@ var slice = createSliceWithThunks({
458
458
  const overrides = {};
459
459
  if (args.systemPromptOverride !== void 0) overrides.prompt = args.systemPromptOverride;
460
460
  if (args.toolsOverride !== void 0) overrides.tools = args.toolsOverride;
461
- const { _executeModel } = await import("./_executeModel-ZUESBV6T.js");
461
+ const { _executeModel } = await import("./_executeModel-U2XB3H4R.js");
462
462
  return _executeModel(
463
463
  {
464
464
  isStreaming: args.isStreaming ?? false,
@@ -479,7 +479,7 @@ var slice = createSliceWithThunks({
479
479
  * - 循环直到无工具调用或触发其他运行时停止条件
480
480
  */
481
481
  runAgent: create.asyncThunk(async (args, thunkApi) => {
482
- const { runAgentClientLoop } = await import("./runAgentClientLoop-6AAA5HNQ.js");
482
+ const { runAgentClientLoop } = await import("./runAgentClientLoop-ERVJ4LFY.js");
483
483
  const { content: loopContent, toolCallCount } = await runAgentClientLoop(
484
484
  {
485
485
  agentKey: args.agentKey,
@@ -495,7 +495,7 @@ var slice = createSliceWithThunks({
495
495
  * 聊天轮次流式 Agent 调用
496
496
  */
497
497
  streamAgentChatTurn: create.asyncThunk(async (args, thunkApi) => {
498
- const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-WNNXYOLC.js");
498
+ const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-2M4L7PF4.js");
499
499
  return streamAgentChatTurnHandler(args, thunkApi);
500
500
  }),
501
501
  /**
@@ -50,7 +50,11 @@ var ANTIGRAVITY_SCOPES = [
50
50
  "https://www.googleapis.com/auth/userinfo.email",
51
51
  "https://www.googleapis.com/auth/userinfo.profile",
52
52
  "https://www.googleapis.com/auth/cclog",
53
- "https://www.googleapis.com/auth/experimentsandconfigs"
53
+ "https://www.googleapis.com/auth/experimentsandconfigs",
54
+ // Antigravity 的「附加模型」(Claude / GPT-OSS 经其代理)需要这个 scope;
55
+ // 对齐 oh-my-pi 的 google-antigravity 授权范围。只影响**新登录**:老凭据没有它
56
+ // 也能继续用 Gemini,不强制重新授权。
57
+ "https://www.googleapis.com/auth/aicode"
54
58
  ];
55
59
  var ANTIGRAVITY_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
56
60
  var ANTIGRAVITY_TOKEN_REQUEST_TIMEOUT_MS = 3e4;
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  requireTokenUser
3
- } from "./chunk-NTLJGRAT.js";
3
+ } from "./chunk-YT65GYRP.js";
4
4
  import {
5
5
  resolveServerUrl
6
6
  } from "./chunk-WACI5I6V.js";
7
7
  import {
8
8
  t
9
- } from "./chunk-E4LYPSYM.js";
9
+ } from "./chunk-PPCUXO3E.js";
10
10
 
11
11
  // packages/cli/cliApiClient.ts
12
12
  var CliApiError = class extends Error {
@@ -2,7 +2,7 @@ import {
2
2
  clipMultilineText,
3
3
  fetchAndSerializeTable,
4
4
  waitForAbortableDelay
5
- } from "./chunk-KCYY5F2P.js";
5
+ } from "./chunk-QSAUX2Q2.js";
6
6
  import {
7
7
  isGatewayHttpStatus
8
8
  } from "./chunk-NF64D32W.js";
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-AGIM7IMJ.js";
22
22
  import {
23
23
  fetchAndCacheMessages
24
- } from "./chunk-HNO2SEYI.js";
24
+ } from "./chunk-ZCKXJTCW.js";
25
25
  import {
26
26
  createSpaceKey
27
27
  } from "./chunk-UAD2WT54.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  readDbRecord,
3
3
  writeAgentRecord
4
- } from "./chunk-CJ37ZMCQ.js";
4
+ } from "./chunk-7C45ONOU.js";
5
5
  import {
6
6
  buildSkillSummaryMarker
7
7
  } from "./chunk-VF4K2QE6.js";