deepcode-ai 1.1.27 → 1.1.29
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/index.js +80 -18
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -3489,7 +3489,7 @@ Caminho: ${selectedPath}`;
|
|
|
3489
3489
|
const effectiveModel = resolvedModel;
|
|
3490
3490
|
if (!effectiveModel) {
|
|
3491
3491
|
throw new Error(
|
|
3492
|
-
|
|
3492
|
+
`No model configured for ${resolvedTarget.provider}. Run /model or set defaultModels.${resolvedTarget.provider} in .deepcode/config.json, or set DEEPCODE_MODEL.`
|
|
3493
3493
|
);
|
|
3494
3494
|
}
|
|
3495
3495
|
session.status = "planning";
|
|
@@ -3516,6 +3516,9 @@ Caminho: ${selectedPath}`;
|
|
|
3516
3516
|
if (error instanceof BudgetExceededError) {
|
|
3517
3517
|
throw error;
|
|
3518
3518
|
}
|
|
3519
|
+
if (options.signal?.aborted) {
|
|
3520
|
+
throw error;
|
|
3521
|
+
}
|
|
3519
3522
|
session.metadata.planError = formatErrorChain(error);
|
|
3520
3523
|
this.eventBus.emit("app:warn", {
|
|
3521
3524
|
message: formatPlanningFailureWarning(error),
|
|
@@ -3552,7 +3555,7 @@ Caminho: ${selectedPath}`;
|
|
|
3552
3555
|
const model = options.model ?? session.model ?? resolveConfiguredModelForProvider(this.config, providerId);
|
|
3553
3556
|
if (!model) {
|
|
3554
3557
|
throw new Error(
|
|
3555
|
-
|
|
3558
|
+
`No model configured for ${providerId}. Run /model or set defaultModels.${providerId} in .deepcode/config.json, or set DEEPCODE_MODEL.`
|
|
3556
3559
|
);
|
|
3557
3560
|
}
|
|
3558
3561
|
const alreadyTrackingBudget = this.activeBudgets.has(session.id);
|
|
@@ -3919,6 +3922,7 @@ ${assistantText}` : assistantText;
|
|
|
3919
3922
|
errorMessage: `Invalid arguments for ${call.name}: ${parsed.error.message}`
|
|
3920
3923
|
};
|
|
3921
3924
|
}
|
|
3925
|
+
const scopedSecurity = this.securityForSession(session);
|
|
3922
3926
|
const context = {
|
|
3923
3927
|
sessionId: session.id,
|
|
3924
3928
|
messageId: createId("msg"),
|
|
@@ -3928,8 +3932,8 @@ ${assistantText}` : assistantText;
|
|
|
3928
3932
|
config: this.config,
|
|
3929
3933
|
agentMode: mode,
|
|
3930
3934
|
cache: this.cache,
|
|
3931
|
-
permissions:
|
|
3932
|
-
pathSecurity:
|
|
3935
|
+
permissions: scopedSecurity.permissions,
|
|
3936
|
+
pathSecurity: scopedSecurity.pathSecurity,
|
|
3933
3937
|
logActivity: (activity) => {
|
|
3934
3938
|
const full = { ...activity, id: createId("activity"), createdAt: nowIso() };
|
|
3935
3939
|
session.activities.push(full);
|
|
@@ -3979,6 +3983,13 @@ ${assistantText}` : assistantText;
|
|
|
3979
3983
|
};
|
|
3980
3984
|
}
|
|
3981
3985
|
}
|
|
3986
|
+
securityForSession(session) {
|
|
3987
|
+
const pathSecurity = this.pathSecurity.forWorktree(session.worktree);
|
|
3988
|
+
return {
|
|
3989
|
+
pathSecurity,
|
|
3990
|
+
permissions: this.permissions.forPathSecurity(pathSecurity)
|
|
3991
|
+
};
|
|
3992
|
+
}
|
|
3982
3993
|
logToolActivity(session, activity) {
|
|
3983
3994
|
const full = { ...activity, id: createId("activity"), createdAt: nowIso() };
|
|
3984
3995
|
session.activities.push(full);
|
|
@@ -4234,8 +4245,9 @@ ${assistantText}` : assistantText;
|
|
|
4234
4245
|
return "Git nao esta instalado. Quer que eu instale?";
|
|
4235
4246
|
}
|
|
4236
4247
|
const scanInput = inputPath === "." ? process.env.HOME ?? inputPath : inputPath;
|
|
4237
|
-
const
|
|
4238
|
-
await
|
|
4248
|
+
const security = this.securityForSession(session);
|
|
4249
|
+
const rootPath = await security.pathSecurity.normalize(scanInput, { enforceAccess: false });
|
|
4250
|
+
await security.permissions.ensure({ operation: "list_projects", kind: "read", path: rootPath });
|
|
4239
4251
|
const results = [];
|
|
4240
4252
|
await this.walkForProjects(rootPath, 3, results, /* @__PURE__ */ new Set());
|
|
4241
4253
|
if (results.length === 0) {
|
|
@@ -6485,10 +6497,14 @@ function globToRegex(glob) {
|
|
|
6485
6497
|
}
|
|
6486
6498
|
return new RegExp(`^${globPatternToRegexSource(glob)}$`);
|
|
6487
6499
|
}
|
|
6488
|
-
var PathSecurity = class {
|
|
6500
|
+
var PathSecurity = class _PathSecurity {
|
|
6489
6501
|
constructor(worktree, rules) {
|
|
6490
6502
|
this.worktree = worktree;
|
|
6491
6503
|
this.home = process.env.HOME ?? os2.homedir();
|
|
6504
|
+
this.sourceRules = {
|
|
6505
|
+
whitelist: [...rules.whitelist],
|
|
6506
|
+
blacklist: [...rules.blacklist]
|
|
6507
|
+
};
|
|
6492
6508
|
this.rules = {
|
|
6493
6509
|
whitelist: rules.whitelist.map((rule) => this.expand(rule, this.home)),
|
|
6494
6510
|
blacklist: rules.blacklist.map((rule) => this.expand(rule, this.home))
|
|
@@ -6496,7 +6512,11 @@ var PathSecurity = class {
|
|
|
6496
6512
|
}
|
|
6497
6513
|
worktree;
|
|
6498
6514
|
rules;
|
|
6515
|
+
sourceRules;
|
|
6499
6516
|
home;
|
|
6517
|
+
forWorktree(worktree) {
|
|
6518
|
+
return new _PathSecurity(path7.resolve(worktree), this.sourceRules);
|
|
6519
|
+
}
|
|
6500
6520
|
async normalize(inputPath, options = {}) {
|
|
6501
6521
|
const enforceAccess = options.enforceAccess ?? true;
|
|
6502
6522
|
const resolved = await this.resolvePath(inputPath);
|
|
@@ -6556,13 +6576,16 @@ var PathSecurity = class {
|
|
|
6556
6576
|
return targetPath;
|
|
6557
6577
|
}
|
|
6558
6578
|
};
|
|
6559
|
-
var PermissionGateway = class {
|
|
6560
|
-
constructor(config, pathSecurity, audit, eventBus, interactive = false) {
|
|
6579
|
+
var PermissionGateway = class _PermissionGateway {
|
|
6580
|
+
constructor(config, pathSecurity, audit, eventBus, interactive = false, state) {
|
|
6561
6581
|
this.config = config;
|
|
6562
6582
|
this.pathSecurity = pathSecurity;
|
|
6563
6583
|
this.audit = audit;
|
|
6564
6584
|
this.eventBus = eventBus;
|
|
6565
6585
|
this.interactive = interactive;
|
|
6586
|
+
this.sessionAllowSet = state?.sessionAllowSet ?? /* @__PURE__ */ new Set();
|
|
6587
|
+
this.alwaysAllowSet = state?.alwaysAllowSet ?? /* @__PURE__ */ new Set();
|
|
6588
|
+
this.pendingApprovals = state?.pendingApprovals ?? /* @__PURE__ */ new Map();
|
|
6566
6589
|
}
|
|
6567
6590
|
config;
|
|
6568
6591
|
pathSecurity;
|
|
@@ -6570,11 +6593,25 @@ var PermissionGateway = class {
|
|
|
6570
6593
|
eventBus;
|
|
6571
6594
|
interactive;
|
|
6572
6595
|
/** Set of operation+path keys that were approved for the current session */
|
|
6573
|
-
sessionAllowSet
|
|
6596
|
+
sessionAllowSet;
|
|
6574
6597
|
/** Set of operation+path keys that were approved permanently (always) */
|
|
6575
|
-
alwaysAllowSet
|
|
6598
|
+
alwaysAllowSet;
|
|
6576
6599
|
/** Map of pending approval requests by request ID */
|
|
6577
|
-
pendingApprovals
|
|
6600
|
+
pendingApprovals;
|
|
6601
|
+
forPathSecurity(pathSecurity) {
|
|
6602
|
+
return new _PermissionGateway(
|
|
6603
|
+
this.config,
|
|
6604
|
+
pathSecurity,
|
|
6605
|
+
this.audit,
|
|
6606
|
+
this.eventBus,
|
|
6607
|
+
this.interactive,
|
|
6608
|
+
{
|
|
6609
|
+
sessionAllowSet: this.sessionAllowSet,
|
|
6610
|
+
alwaysAllowSet: this.alwaysAllowSet,
|
|
6611
|
+
pendingApprovals: this.pendingApprovals
|
|
6612
|
+
}
|
|
6613
|
+
);
|
|
6614
|
+
}
|
|
6578
6615
|
/** Clear all session-scoped permissions (e.g., when session ends) */
|
|
6579
6616
|
clearSessionAllowSet() {
|
|
6580
6617
|
this.sessionAllowSet.clear();
|
|
@@ -7479,7 +7516,15 @@ function classifyShellCommand(command) {
|
|
|
7479
7516
|
/\bdd\s+if=/,
|
|
7480
7517
|
/\bsudo\b/,
|
|
7481
7518
|
/\bcurl\b.*\|\s*(sh|bash)\b/,
|
|
7482
|
-
/\bwget\b.*\|\s*(sh|bash)\b
|
|
7519
|
+
/\bwget\b.*\|\s*(sh|bash)\b/,
|
|
7520
|
+
// Auto-install and execute remote packages without confirmation
|
|
7521
|
+
/\bnpx\s+(?:--yes|-y)\b/,
|
|
7522
|
+
// Background processes that outlive the agent turn
|
|
7523
|
+
/(?:^|;|\|)\s*[^&]*[^&]\s*&\s*$/,
|
|
7524
|
+
// HTTP/TCP servers that bind to all interfaces (exposes files to the network)
|
|
7525
|
+
/\bpython3?\s+-m\s+http\.server\b(?!.*--bind\s+(?:127\.|::1|localhost))/,
|
|
7526
|
+
/\bnc\s+.*-l\b/,
|
|
7527
|
+
/\bsocat\b.*(?:TCP-LISTEN|UDP-LISTEN)/
|
|
7483
7528
|
].some((pattern) => pattern.test(normalized2));
|
|
7484
7529
|
return dangerous ? "dangerous" : "shell";
|
|
7485
7530
|
}
|
|
@@ -28118,7 +28163,7 @@ function parseVersion2(version) {
|
|
|
28118
28163
|
if (!match) return null;
|
|
28119
28164
|
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
28120
28165
|
}
|
|
28121
|
-
var VERSION = "1.1.
|
|
28166
|
+
var VERSION = "1.1.29".length > 0 ? "1.1.29" : "0.0.0-dev";
|
|
28122
28167
|
var updateCommand = {
|
|
28123
28168
|
name: "update",
|
|
28124
28169
|
description: "Check published DeepCode versions",
|
|
@@ -29697,6 +29742,7 @@ Follow-up suggestion:`;
|
|
|
29697
29742
|
return null;
|
|
29698
29743
|
}
|
|
29699
29744
|
}
|
|
29745
|
+
var APPROVAL_ENTER_ARM_DELAY_MS = 350;
|
|
29700
29746
|
var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
29701
29747
|
const historyManager = useHistory();
|
|
29702
29748
|
const addHistoryItem = historyManager.addItem;
|
|
@@ -29758,6 +29804,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
|
29758
29804
|
const messageQueueRef = useRef17([]);
|
|
29759
29805
|
const sessionShellAllowlistRef = useRef17(/* @__PURE__ */ new Set());
|
|
29760
29806
|
const mainControlsRef = useRef17(null);
|
|
29807
|
+
const approvalPromptVisibleAtRef = useRef17(null);
|
|
29761
29808
|
const { stdin, setRawMode } = useStdin3();
|
|
29762
29809
|
const { columns: terminalWidth, rows: terminalHeight } = useTerminalSize();
|
|
29763
29810
|
const mainAreaWidth = Math.min(Math.max(terminalWidth - 4, 20), 120);
|
|
@@ -29889,6 +29936,14 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
|
29889
29936
|
}, []);
|
|
29890
29937
|
const setSessionMode = useCallback26((mode) => {
|
|
29891
29938
|
setAgentMode(mode);
|
|
29939
|
+
const runtime = runtimeRef.current;
|
|
29940
|
+
const session = sessionRef.current;
|
|
29941
|
+
if (runtime && session) {
|
|
29942
|
+
session.metadata = { ...session.metadata, agentMode: mode };
|
|
29943
|
+
runtime.sessions.save(session);
|
|
29944
|
+
runtime.sessions.persist(session.id).catch(() => {
|
|
29945
|
+
});
|
|
29946
|
+
}
|
|
29892
29947
|
}, []);
|
|
29893
29948
|
const setSessionName = useCallback26((name) => {
|
|
29894
29949
|
const runtime = runtimeRef.current;
|
|
@@ -29985,12 +30040,14 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
|
29985
30040
|
}, [messageQueue]);
|
|
29986
30041
|
useEffect27(() => {
|
|
29987
30042
|
if (approvalQueue.length > 0) {
|
|
30043
|
+
approvalPromptVisibleAtRef.current ??= Date.now();
|
|
29988
30044
|
setStreamingState(
|
|
29989
30045
|
"waiting_for_confirmation"
|
|
29990
30046
|
/* WaitingForConfirmation */
|
|
29991
30047
|
);
|
|
29992
30048
|
return;
|
|
29993
30049
|
}
|
|
30050
|
+
approvalPromptVisibleAtRef.current = null;
|
|
29994
30051
|
if (isRunning) {
|
|
29995
30052
|
setStreamingState(
|
|
29996
30053
|
"responding"
|
|
@@ -30070,7 +30127,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
|
30070
30127
|
dangerous: runtime.config.permissions.dangerous
|
|
30071
30128
|
});
|
|
30072
30129
|
setAuthSummary(formatAuthSummary(runtime.config.github));
|
|
30073
|
-
|
|
30130
|
+
const persistedMode = typeof session.metadata.agentMode === "string" && (session.metadata.agentMode === "build" || session.metadata.agentMode === "plan") ? session.metadata.agentMode : runtime.config.agentMode;
|
|
30131
|
+
setAgentMode(persistedMode);
|
|
30074
30132
|
setTargetSource(provider || model ? "cli" : "config");
|
|
30075
30133
|
setCurrentModel(session.model ?? "(unconfigured)");
|
|
30076
30134
|
setProviderLabel(formatProviderLabel(session.provider, session.model));
|
|
@@ -30416,6 +30474,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
|
30416
30474
|
let status = "Success";
|
|
30417
30475
|
let resultDisplay = "(no output)";
|
|
30418
30476
|
try {
|
|
30477
|
+
const pathSecurity = runtime.pathSecurity.forWorktree(session.worktree);
|
|
30478
|
+
const permissions = runtime.permissions.forPathSecurity(pathSecurity);
|
|
30419
30479
|
const result = await runToolEffect(
|
|
30420
30480
|
tool.execute(parsed.data, {
|
|
30421
30481
|
sessionId: session.id,
|
|
@@ -30426,8 +30486,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
|
30426
30486
|
config: runtime.config,
|
|
30427
30487
|
agentMode,
|
|
30428
30488
|
cache: runtime.cache,
|
|
30429
|
-
permissions
|
|
30430
|
-
pathSecurity
|
|
30489
|
+
permissions,
|
|
30490
|
+
pathSecurity,
|
|
30431
30491
|
logActivity: (activity) => {
|
|
30432
30492
|
runtime.events.emit("activity", {
|
|
30433
30493
|
id: createId("activity"),
|
|
@@ -30973,10 +31033,12 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId }) => {
|
|
|
30973
31033
|
}
|
|
30974
31034
|
if (approvalQueue.length > 0) {
|
|
30975
31035
|
const pressed = input.toLowerCase();
|
|
30976
|
-
|
|
31036
|
+
const enterArmed = approvalPromptVisibleAtRef.current !== null && Date.now() - approvalPromptVisibleAtRef.current >= APPROVAL_ENTER_ARM_DELAY_MS;
|
|
31037
|
+
if (pressed === "y" || key.return && enterArmed) {
|
|
30977
31038
|
resolveApproval({ allowed: true, scope: "once", reason: "Approved in TUI" });
|
|
30978
31039
|
return;
|
|
30979
31040
|
}
|
|
31041
|
+
if (key.return) return;
|
|
30980
31042
|
if (pressed === "s") {
|
|
30981
31043
|
resolveApproval({ allowed: true, scope: "session", reason: "Approved for session in TUI" });
|
|
30982
31044
|
return;
|