episoda 0.2.102 → 0.2.104
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/dist/daemon/daemon-process.js +101 -11
- package/dist/daemon/daemon-process.js.map +1 -1
- package/dist/index.js +40 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -2786,7 +2786,7 @@ var require_package = __commonJS({
|
|
|
2786
2786
|
"package.json"(exports2, module2) {
|
|
2787
2787
|
module2.exports = {
|
|
2788
2788
|
name: "episoda",
|
|
2789
|
-
version: "0.2.
|
|
2789
|
+
version: "0.2.104",
|
|
2790
2790
|
description: "CLI tool for Episoda local development workflow orchestration",
|
|
2791
2791
|
main: "dist/index.js",
|
|
2792
2792
|
types: "dist/index.d.ts",
|
|
@@ -8374,7 +8374,7 @@ var AgentManager = class {
|
|
|
8374
8374
|
* EP1173: Added autonomousMode parameter for permission-free execution
|
|
8375
8375
|
*/
|
|
8376
8376
|
async startSession(options) {
|
|
8377
|
-
const { sessionId, moduleId, moduleUid, projectPath, provider = "claude", autonomousMode = true, message, credentials, systemPrompt, onChunk, onComplete, onError } = options;
|
|
8377
|
+
const { sessionId, moduleId, moduleUid, projectPath, provider = "claude", autonomousMode = true, canWrite = true, readOnlyReason, message, credentials, systemPrompt, onChunk, onComplete, onError } = options;
|
|
8378
8378
|
if (this.sessions.has(sessionId)) {
|
|
8379
8379
|
return { success: false, error: "Session already exists" };
|
|
8380
8380
|
}
|
|
@@ -8413,6 +8413,10 @@ var AgentManager = class {
|
|
|
8413
8413
|
// EP1133: Store provider in session
|
|
8414
8414
|
autonomousMode,
|
|
8415
8415
|
// EP1173: Store autonomous mode setting
|
|
8416
|
+
canWrite,
|
|
8417
|
+
// EP1205: Store write permission
|
|
8418
|
+
readOnlyReason,
|
|
8419
|
+
// EP1205: Store reason for read-only mode
|
|
8416
8420
|
credentials,
|
|
8417
8421
|
systemPrompt,
|
|
8418
8422
|
status: "starting",
|
|
@@ -8437,16 +8441,50 @@ var AgentManager = class {
|
|
|
8437
8441
|
* EP1133: Supports both Claude Code and Codex CLI with provider-specific handling.
|
|
8438
8442
|
*/
|
|
8439
8443
|
async sendMessage(options) {
|
|
8440
|
-
const { sessionId, message, isFirstMessage, agentSessionId, claudeSessionId, onChunk, onComplete, onError } = options;
|
|
8444
|
+
const { sessionId, message, isFirstMessage, canWrite, readOnlyReason, agentSessionId, claudeSessionId, onChunk, onComplete, onError } = options;
|
|
8441
8445
|
const session = this.sessions.get(sessionId);
|
|
8442
8446
|
if (!session) {
|
|
8443
8447
|
return { success: false, error: "Session not found" };
|
|
8444
8448
|
}
|
|
8445
8449
|
session.lastActivityAt = /* @__PURE__ */ new Date();
|
|
8446
8450
|
session.status = "running";
|
|
8451
|
+
if (canWrite !== void 0) {
|
|
8452
|
+
session.canWrite = canWrite;
|
|
8453
|
+
session.readOnlyReason = readOnlyReason;
|
|
8454
|
+
}
|
|
8447
8455
|
const resumeSessionId = agentSessionId || claudeSessionId;
|
|
8448
8456
|
try {
|
|
8449
8457
|
const provider = session.provider || "claude";
|
|
8458
|
+
let effectiveSystemPrompt = session.systemPrompt || "";
|
|
8459
|
+
if (session.canWrite === false) {
|
|
8460
|
+
const readOnlyNotice = `
|
|
8461
|
+
\u26A0\uFE0F READ-ONLY SESSION - STRICT ENFORCEMENT
|
|
8462
|
+
|
|
8463
|
+
You are operating in READ-ONLY mode. You MUST NOT perform ANY write operations:
|
|
8464
|
+
|
|
8465
|
+
FORBIDDEN ACTIONS:
|
|
8466
|
+
- Create, modify, or delete any files (Write/Edit tools are blocked)
|
|
8467
|
+
- Run Bash commands that modify files (rm, mv, cp, touch, echo >, sed -i, etc.)
|
|
8468
|
+
- Run Bash commands that modify git state (git commit, git push, git checkout --, etc.)
|
|
8469
|
+
- Make any changes to the filesystem whatsoever
|
|
8470
|
+
|
|
8471
|
+
Reason: ${session.readOnlyReason || "You do not have write access to this module."}
|
|
8472
|
+
|
|
8473
|
+
ALLOWED ACTIONS:
|
|
8474
|
+
- Read files (using Read tool)
|
|
8475
|
+
- Run read-only Bash commands (ls, cat, git status, git log, git diff, grep, find, etc.)
|
|
8476
|
+
- Analyze code and provide recommendations
|
|
8477
|
+
- Explain architecture and suggest changes (but not implement them)
|
|
8478
|
+
|
|
8479
|
+
If the user requests changes, explain what would need to be done but DO NOT execute any write operations.
|
|
8480
|
+
Violations will result in errors and may affect your ability to assist.
|
|
8481
|
+
|
|
8482
|
+
---
|
|
8483
|
+
|
|
8484
|
+
`;
|
|
8485
|
+
effectiveSystemPrompt = readOnlyNotice + effectiveSystemPrompt;
|
|
8486
|
+
console.log(`[AgentManager] EP1205: Read-only mode enabled for session ${sessionId}: ${session.readOnlyReason}`);
|
|
8487
|
+
}
|
|
8450
8488
|
let binaryPath;
|
|
8451
8489
|
let args;
|
|
8452
8490
|
if (provider === "codex") {
|
|
@@ -8461,21 +8499,39 @@ var AgentManager = class {
|
|
|
8461
8499
|
session.projectPath
|
|
8462
8500
|
// Working directory
|
|
8463
8501
|
];
|
|
8464
|
-
if (session.autonomousMode) {
|
|
8502
|
+
if (session.autonomousMode && session.canWrite !== false) {
|
|
8465
8503
|
args.push("--full-auto");
|
|
8466
8504
|
console.log(`[AgentManager] EP1173: Codex autonomous mode enabled - using --full-auto`);
|
|
8467
8505
|
}
|
|
8506
|
+
if (session.canWrite === false) {
|
|
8507
|
+
args.push("--sandbox", "read-only");
|
|
8508
|
+
console.log(`[AgentManager] EP1205: Codex read-only mode - using --sandbox read-only`);
|
|
8509
|
+
}
|
|
8468
8510
|
if (resumeSessionId) {
|
|
8469
8511
|
args.push("resume", resumeSessionId);
|
|
8470
8512
|
}
|
|
8471
8513
|
let fullMessage = message;
|
|
8472
|
-
if (isFirstMessage &&
|
|
8473
|
-
fullMessage = `${
|
|
8514
|
+
if (isFirstMessage && effectiveSystemPrompt) {
|
|
8515
|
+
fullMessage = `${effectiveSystemPrompt}
|
|
8474
8516
|
|
|
8475
8517
|
---
|
|
8476
8518
|
|
|
8477
8519
|
${message}`;
|
|
8478
8520
|
}
|
|
8521
|
+
if (session.canWrite === false && !isFirstMessage) {
|
|
8522
|
+
const readOnlyReminder = `
|
|
8523
|
+
[SYSTEM REMINDER - READ-ONLY MODE]
|
|
8524
|
+
You are in READ-ONLY mode. Do NOT:
|
|
8525
|
+
- Create, modify, or delete any files
|
|
8526
|
+
- Run commands that write to the filesystem
|
|
8527
|
+
- Make git commits or changes
|
|
8528
|
+
Reason: ${session.readOnlyReason || "No write access to this module."}
|
|
8529
|
+
If changes are needed, explain what needs to be done but do not execute.
|
|
8530
|
+
[END SYSTEM REMINDER]
|
|
8531
|
+
|
|
8532
|
+
`;
|
|
8533
|
+
fullMessage = readOnlyReminder + fullMessage;
|
|
8534
|
+
}
|
|
8479
8535
|
args.push(fullMessage);
|
|
8480
8536
|
} else {
|
|
8481
8537
|
binaryPath = await ensureClaudeBinary();
|
|
@@ -8494,12 +8550,26 @@ ${message}`;
|
|
|
8494
8550
|
args.push("--model", session.credentials.preferredModel);
|
|
8495
8551
|
console.log(`[AgentManager] EP1152: Using user preferred model: ${session.credentials.preferredModel}`);
|
|
8496
8552
|
}
|
|
8497
|
-
if (session.autonomousMode) {
|
|
8553
|
+
if (session.autonomousMode && session.canWrite !== false) {
|
|
8498
8554
|
args.push("--dangerously-skip-permissions");
|
|
8499
8555
|
console.log(`[AgentManager] EP1173: Autonomous mode enabled - skipping permission prompts`);
|
|
8556
|
+
} else if (session.autonomousMode && session.canWrite === false) {
|
|
8557
|
+
console.log(`[AgentManager] EP1205: Autonomous mode with read-only - NOT skipping permissions (safety net)`);
|
|
8558
|
+
}
|
|
8559
|
+
if (isFirstMessage && effectiveSystemPrompt) {
|
|
8560
|
+
args.push("--system-prompt", effectiveSystemPrompt);
|
|
8500
8561
|
}
|
|
8501
|
-
if (
|
|
8502
|
-
args.push("--
|
|
8562
|
+
if (session.canWrite === false) {
|
|
8563
|
+
args.push("--disallowed-tools", "Write,Edit,MultiEdit,NotebookEdit");
|
|
8564
|
+
console.log("[AgentManager] EP1205: Read-only enforcement - disallowed Write/Edit tools");
|
|
8565
|
+
if (!isFirstMessage) {
|
|
8566
|
+
const readOnlyReminder = `
|
|
8567
|
+
REMINDER: You are in READ-ONLY mode. You cannot create, modify, or delete files.
|
|
8568
|
+
Reason: ${session.readOnlyReason || "No write access to this module."}
|
|
8569
|
+
If changes are needed, explain what needs to be done.`;
|
|
8570
|
+
args.push("--append-system-prompt", readOnlyReminder);
|
|
8571
|
+
console.log("[AgentManager] EP1205: Appended read-only reminder to subsequent message");
|
|
8572
|
+
}
|
|
8503
8573
|
}
|
|
8504
8574
|
if (resumeSessionId) {
|
|
8505
8575
|
args.push("--resume", resumeSessionId);
|
|
@@ -10217,11 +10287,23 @@ var Daemon = class _Daemon {
|
|
|
10217
10287
|
if (cmd.action === "start") {
|
|
10218
10288
|
const callbacks = createStreamingCallbacks(cmd.sessionId, message.id);
|
|
10219
10289
|
let agentWorkingDir = projectPath;
|
|
10220
|
-
if (cmd.moduleUid) {
|
|
10290
|
+
if (cmd.moduleUid && cmd.sessionContext === "worktree") {
|
|
10221
10291
|
const worktreeInfo = await getWorktreeInfoForModule(cmd.moduleUid);
|
|
10222
10292
|
if (worktreeInfo?.exists) {
|
|
10223
10293
|
agentWorkingDir = worktreeInfo.path;
|
|
10224
|
-
console.log(`[Daemon]
|
|
10294
|
+
console.log(`[Daemon] EP1205: Agent for ${cmd.moduleUid} in worktree: ${agentWorkingDir}`);
|
|
10295
|
+
} else {
|
|
10296
|
+
console.log(`[Daemon] EP1205: Worktree requested but not found for ${cmd.moduleUid}, using project root`);
|
|
10297
|
+
}
|
|
10298
|
+
} else if (cmd.sessionContext === "project_root") {
|
|
10299
|
+
console.log(`[Daemon] EP1205: Agent for ${cmd.moduleUid || "project"} in project root (sessionContext=project_root)`);
|
|
10300
|
+
} else {
|
|
10301
|
+
if (cmd.moduleUid) {
|
|
10302
|
+
const worktreeInfo = await getWorktreeInfoForModule(cmd.moduleUid);
|
|
10303
|
+
if (worktreeInfo?.exists) {
|
|
10304
|
+
agentWorkingDir = worktreeInfo.path;
|
|
10305
|
+
console.log(`[Daemon] EP959: Agent for ${cmd.moduleUid} in worktree (legacy, no sessionContext): ${agentWorkingDir}`);
|
|
10306
|
+
}
|
|
10225
10307
|
}
|
|
10226
10308
|
}
|
|
10227
10309
|
const startResult = await agentManager.startSession({
|
|
@@ -10233,6 +10315,10 @@ var Daemon = class _Daemon {
|
|
|
10233
10315
|
// EP1133: Multi-provider support
|
|
10234
10316
|
autonomousMode: cmd.autonomousMode ?? true,
|
|
10235
10317
|
// EP1173: Default to autonomous
|
|
10318
|
+
canWrite: cmd.canWrite ?? true,
|
|
10319
|
+
// EP1205: Default to writable
|
|
10320
|
+
readOnlyReason: cmd.readOnlyReason,
|
|
10321
|
+
// EP1205: Pass reason for UI
|
|
10236
10322
|
message: cmd.message,
|
|
10237
10323
|
credentials: cmd.credentials,
|
|
10238
10324
|
systemPrompt: cmd.systemPrompt,
|
|
@@ -10250,6 +10336,10 @@ var Daemon = class _Daemon {
|
|
|
10250
10336
|
sessionId: cmd.sessionId,
|
|
10251
10337
|
message: cmd.message,
|
|
10252
10338
|
isFirstMessage: false,
|
|
10339
|
+
canWrite: cmd.canWrite,
|
|
10340
|
+
// EP1205: Update write permission if changed
|
|
10341
|
+
readOnlyReason: cmd.readOnlyReason,
|
|
10342
|
+
// EP1205: Update reason if changed
|
|
10253
10343
|
agentSessionId: cmd.agentSessionId || cmd.claudeSessionId,
|
|
10254
10344
|
claudeSessionId: cmd.claudeSessionId,
|
|
10255
10345
|
// Backward compat
|