episoda 0.2.81 → 0.2.83
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.
|
@@ -2748,7 +2748,7 @@ var require_package = __commonJS({
|
|
|
2748
2748
|
"package.json"(exports2, module2) {
|
|
2749
2749
|
module2.exports = {
|
|
2750
2750
|
name: "episoda",
|
|
2751
|
-
version: "0.2.
|
|
2751
|
+
version: "0.2.83",
|
|
2752
2752
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
2753
2753
|
main: "dist/index.js",
|
|
2754
2754
|
types: "dist/index.d.ts",
|
|
@@ -4952,6 +4952,297 @@ var import_child_process8 = require("child_process");
|
|
|
4952
4952
|
var path9 = __toESM(require("path"));
|
|
4953
4953
|
var fs8 = __toESM(require("fs"));
|
|
4954
4954
|
var os3 = __toESM(require("os"));
|
|
4955
|
+
|
|
4956
|
+
// src/agent/claude-config.ts
|
|
4957
|
+
var import_crypto = require("crypto");
|
|
4958
|
+
function generateStatsigHash() {
|
|
4959
|
+
return (0, import_crypto.randomUUID)().replace(/-/g, "").substring(0, 10);
|
|
4960
|
+
}
|
|
4961
|
+
function generateNumericHash() {
|
|
4962
|
+
return Math.floor(1e9 + Math.random() * 9e9).toString();
|
|
4963
|
+
}
|
|
4964
|
+
function generateSettings() {
|
|
4965
|
+
return {
|
|
4966
|
+
permissions: {
|
|
4967
|
+
allow: [
|
|
4968
|
+
"Bash",
|
|
4969
|
+
"Read",
|
|
4970
|
+
"Write",
|
|
4971
|
+
"Edit",
|
|
4972
|
+
"Glob",
|
|
4973
|
+
"Grep",
|
|
4974
|
+
"WebFetch"
|
|
4975
|
+
],
|
|
4976
|
+
deny: [],
|
|
4977
|
+
ask: [],
|
|
4978
|
+
defaultMode: "acceptEdits"
|
|
4979
|
+
},
|
|
4980
|
+
alwaysThinkingEnabled: true
|
|
4981
|
+
};
|
|
4982
|
+
}
|
|
4983
|
+
function generateStableId() {
|
|
4984
|
+
return JSON.stringify((0, import_crypto.randomUUID)());
|
|
4985
|
+
}
|
|
4986
|
+
function generateSessionId() {
|
|
4987
|
+
const now = Date.now();
|
|
4988
|
+
return {
|
|
4989
|
+
sessionID: (0, import_crypto.randomUUID)(),
|
|
4990
|
+
startTime: now,
|
|
4991
|
+
lastUpdate: now
|
|
4992
|
+
};
|
|
4993
|
+
}
|
|
4994
|
+
function generateLastModifiedTime(hash) {
|
|
4995
|
+
return {
|
|
4996
|
+
[`statsig.cached.evaluations.${hash}`]: Date.now()
|
|
4997
|
+
};
|
|
4998
|
+
}
|
|
4999
|
+
function generateCachedEvaluations(stableId, sessionId) {
|
|
5000
|
+
const now = Date.now();
|
|
5001
|
+
const userIdHash = (0, import_crypto.randomUUID)().replace(/-/g, "");
|
|
5002
|
+
const featureGates = {
|
|
5003
|
+
// Essential gates for Claude Code operation
|
|
5004
|
+
"94472862": {
|
|
5005
|
+
name: "94472862",
|
|
5006
|
+
value: true,
|
|
5007
|
+
rule_id: "default",
|
|
5008
|
+
id_type: "userID",
|
|
5009
|
+
secondary_exposures: []
|
|
5010
|
+
},
|
|
5011
|
+
"165668090": {
|
|
5012
|
+
name: "165668090",
|
|
5013
|
+
value: true,
|
|
5014
|
+
rule_id: "default",
|
|
5015
|
+
id_type: "userID",
|
|
5016
|
+
secondary_exposures: []
|
|
5017
|
+
},
|
|
5018
|
+
"555881916": {
|
|
5019
|
+
name: "555881916",
|
|
5020
|
+
value: true,
|
|
5021
|
+
rule_id: "default",
|
|
5022
|
+
id_type: "userID",
|
|
5023
|
+
secondary_exposures: []
|
|
5024
|
+
},
|
|
5025
|
+
"1028491294": {
|
|
5026
|
+
name: "1028491294",
|
|
5027
|
+
value: true,
|
|
5028
|
+
rule_id: "default",
|
|
5029
|
+
id_type: "userID",
|
|
5030
|
+
secondary_exposures: []
|
|
5031
|
+
},
|
|
5032
|
+
"1129671138": {
|
|
5033
|
+
name: "1129671138",
|
|
5034
|
+
value: true,
|
|
5035
|
+
rule_id: "default",
|
|
5036
|
+
id_type: "userID",
|
|
5037
|
+
secondary_exposures: []
|
|
5038
|
+
},
|
|
5039
|
+
"1508506049": {
|
|
5040
|
+
name: "1508506049",
|
|
5041
|
+
value: true,
|
|
5042
|
+
rule_id: "default",
|
|
5043
|
+
id_type: "userID",
|
|
5044
|
+
secondary_exposures: []
|
|
5045
|
+
},
|
|
5046
|
+
"1567641428": {
|
|
5047
|
+
name: "1567641428",
|
|
5048
|
+
value: true,
|
|
5049
|
+
rule_id: "default",
|
|
5050
|
+
id_type: "userID",
|
|
5051
|
+
secondary_exposures: []
|
|
5052
|
+
},
|
|
5053
|
+
"1717649336": {
|
|
5054
|
+
name: "1717649336",
|
|
5055
|
+
value: true,
|
|
5056
|
+
rule_id: "default",
|
|
5057
|
+
id_type: "accountUUID",
|
|
5058
|
+
secondary_exposures: []
|
|
5059
|
+
},
|
|
5060
|
+
"2063607371": {
|
|
5061
|
+
name: "2063607371",
|
|
5062
|
+
value: true,
|
|
5063
|
+
rule_id: "default",
|
|
5064
|
+
id_type: "userID",
|
|
5065
|
+
secondary_exposures: []
|
|
5066
|
+
},
|
|
5067
|
+
"2866051182": {
|
|
5068
|
+
name: "2866051182",
|
|
5069
|
+
value: true,
|
|
5070
|
+
rule_id: "default",
|
|
5071
|
+
id_type: "userID",
|
|
5072
|
+
secondary_exposures: []
|
|
5073
|
+
},
|
|
5074
|
+
"3098321994": {
|
|
5075
|
+
name: "3098321994",
|
|
5076
|
+
value: true,
|
|
5077
|
+
rule_id: "default",
|
|
5078
|
+
id_type: "userID",
|
|
5079
|
+
secondary_exposures: []
|
|
5080
|
+
},
|
|
5081
|
+
"3222645059": {
|
|
5082
|
+
name: "3222645059",
|
|
5083
|
+
value: true,
|
|
5084
|
+
rule_id: "disabled",
|
|
5085
|
+
id_type: "userID",
|
|
5086
|
+
secondary_exposures: []
|
|
5087
|
+
},
|
|
5088
|
+
"3295963892": {
|
|
5089
|
+
name: "3295963892",
|
|
5090
|
+
value: true,
|
|
5091
|
+
rule_id: "default",
|
|
5092
|
+
id_type: "userID",
|
|
5093
|
+
secondary_exposures: []
|
|
5094
|
+
},
|
|
5095
|
+
"3326511187": {
|
|
5096
|
+
name: "3326511187",
|
|
5097
|
+
value: true,
|
|
5098
|
+
rule_id: "disabled",
|
|
5099
|
+
id_type: "userID",
|
|
5100
|
+
secondary_exposures: []
|
|
5101
|
+
},
|
|
5102
|
+
"3542670523": {
|
|
5103
|
+
name: "3542670523",
|
|
5104
|
+
value: true,
|
|
5105
|
+
rule_id: "default",
|
|
5106
|
+
id_type: "accountUUID",
|
|
5107
|
+
secondary_exposures: []
|
|
5108
|
+
},
|
|
5109
|
+
"3718505973": {
|
|
5110
|
+
name: "3718505973",
|
|
5111
|
+
value: true,
|
|
5112
|
+
rule_id: "default",
|
|
5113
|
+
id_type: "userID",
|
|
5114
|
+
secondary_exposures: []
|
|
5115
|
+
},
|
|
5116
|
+
"3864040445": {
|
|
5117
|
+
name: "3864040445",
|
|
5118
|
+
value: true,
|
|
5119
|
+
rule_id: "default",
|
|
5120
|
+
id_type: "userID",
|
|
5121
|
+
secondary_exposures: []
|
|
5122
|
+
},
|
|
5123
|
+
"3905024370": {
|
|
5124
|
+
name: "3905024370",
|
|
5125
|
+
value: true,
|
|
5126
|
+
rule_id: "default",
|
|
5127
|
+
id_type: "userID",
|
|
5128
|
+
secondary_exposures: []
|
|
5129
|
+
},
|
|
5130
|
+
"3975122287": {
|
|
5131
|
+
name: "3975122287",
|
|
5132
|
+
value: true,
|
|
5133
|
+
rule_id: "disabled",
|
|
5134
|
+
id_type: "userID",
|
|
5135
|
+
secondary_exposures: []
|
|
5136
|
+
}
|
|
5137
|
+
};
|
|
5138
|
+
const dynamicConfigs = {
|
|
5139
|
+
"1772930429": {
|
|
5140
|
+
name: "1772930429",
|
|
5141
|
+
value: { minVersion: "1.0.88" },
|
|
5142
|
+
rule_id: "default",
|
|
5143
|
+
group: "default",
|
|
5144
|
+
is_device_based: false,
|
|
5145
|
+
passed: false,
|
|
5146
|
+
id_type: "userID",
|
|
5147
|
+
secondary_exposures: []
|
|
5148
|
+
},
|
|
5149
|
+
"3148619311": {
|
|
5150
|
+
name: "3148619311",
|
|
5151
|
+
value: { fromMarketplace: true },
|
|
5152
|
+
rule_id: "default",
|
|
5153
|
+
group: "default",
|
|
5154
|
+
is_device_based: false,
|
|
5155
|
+
passed: true,
|
|
5156
|
+
id_type: "userID",
|
|
5157
|
+
secondary_exposures: []
|
|
5158
|
+
},
|
|
5159
|
+
"3239527534": {
|
|
5160
|
+
name: "3239527534",
|
|
5161
|
+
value: { capableModel: "dodo-v5-prod" },
|
|
5162
|
+
rule_id: "default",
|
|
5163
|
+
group: "default",
|
|
5164
|
+
is_device_based: false,
|
|
5165
|
+
passed: false,
|
|
5166
|
+
id_type: "userID",
|
|
5167
|
+
secondary_exposures: []
|
|
5168
|
+
}
|
|
5169
|
+
};
|
|
5170
|
+
const data = {
|
|
5171
|
+
feature_gates: featureGates,
|
|
5172
|
+
dynamic_configs: dynamicConfigs,
|
|
5173
|
+
layer_configs: {},
|
|
5174
|
+
sdkParams: {},
|
|
5175
|
+
has_updates: true,
|
|
5176
|
+
generator: "scrapi-nest",
|
|
5177
|
+
time: now,
|
|
5178
|
+
company_lcut: now,
|
|
5179
|
+
evaluated_keys: {
|
|
5180
|
+
userID: userIdHash,
|
|
5181
|
+
stableID: stableId,
|
|
5182
|
+
customIDs: {
|
|
5183
|
+
sessionId,
|
|
5184
|
+
organizationUUID: (0, import_crypto.randomUUID)(),
|
|
5185
|
+
accountUUID: (0, import_crypto.randomUUID)()
|
|
5186
|
+
}
|
|
5187
|
+
},
|
|
5188
|
+
hash_used: "djb2",
|
|
5189
|
+
derived_fields: {
|
|
5190
|
+
ip: "0.0.0.0",
|
|
5191
|
+
country: "US",
|
|
5192
|
+
appVersion: "2.1.7",
|
|
5193
|
+
app_version: "2.1.7",
|
|
5194
|
+
browserName: "Other",
|
|
5195
|
+
browserVersion: "0.0.0",
|
|
5196
|
+
osName: "Linux",
|
|
5197
|
+
osVersion: "0.0.0",
|
|
5198
|
+
browser_name: "Other",
|
|
5199
|
+
browser_version: "0.0.0",
|
|
5200
|
+
os_name: "Linux",
|
|
5201
|
+
os_version: "0.0.0"
|
|
5202
|
+
},
|
|
5203
|
+
hashed_sdk_key_used: "658916400",
|
|
5204
|
+
can_record_session: false,
|
|
5205
|
+
recording_blocked: true,
|
|
5206
|
+
session_recording_rate: 0,
|
|
5207
|
+
auto_capture_settings: { disabled_events: {} },
|
|
5208
|
+
target_app_used: "Claude Code - Everyone Can See These Names",
|
|
5209
|
+
full_checksum: Math.floor(Math.random() * 1e10).toString(),
|
|
5210
|
+
is_delta: false,
|
|
5211
|
+
checksum: Math.floor(Math.random() * 1e10).toString(),
|
|
5212
|
+
checksumV2: Math.floor(Math.random() * 1e10).toString(),
|
|
5213
|
+
deltas_full_response: null
|
|
5214
|
+
};
|
|
5215
|
+
return {
|
|
5216
|
+
source: "NetworkNotModified",
|
|
5217
|
+
data: JSON.stringify(data),
|
|
5218
|
+
receivedAt: now,
|
|
5219
|
+
stableID: stableId,
|
|
5220
|
+
fullUserHash: Math.floor(Math.random() * 1e10).toString()
|
|
5221
|
+
};
|
|
5222
|
+
}
|
|
5223
|
+
function generateClaudeConfig() {
|
|
5224
|
+
const hash = generateStatsigHash();
|
|
5225
|
+
const numericHash = generateNumericHash();
|
|
5226
|
+
const stableId = (0, import_crypto.randomUUID)();
|
|
5227
|
+
const sessionId = (0, import_crypto.randomUUID)();
|
|
5228
|
+
return {
|
|
5229
|
+
"settings.json": JSON.stringify(generateSettings(), null, 2),
|
|
5230
|
+
statsig: {
|
|
5231
|
+
[`statsig.stable_id.${numericHash}`]: generateStableId(),
|
|
5232
|
+
[`statsig.session_id.${numericHash}`]: JSON.stringify(
|
|
5233
|
+
generateSessionId()
|
|
5234
|
+
),
|
|
5235
|
+
[`statsig.last_modified_time.evaluations`]: JSON.stringify(
|
|
5236
|
+
generateLastModifiedTime(hash)
|
|
5237
|
+
),
|
|
5238
|
+
[`statsig.cached.evaluations.${hash}`]: JSON.stringify(
|
|
5239
|
+
generateCachedEvaluations(stableId, sessionId)
|
|
5240
|
+
)
|
|
5241
|
+
}
|
|
5242
|
+
};
|
|
5243
|
+
}
|
|
5244
|
+
|
|
5245
|
+
// src/agent/agent-manager.ts
|
|
4955
5246
|
var instance = null;
|
|
4956
5247
|
function getAgentManager() {
|
|
4957
5248
|
if (!instance) {
|
|
@@ -5000,11 +5291,16 @@ var AgentManager = class {
|
|
|
5000
5291
|
if (this.sessions.has(sessionId)) {
|
|
5001
5292
|
return { success: false, error: "Session already exists" };
|
|
5002
5293
|
}
|
|
5003
|
-
const oauthToken = credentials?.oauthToken
|
|
5004
|
-
|
|
5005
|
-
|
|
5294
|
+
const oauthToken = credentials?.oauthToken;
|
|
5295
|
+
const apiKey = credentials?.apiKey;
|
|
5296
|
+
if (!oauthToken && !apiKey) {
|
|
5297
|
+
return {
|
|
5298
|
+
success: false,
|
|
5299
|
+
error: "Missing credentials. Please connect your Claude account in Settings or provide an API key."
|
|
5300
|
+
};
|
|
5006
5301
|
}
|
|
5007
|
-
|
|
5302
|
+
const authMethod = oauthToken ? "OAuth" : "API key";
|
|
5303
|
+
console.log(`[AgentManager] Using ${authMethod} authentication`);
|
|
5008
5304
|
try {
|
|
5009
5305
|
await ensureClaudeBinary();
|
|
5010
5306
|
} catch (error) {
|
|
@@ -5080,25 +5376,69 @@ var AgentManager = class {
|
|
|
5080
5376
|
spawnCmd = binaryPath;
|
|
5081
5377
|
spawnArgs = args;
|
|
5082
5378
|
}
|
|
5379
|
+
const useOAuth = !!session.credentials.oauthToken;
|
|
5380
|
+
const useApiKey = !useOAuth && !!session.credentials.apiKey;
|
|
5083
5381
|
const claudeDir = path9.join(os3.homedir(), ".claude");
|
|
5084
5382
|
const credentialsPath = path9.join(claudeDir, ".credentials.json");
|
|
5383
|
+
const statsigDir = path9.join(claudeDir, "statsig");
|
|
5085
5384
|
if (!fs8.existsSync(claudeDir)) {
|
|
5086
5385
|
fs8.mkdirSync(claudeDir, { recursive: true });
|
|
5087
5386
|
}
|
|
5088
|
-
|
|
5089
|
-
|
|
5387
|
+
if (!fs8.existsSync(statsigDir)) {
|
|
5388
|
+
fs8.mkdirSync(statsigDir, { recursive: true });
|
|
5389
|
+
}
|
|
5390
|
+
if (useOAuth) {
|
|
5391
|
+
const oauthCredentials = {
|
|
5090
5392
|
accessToken: session.credentials.oauthToken
|
|
5091
|
-
}
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5393
|
+
};
|
|
5394
|
+
if (session.credentials.refreshToken) {
|
|
5395
|
+
oauthCredentials.refreshToken = session.credentials.refreshToken;
|
|
5396
|
+
}
|
|
5397
|
+
if (session.credentials.expiresAt) {
|
|
5398
|
+
oauthCredentials.expiresAt = session.credentials.expiresAt;
|
|
5399
|
+
}
|
|
5400
|
+
if (session.credentials.scopes) {
|
|
5401
|
+
oauthCredentials.scopes = session.credentials.scopes;
|
|
5402
|
+
}
|
|
5403
|
+
const credentialsContent = JSON.stringify({
|
|
5404
|
+
claudeAiOauth: oauthCredentials
|
|
5405
|
+
}, null, 2);
|
|
5406
|
+
fs8.writeFileSync(credentialsPath, credentialsContent, { mode: 384 });
|
|
5407
|
+
console.log(
|
|
5408
|
+
"[AgentManager] EP1126: Wrote OAuth credentials to ~/.claude/.credentials.json (with %s fields)",
|
|
5409
|
+
Object.keys(oauthCredentials).join(", ")
|
|
5410
|
+
);
|
|
5411
|
+
try {
|
|
5412
|
+
const claudeConfig = generateClaudeConfig();
|
|
5413
|
+
const statsigFiles = Object.keys(claudeConfig.statsig);
|
|
5414
|
+
const hasEvaluations = statsigFiles.some((f) => f.includes("cached.evaluations"));
|
|
5415
|
+
const hasStableId = statsigFiles.some((f) => f.includes("stable_id"));
|
|
5416
|
+
if (!hasEvaluations || !hasStableId) {
|
|
5417
|
+
throw new Error(`Invalid statsig config: missing required files (evaluations=${hasEvaluations}, stableId=${hasStableId})`);
|
|
5418
|
+
}
|
|
5419
|
+
const settingsPath = path9.join(claudeDir, "settings.json");
|
|
5420
|
+
fs8.writeFileSync(settingsPath, claudeConfig["settings.json"], { mode: 384 });
|
|
5421
|
+
console.log("[AgentManager] EP1126: Wrote settings.json");
|
|
5422
|
+
for (const [filename, content] of Object.entries(claudeConfig.statsig)) {
|
|
5423
|
+
const filePath = path9.join(statsigDir, filename);
|
|
5424
|
+
fs8.writeFileSync(filePath, content, { mode: 420 });
|
|
5425
|
+
}
|
|
5426
|
+
console.log("[AgentManager] EP1126: Wrote statsig cache files (%d files) for eligibility verification", statsigFiles.length);
|
|
5427
|
+
} catch (configError) {
|
|
5428
|
+
console.warn("[AgentManager] EP1126: Failed to write config files:", configError instanceof Error ? configError.message : configError);
|
|
5429
|
+
}
|
|
5430
|
+
} else if (useApiKey) {
|
|
5431
|
+
console.log("[AgentManager] EP1126: Using API key authentication (ANTHROPIC_API_KEY)");
|
|
5432
|
+
}
|
|
5095
5433
|
const childProcess = (0, import_child_process8.spawn)(spawnCmd, spawnArgs, {
|
|
5096
5434
|
cwd: session.projectPath,
|
|
5097
5435
|
env: {
|
|
5098
5436
|
...process.env,
|
|
5099
5437
|
// Disable color output for cleaner JSON parsing
|
|
5100
5438
|
NO_COLOR: "1",
|
|
5101
|
-
FORCE_COLOR: "0"
|
|
5439
|
+
FORCE_COLOR: "0",
|
|
5440
|
+
// Add API key if using API key auth mode
|
|
5441
|
+
...useApiKey && session.credentials.apiKey ? { ANTHROPIC_API_KEY: session.credentials.apiKey } : {}
|
|
5102
5442
|
},
|
|
5103
5443
|
stdio: ["pipe", "pipe", "pipe"]
|
|
5104
5444
|
});
|