aiden-runtime 4.1.5 → 4.5.0
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/README.md +250 -847
- package/dist/api/server.js +32 -5
- package/dist/cli/v4/aidenCLI.js +351 -53
- package/dist/cli/v4/callbacks.js +170 -0
- package/dist/cli/v4/chatSession.js +138 -3
- package/dist/cli/v4/commands/_runtimeToggleHelpers.js +92 -0
- package/dist/cli/v4/commands/browserDepth.js +45 -0
- package/dist/cli/v4/commands/cron.js +264 -0
- package/dist/cli/v4/commands/daemon.js +541 -0
- package/dist/cli/v4/commands/daemonStatus.js +253 -0
- package/dist/cli/v4/commands/help.js +7 -0
- package/dist/cli/v4/commands/index.js +20 -1
- package/dist/cli/v4/commands/runs.js +203 -0
- package/dist/cli/v4/commands/sandbox.js +48 -0
- package/dist/cli/v4/commands/suggestions.js +68 -0
- package/dist/cli/v4/commands/tce.js +41 -0
- package/dist/cli/v4/commands/trigger.js +378 -0
- package/dist/cli/v4/commands/update.js +95 -3
- package/dist/cli/v4/daemonAgentBuilder.js +142 -0
- package/dist/cli/v4/defaultSoul.js +1 -1
- package/dist/cli/v4/display/capabilityCard.js +26 -0
- package/dist/cli/v4/display.js +18 -8
- package/dist/cli/v4/replyRenderer.js +31 -23
- package/dist/cli/v4/updateBootPrompt.js +170 -0
- package/dist/core/playwrightBridge.js +129 -0
- package/dist/core/v4/aidenAgent.js +308 -4
- package/dist/core/v4/browserState.js +436 -0
- package/dist/core/v4/checkpoint.js +79 -0
- package/dist/core/v4/daemon/bootstrap.js +604 -0
- package/dist/core/v4/daemon/cleanShutdown.js +154 -0
- package/dist/core/v4/daemon/cron/cronBridge.js +126 -0
- package/dist/core/v4/daemon/cron/cronEmitter.js +173 -0
- package/dist/core/v4/daemon/cron/migration.js +199 -0
- package/dist/core/v4/daemon/cron/misfirePolicy.js +115 -0
- package/dist/core/v4/daemon/daemonConfig.js +90 -0
- package/dist/core/v4/daemon/db/connection.js +106 -0
- package/dist/core/v4/daemon/db/migrations.js +296 -0
- package/dist/core/v4/daemon/db/schema/v1.spec.js +18 -0
- package/dist/core/v4/daemon/dispatcher/agentRunner.js +98 -0
- package/dist/core/v4/daemon/dispatcher/budgetGate.js +127 -0
- package/dist/core/v4/daemon/dispatcher/daemonApproval.js +113 -0
- package/dist/core/v4/daemon/dispatcher/dailyBudgetTracker.js +120 -0
- package/dist/core/v4/daemon/dispatcher/dispatcher.js +389 -0
- package/dist/core/v4/daemon/dispatcher/fireRateLimiter.js +113 -0
- package/dist/core/v4/daemon/dispatcher/index.js +53 -0
- package/dist/core/v4/daemon/dispatcher/promptTemplate.js +95 -0
- package/dist/core/v4/daemon/dispatcher/realAgentRunner.js +356 -0
- package/dist/core/v4/daemon/dispatcher/resolveModel.js +93 -0
- package/dist/core/v4/daemon/dispatcher/sessionId.js +93 -0
- package/dist/core/v4/daemon/drain.js +156 -0
- package/dist/core/v4/daemon/eventLoopLag.js +73 -0
- package/dist/core/v4/daemon/health.js +159 -0
- package/dist/core/v4/daemon/idempotencyStore.js +204 -0
- package/dist/core/v4/daemon/index.js +179 -0
- package/dist/core/v4/daemon/instanceTracker.js +99 -0
- package/dist/core/v4/daemon/resourceRegistry.js +150 -0
- package/dist/core/v4/daemon/restartCode.js +32 -0
- package/dist/core/v4/daemon/restartFailureCounter.js +77 -0
- package/dist/core/v4/daemon/runStore.js +114 -0
- package/dist/core/v4/daemon/runtimeLock.js +167 -0
- package/dist/core/v4/daemon/signals.js +50 -0
- package/dist/core/v4/daemon/supervisor.js +272 -0
- package/dist/core/v4/daemon/triggerBus.js +279 -0
- package/dist/core/v4/daemon/triggers/email/allowlist.js +70 -0
- package/dist/core/v4/daemon/triggers/email/automatedSender.js +78 -0
- package/dist/core/v4/daemon/triggers/email/bodyExtractor.js +0 -0
- package/dist/core/v4/daemon/triggers/email/emailSeenStore.js +99 -0
- package/dist/core/v4/daemon/triggers/email/emailSpec.js +107 -0
- package/dist/core/v4/daemon/triggers/email/imapConnection.js +211 -0
- package/dist/core/v4/daemon/triggers/email/index.js +332 -0
- package/dist/core/v4/daemon/triggers/email/seenUids.js +60 -0
- package/dist/core/v4/daemon/triggers/fileObservationsStore.js +93 -0
- package/dist/core/v4/daemon/triggers/fileWatcher.js +253 -0
- package/dist/core/v4/daemon/triggers/fileWatcherSpec.js +88 -0
- package/dist/core/v4/daemon/triggers/fsIdentity.js +42 -0
- package/dist/core/v4/daemon/triggers/globMatcher.js +100 -0
- package/dist/core/v4/daemon/triggers/reconcile.js +206 -0
- package/dist/core/v4/daemon/triggers/settleStat.js +81 -0
- package/dist/core/v4/daemon/triggers/webhook.js +376 -0
- package/dist/core/v4/daemon/triggers/webhookDeliveriesStore.js +109 -0
- package/dist/core/v4/daemon/triggers/webhookIdempotency.js +72 -0
- package/dist/core/v4/daemon/triggers/webhookRateLimit.js +56 -0
- package/dist/core/v4/daemon/triggers/webhookSpec.js +76 -0
- package/dist/core/v4/daemon/triggers/webhookVerifier.js +128 -0
- package/dist/core/v4/daemon/types.js +15 -0
- package/dist/core/v4/dockerSession.js +461 -0
- package/dist/core/v4/dryRun.js +117 -0
- package/dist/core/v4/failureClassifier.js +779 -0
- package/dist/core/v4/recoveryReport.js +449 -0
- package/dist/core/v4/runtimeToggles.js +187 -0
- package/dist/core/v4/sandboxConfig.js +285 -0
- package/dist/core/v4/sandboxFs.js +316 -0
- package/dist/core/v4/suggestionCatalog.js +41 -0
- package/dist/core/v4/suggestionEngine.js +210 -0
- package/dist/core/v4/toolRegistry.js +18 -0
- package/dist/core/v4/turnState.js +587 -0
- package/dist/core/v4/update/checkUpdate.js +63 -3
- package/dist/core/v4/update/installMethodDetect.js +115 -0
- package/dist/core/v4/update/registryClient.js +121 -0
- package/dist/core/v4/update/skipState.js +75 -0
- package/dist/core/v4/verifier.js +448 -0
- package/dist/core/version.js +1 -1
- package/dist/tools/v4/browser/_observer.js +224 -0
- package/dist/tools/v4/browser/browserBlocker.js +396 -0
- package/dist/tools/v4/browser/browserClick.js +18 -1
- package/dist/tools/v4/browser/browserClose.js +18 -1
- package/dist/tools/v4/browser/browserExtract.js +5 -1
- package/dist/tools/v4/browser/browserFill.js +17 -1
- package/dist/tools/v4/browser/browserGetUrl.js +5 -1
- package/dist/tools/v4/browser/browserNavigate.js +16 -1
- package/dist/tools/v4/browser/browserScreenshot.js +5 -1
- package/dist/tools/v4/browser/browserScroll.js +18 -1
- package/dist/tools/v4/browser/browserType.js +17 -1
- package/dist/tools/v4/browser/captchaCheck.js +5 -1
- package/dist/tools/v4/executeCode.js +1 -0
- package/dist/tools/v4/files/fileCopy.js +56 -2
- package/dist/tools/v4/files/fileDelete.js +38 -1
- package/dist/tools/v4/files/fileList.js +12 -1
- package/dist/tools/v4/files/fileMove.js +59 -2
- package/dist/tools/v4/files/filePatch.js +43 -1
- package/dist/tools/v4/files/fileRead.js +12 -1
- package/dist/tools/v4/files/fileWrite.js +41 -1
- package/dist/tools/v4/index.js +71 -58
- package/dist/tools/v4/memory/memoryAdd.js +14 -0
- package/dist/tools/v4/memory/memoryRemove.js +14 -0
- package/dist/tools/v4/memory/memoryReplace.js +15 -0
- package/dist/tools/v4/memory/sessionSummary.js +12 -0
- package/dist/tools/v4/process/processKill.js +19 -0
- package/dist/tools/v4/process/processList.js +1 -0
- package/dist/tools/v4/process/processLogRead.js +1 -0
- package/dist/tools/v4/process/processSpawn.js +13 -0
- package/dist/tools/v4/process/processWait.js +1 -0
- package/dist/tools/v4/sessions/recallSession.js +1 -0
- package/dist/tools/v4/sessions/sessionList.js +1 -0
- package/dist/tools/v4/sessions/sessionSearch.js +1 -0
- package/dist/tools/v4/skills/lookupToolSchema.js +2 -0
- package/dist/tools/v4/skills/skillManage.js +13 -0
- package/dist/tools/v4/skills/skillView.js +1 -0
- package/dist/tools/v4/skills/skillsList.js +1 -0
- package/dist/tools/v4/subagent/subagentFanout.js +1 -0
- package/dist/tools/v4/system/aidenSelfUpdate.js +16 -0
- package/dist/tools/v4/system/appClose.js +13 -0
- package/dist/tools/v4/system/appInput.js +13 -0
- package/dist/tools/v4/system/appLaunch.js +13 -0
- package/dist/tools/v4/system/clipboardRead.js +1 -0
- package/dist/tools/v4/system/clipboardWrite.js +14 -0
- package/dist/tools/v4/system/mediaKey.js +12 -0
- package/dist/tools/v4/system/mediaSessions.js +1 -0
- package/dist/tools/v4/system/mediaTransport.js +13 -0
- package/dist/tools/v4/system/naturalEvents.js +1 -0
- package/dist/tools/v4/system/nowPlaying.js +1 -0
- package/dist/tools/v4/system/osProcessList.js +1 -0
- package/dist/tools/v4/system/screenshot.js +1 -0
- package/dist/tools/v4/system/systemInfo.js +1 -0
- package/dist/tools/v4/system/volumeSet.js +17 -0
- package/dist/tools/v4/terminal/shellExec.js +81 -9
- package/dist/tools/v4/web/deepResearch.js +1 -0
- package/dist/tools/v4/web/openUrl.js +1 -0
- package/dist/tools/v4/web/webFetch.js +1 -0
- package/dist/tools/v4/web/webPage.js +1 -0
- package/dist/tools/v4/web/webSearch.js +1 -0
- package/dist/tools/v4/web/youtubeSearch.js +1 -0
- package/package.json +7 -1
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.memoryAddTool = void 0;
|
|
20
|
+
const dryRun_1 = require("../../../core/v4/dryRun");
|
|
20
21
|
exports.memoryAddTool = {
|
|
21
22
|
schema: {
|
|
22
23
|
name: 'memory_add',
|
|
@@ -37,6 +38,19 @@ exports.memoryAddTool = {
|
|
|
37
38
|
category: 'write',
|
|
38
39
|
mutates: true,
|
|
39
40
|
toolset: 'memory',
|
|
41
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
42
|
+
buildPreview(args) {
|
|
43
|
+
const file = args.file === 'user' ? 'user' : 'memory';
|
|
44
|
+
const content = String(args.content ?? '');
|
|
45
|
+
return {
|
|
46
|
+
tool: 'memory_add',
|
|
47
|
+
args,
|
|
48
|
+
riskTier: 'caution',
|
|
49
|
+
sideEffects: [{ type: 'memory_write', op: 'add', bullet: (0, dryRun_1.truncatePreview)(content) }],
|
|
50
|
+
detectedRisks: [],
|
|
51
|
+
summary: `Would append to ${file === 'user' ? 'USER.md' : 'MEMORY.md'}: "${(0, dryRun_1.truncatePreview)(content, 80)}"`,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
40
54
|
async execute(args, ctx) {
|
|
41
55
|
if (!ctx.memoryGuard) {
|
|
42
56
|
return { success: false, error: 'memory guard not configured' };
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
32
|
exports.memoryRemoveTool = void 0;
|
|
33
33
|
const memoryGuard_1 = require("../../../moat/memoryGuard");
|
|
34
|
+
const dryRun_1 = require("../../../core/v4/dryRun");
|
|
34
35
|
/** Section in MEMORY.md that Phase D promotion writes to. */
|
|
35
36
|
const DURABLE_FACTS_HEADER = '## Durable facts';
|
|
36
37
|
exports.memoryRemoveTool = {
|
|
@@ -59,6 +60,19 @@ exports.memoryRemoveTool = {
|
|
|
59
60
|
category: 'write',
|
|
60
61
|
mutates: true,
|
|
61
62
|
toolset: 'memory',
|
|
63
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
64
|
+
buildPreview(args) {
|
|
65
|
+
const file = args.file === 'user' ? 'user' : 'memory';
|
|
66
|
+
const text = String(args.text ?? '');
|
|
67
|
+
return {
|
|
68
|
+
tool: 'memory_remove',
|
|
69
|
+
args,
|
|
70
|
+
riskTier: 'caution',
|
|
71
|
+
sideEffects: [{ type: 'memory_write', op: 'remove', pattern: (0, dryRun_1.truncatePreview)(text, 80) }],
|
|
72
|
+
detectedRisks: [],
|
|
73
|
+
summary: `Would remove from ${file === 'user' ? 'USER.md' : 'MEMORY.md'}: "${(0, dryRun_1.truncatePreview)(text, 80)}"`,
|
|
74
|
+
};
|
|
75
|
+
},
|
|
62
76
|
async execute(args, ctx) {
|
|
63
77
|
if (!ctx.memoryGuard) {
|
|
64
78
|
return { success: false, error: 'memory guard not configured' };
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.memoryReplaceTool = void 0;
|
|
19
|
+
const dryRun_1 = require("../../../core/v4/dryRun");
|
|
19
20
|
exports.memoryReplaceTool = {
|
|
20
21
|
schema: {
|
|
21
22
|
name: 'memory_replace',
|
|
@@ -37,6 +38,20 @@ exports.memoryReplaceTool = {
|
|
|
37
38
|
category: 'write',
|
|
38
39
|
mutates: true,
|
|
39
40
|
toolset: 'memory',
|
|
41
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
42
|
+
buildPreview(args) {
|
|
43
|
+
const file = args.file === 'user' ? 'user' : 'memory';
|
|
44
|
+
const oldText = String(args.old_text ?? args.oldText ?? '');
|
|
45
|
+
const newText = String(args.new_text ?? args.newText ?? '');
|
|
46
|
+
return {
|
|
47
|
+
tool: 'memory_replace',
|
|
48
|
+
args,
|
|
49
|
+
riskTier: 'caution',
|
|
50
|
+
sideEffects: [{ type: 'memory_write', op: 'replace', pattern: (0, dryRun_1.truncatePreview)(oldText, 80), bullet: (0, dryRun_1.truncatePreview)(newText, 80) }],
|
|
51
|
+
detectedRisks: [],
|
|
52
|
+
summary: `Would replace in ${file === 'user' ? 'USER.md' : 'MEMORY.md'}: "${(0, dryRun_1.truncatePreview)(oldText, 40)}" → "${(0, dryRun_1.truncatePreview)(newText, 40)}"`,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
40
55
|
async execute(args, ctx) {
|
|
41
56
|
if (!ctx.memoryGuard) {
|
|
42
57
|
return { success: false, error: 'memory guard not configured' };
|
|
@@ -100,6 +100,18 @@ exports.sessionSummaryTool = {
|
|
|
100
100
|
category: 'write',
|
|
101
101
|
mutates: true,
|
|
102
102
|
toolset: 'memory',
|
|
103
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
104
|
+
buildPreview(args, ctx) {
|
|
105
|
+
const sessionId = String(args.session_id ?? args.sessionId ?? ctx.sessionId ?? 'current');
|
|
106
|
+
return {
|
|
107
|
+
tool: 'session_summary',
|
|
108
|
+
args,
|
|
109
|
+
riskTier: 'caution',
|
|
110
|
+
sideEffects: [{ type: 'session_distill', session_id: sessionId }],
|
|
111
|
+
detectedRisks: [],
|
|
112
|
+
summary: `Would distill session ${sessionId} into Recent-sessions section of MEMORY.md`,
|
|
113
|
+
};
|
|
114
|
+
},
|
|
103
115
|
async execute(args, ctx) {
|
|
104
116
|
if (!ctx.memoryGuard) {
|
|
105
117
|
return { success: false, error: 'memory guard not configured' };
|
|
@@ -31,6 +31,25 @@ exports.processKillTool = {
|
|
|
31
31
|
category: 'write',
|
|
32
32
|
mutates: true,
|
|
33
33
|
toolset: 'process',
|
|
34
|
+
riskTier: 'dangerous', // v4.4 Phase 1
|
|
35
|
+
buildPreview(args, ctx) {
|
|
36
|
+
const id = String(args.id ?? '').trim();
|
|
37
|
+
const signal = args.signal || 'SIGTERM';
|
|
38
|
+
let pid = -1;
|
|
39
|
+
if (ctx.processes && id) {
|
|
40
|
+
const h = ctx.processes.get(id);
|
|
41
|
+
if (h && typeof h.pid === 'number')
|
|
42
|
+
pid = h.pid;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
tool: 'process_kill',
|
|
46
|
+
args,
|
|
47
|
+
riskTier: 'dangerous',
|
|
48
|
+
sideEffects: [{ type: 'process_kill', pid, signal }],
|
|
49
|
+
detectedRisks: signal === 'SIGKILL' ? ['SIGKILL'] : [],
|
|
50
|
+
summary: `Would send ${signal} to process ${id}${pid > 0 ? ` (pid ${pid})` : ''}`,
|
|
51
|
+
};
|
|
52
|
+
},
|
|
34
53
|
async execute(args, ctx) {
|
|
35
54
|
if (!ctx.processes) {
|
|
36
55
|
return { success: false, error: 'process registry not configured' };
|
|
@@ -32,6 +32,19 @@ exports.processSpawnTool = {
|
|
|
32
32
|
category: 'execute',
|
|
33
33
|
mutates: true,
|
|
34
34
|
toolset: 'process',
|
|
35
|
+
riskTier: 'dangerous', // v4.4 Phase 1
|
|
36
|
+
buildPreview(args, ctx) {
|
|
37
|
+
const command = String(args.command ?? '').trim();
|
|
38
|
+
const cwd = typeof args.cwd === 'string' ? args.cwd : ctx.cwd;
|
|
39
|
+
return {
|
|
40
|
+
tool: 'process_spawn',
|
|
41
|
+
args,
|
|
42
|
+
riskTier: 'dangerous',
|
|
43
|
+
sideEffects: [{ type: 'process_spawn', command, args: [] }],
|
|
44
|
+
detectedRisks: [],
|
|
45
|
+
summary: `Would spawn background process: \`${command.length > 80 ? command.slice(0, 80) + '…' : command}\` in ${cwd}`,
|
|
46
|
+
};
|
|
47
|
+
},
|
|
35
48
|
async execute(args, ctx) {
|
|
36
49
|
if (!ctx.processes) {
|
|
37
50
|
return { success: false, error: 'process registry not configured' };
|
|
@@ -45,6 +45,7 @@ function makeLookupToolSchema(registry) {
|
|
|
45
45
|
category: 'read',
|
|
46
46
|
mutates: false,
|
|
47
47
|
toolset: 'skills',
|
|
48
|
+
riskTier: 'safe', // v4.4 Phase 1
|
|
48
49
|
async execute(args) {
|
|
49
50
|
const name = String(args.toolName ?? args.name ?? '').trim();
|
|
50
51
|
if (!name)
|
|
@@ -63,6 +64,7 @@ function makeLookupToolSchema(registry) {
|
|
|
63
64
|
category: handler.category,
|
|
64
65
|
mutates: handler.mutates,
|
|
65
66
|
toolset: handler.toolset,
|
|
67
|
+
riskTier: 'safe', // v4.4 Phase 1
|
|
66
68
|
};
|
|
67
69
|
},
|
|
68
70
|
};
|
|
@@ -78,6 +78,19 @@ exports.skillManageTool = {
|
|
|
78
78
|
category: 'write',
|
|
79
79
|
mutates: true,
|
|
80
80
|
toolset: 'skills',
|
|
81
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
82
|
+
buildPreview(args) {
|
|
83
|
+
const action = typeof args.action === 'string' ? args.action : '';
|
|
84
|
+
const name = typeof args.name === 'string' ? args.name : '';
|
|
85
|
+
return {
|
|
86
|
+
tool: 'skill_manage',
|
|
87
|
+
args,
|
|
88
|
+
riskTier: 'caution',
|
|
89
|
+
sideEffects: [{ type: 'skill_write', op: action, name }],
|
|
90
|
+
detectedRisks: action === 'delete' ? ['skill_delete'] : [],
|
|
91
|
+
summary: `Would ${action} skill: ${name}`,
|
|
92
|
+
};
|
|
93
|
+
},
|
|
81
94
|
async execute(args, ctx) {
|
|
82
95
|
if (!ctx.skillLoader || !ctx.paths) {
|
|
83
96
|
return { success: false, error: 'No skill loader configured' };
|
|
@@ -122,6 +122,7 @@ function makeSubagentFanoutTool(factory) {
|
|
|
122
122
|
category: 'network',
|
|
123
123
|
mutates: false,
|
|
124
124
|
toolset: 'subagent',
|
|
125
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
125
126
|
async execute(args, _ctx) {
|
|
126
127
|
const logger = factory.logger ?? (0, factory_1.noopLogger)();
|
|
127
128
|
// ── Coerce args ────────────────────────────────────────────
|
|
@@ -68,6 +68,22 @@ exports.aidenSelfUpdateTool = {
|
|
|
68
68
|
category: 'write',
|
|
69
69
|
mutates: true,
|
|
70
70
|
toolset: 'system',
|
|
71
|
+
riskTier: 'dangerous', // v4.4 Phase 1
|
|
72
|
+
// v4.4 Phase 4 — dry-run refuses; self-update bootstrapping is not
|
|
73
|
+
// safe to model with a no-op preview.
|
|
74
|
+
buildPreview(args) {
|
|
75
|
+
return {
|
|
76
|
+
tool: 'aiden_self_update',
|
|
77
|
+
args,
|
|
78
|
+
riskTier: 'dangerous',
|
|
79
|
+
sideEffects: [{
|
|
80
|
+
type: 'refuse',
|
|
81
|
+
reason: 'aiden_self_update is not safe to preview in dry-run mode. Set AIDEN_DRYRUN=0 to perform a real self-update (with the usual approval-engine confirmation).',
|
|
82
|
+
}],
|
|
83
|
+
detectedRisks: ['self_update'],
|
|
84
|
+
summary: 'Refused: aiden_self_update cannot be previewed in dry-run mode',
|
|
85
|
+
};
|
|
86
|
+
},
|
|
71
87
|
async execute(args, ctx) {
|
|
72
88
|
if (!ctx.paths) {
|
|
73
89
|
return {
|
|
@@ -53,6 +53,19 @@ exports.appCloseTool = {
|
|
|
53
53
|
category: 'execute',
|
|
54
54
|
mutates: true,
|
|
55
55
|
toolset: 'system',
|
|
56
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
57
|
+
buildPreview(args) {
|
|
58
|
+
const app = typeof args.app === 'string' ? args.app : '';
|
|
59
|
+
const force = args.force === true;
|
|
60
|
+
return {
|
|
61
|
+
tool: 'app_close',
|
|
62
|
+
args,
|
|
63
|
+
riskTier: 'caution',
|
|
64
|
+
sideEffects: [{ type: 'app_control', action: force ? 'force-close' : 'close', target: app }],
|
|
65
|
+
detectedRisks: force ? ['force_close'] : [],
|
|
66
|
+
summary: `Would ${force ? 'force-' : ''}close app: ${app}`,
|
|
67
|
+
};
|
|
68
|
+
},
|
|
56
69
|
async execute(args, _ctx) {
|
|
57
70
|
if (!(0, _psHelpers_1.isWindows)())
|
|
58
71
|
return (0, _psHelpers_1.windowsOnlyError)('app_close');
|
|
@@ -89,6 +89,19 @@ exports.appInputTool = {
|
|
|
89
89
|
category: 'execute',
|
|
90
90
|
mutates: true,
|
|
91
91
|
toolset: 'system',
|
|
92
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
93
|
+
buildPreview(args) {
|
|
94
|
+
const app = typeof args.app === 'string' ? args.app : '';
|
|
95
|
+
const keys = typeof args.keys === 'string' ? args.keys : '';
|
|
96
|
+
return {
|
|
97
|
+
tool: 'app_input',
|
|
98
|
+
args,
|
|
99
|
+
riskTier: 'caution',
|
|
100
|
+
sideEffects: [{ type: 'app_control', action: `send-keys:${keys}`, target: app }],
|
|
101
|
+
detectedRisks: [],
|
|
102
|
+
summary: `Would send keys "${keys}" to app: ${app}`,
|
|
103
|
+
};
|
|
104
|
+
},
|
|
92
105
|
async execute(args, _ctx) {
|
|
93
106
|
if (!(0, _psHelpers_1.isWindows)()) {
|
|
94
107
|
return (0, _psHelpers_1.windowsOnlyError)('app_input', {
|
|
@@ -123,6 +123,19 @@ exports.appLaunchTool = {
|
|
|
123
123
|
category: 'execute',
|
|
124
124
|
mutates: true,
|
|
125
125
|
toolset: 'system',
|
|
126
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
127
|
+
buildPreview(args) {
|
|
128
|
+
const app = typeof args.app === 'string' ? args.app : '';
|
|
129
|
+
const cliArgs = Array.isArray(args.args) ? args.args.map(String) : [];
|
|
130
|
+
return {
|
|
131
|
+
tool: 'app_launch',
|
|
132
|
+
args,
|
|
133
|
+
riskTier: 'caution',
|
|
134
|
+
sideEffects: [{ type: 'app_control', action: 'launch', target: app + (cliArgs.length ? ' ' + cliArgs.join(' ') : '') }],
|
|
135
|
+
detectedRisks: [],
|
|
136
|
+
summary: `Would launch app: ${app}${cliArgs.length ? ' with args ' + cliArgs.join(' ') : ''}`,
|
|
137
|
+
};
|
|
138
|
+
},
|
|
126
139
|
async execute(args, _ctx) {
|
|
127
140
|
if (!(0, _psHelpers_1.isWindows)())
|
|
128
141
|
return (0, _psHelpers_1.windowsOnlyError)('app_launch');
|
|
@@ -32,6 +32,7 @@ exports.clipboardReadTool = {
|
|
|
32
32
|
category: 'read',
|
|
33
33
|
mutates: false,
|
|
34
34
|
toolset: 'system',
|
|
35
|
+
riskTier: 'safe', // v4.4 Phase 1
|
|
35
36
|
async execute(_args, _ctx) {
|
|
36
37
|
if (!(0, _psHelpers_1.isWindows)())
|
|
37
38
|
return (0, _psHelpers_1.windowsOnlyError)('clipboard_read');
|
|
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
exports.clipboardWriteTool = void 0;
|
|
20
20
|
const node_child_process_1 = require("node:child_process");
|
|
21
21
|
const _psHelpers_1 = require("./_psHelpers");
|
|
22
|
+
const dryRun_1 = require("../../../core/v4/dryRun");
|
|
22
23
|
/**
|
|
23
24
|
* Spawn `powershell.exe Set-Clipboard` with the text piped on stdin.
|
|
24
25
|
* Wrapper Promise so the tool's `execute` can `await` it.
|
|
@@ -61,6 +62,19 @@ exports.clipboardWriteTool = {
|
|
|
61
62
|
category: 'execute',
|
|
62
63
|
mutates: true,
|
|
63
64
|
toolset: 'system',
|
|
65
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
66
|
+
buildPreview(args) {
|
|
67
|
+
const text = typeof args.text === 'string' ? args.text : '';
|
|
68
|
+
const bytes = Buffer.byteLength(text, 'utf-8');
|
|
69
|
+
return {
|
|
70
|
+
tool: 'clipboard_write',
|
|
71
|
+
args,
|
|
72
|
+
riskTier: 'caution',
|
|
73
|
+
sideEffects: [{ type: 'clipboard_write', bytes, preview: (0, dryRun_1.truncatePreview)(text) }],
|
|
74
|
+
detectedRisks: [],
|
|
75
|
+
summary: `Would write ${bytes} bytes to clipboard`,
|
|
76
|
+
};
|
|
77
|
+
},
|
|
64
78
|
async execute(args, _ctx) {
|
|
65
79
|
if (!(0, _psHelpers_1.isWindows)())
|
|
66
80
|
return (0, _psHelpers_1.windowsOnlyError)('clipboard_write');
|
|
@@ -53,6 +53,18 @@ exports.mediaKeyTool = {
|
|
|
53
53
|
category: 'execute',
|
|
54
54
|
mutates: true,
|
|
55
55
|
toolset: 'system',
|
|
56
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
57
|
+
buildPreview(args) {
|
|
58
|
+
const action = typeof args.action === 'string' ? args.action : '';
|
|
59
|
+
return {
|
|
60
|
+
tool: 'media_key',
|
|
61
|
+
args,
|
|
62
|
+
riskTier: 'caution',
|
|
63
|
+
sideEffects: [{ type: 'media_control', action }],
|
|
64
|
+
detectedRisks: [],
|
|
65
|
+
summary: `Would send media key: ${action}`,
|
|
66
|
+
};
|
|
67
|
+
},
|
|
56
68
|
async execute(args, _ctx) {
|
|
57
69
|
if (!(0, _psHelpers_1.isWindows)()) {
|
|
58
70
|
return (0, _psHelpers_1.windowsOnlyError)('media_key', {
|
|
@@ -113,6 +113,7 @@ exports.mediaSessionsTool = {
|
|
|
113
113
|
category: 'read',
|
|
114
114
|
mutates: false,
|
|
115
115
|
toolset: 'system',
|
|
116
|
+
riskTier: 'safe', // v4.4 Phase 1
|
|
116
117
|
async execute(_args, _ctx) {
|
|
117
118
|
if (!(0, _psHelpers_1.isWindows)()) {
|
|
118
119
|
return (0, _psHelpers_1.windowsOnlyError)('media_sessions', {
|
|
@@ -135,6 +135,19 @@ exports.mediaTransportTool = {
|
|
|
135
135
|
category: 'execute',
|
|
136
136
|
mutates: true,
|
|
137
137
|
toolset: 'system',
|
|
138
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
139
|
+
buildPreview(args) {
|
|
140
|
+
const action = typeof args.action === 'string' ? args.action : '';
|
|
141
|
+
const target = typeof args.target === 'string' ? args.target : '';
|
|
142
|
+
return {
|
|
143
|
+
tool: 'media_transport',
|
|
144
|
+
args,
|
|
145
|
+
riskTier: 'caution',
|
|
146
|
+
sideEffects: [{ type: 'media_control', action: target ? `${action}:${target}` : action }],
|
|
147
|
+
detectedRisks: [],
|
|
148
|
+
summary: `Would invoke media transport: ${action}${target ? ` on ${target}` : ' (current session)'}`,
|
|
149
|
+
};
|
|
150
|
+
},
|
|
138
151
|
async execute(args, _ctx) {
|
|
139
152
|
if (!(0, _psHelpers_1.isWindows)()) {
|
|
140
153
|
// v4.1.3-essentials: tailored capability card for non-Windows.
|
|
@@ -62,6 +62,7 @@ exports.osProcessListTool = {
|
|
|
62
62
|
category: 'read',
|
|
63
63
|
mutates: false,
|
|
64
64
|
toolset: 'system',
|
|
65
|
+
riskTier: 'safe', // v4.4 Phase 1
|
|
65
66
|
async execute(args, _ctx) {
|
|
66
67
|
if (!(0, _psHelpers_1.isWindows)())
|
|
67
68
|
return (0, _psHelpers_1.windowsOnlyError)('os_process_list');
|
|
@@ -123,6 +123,23 @@ exports.volumeSetTool = {
|
|
|
123
123
|
category: 'execute',
|
|
124
124
|
mutates: true,
|
|
125
125
|
toolset: 'system',
|
|
126
|
+
riskTier: 'caution', // v4.4 Phase 1
|
|
127
|
+
buildPreview(args) {
|
|
128
|
+
const action = typeof args.action === 'string' ? args.action : '';
|
|
129
|
+
const percent = typeof args.percent === 'number' ? args.percent : -1;
|
|
130
|
+
return {
|
|
131
|
+
tool: 'volume_set',
|
|
132
|
+
args,
|
|
133
|
+
riskTier: 'caution',
|
|
134
|
+
sideEffects: action === 'set'
|
|
135
|
+
? [{ type: 'volume_set', level: Math.max(0, Math.min(100, percent)) }]
|
|
136
|
+
: [{ type: 'media_control', action }],
|
|
137
|
+
detectedRisks: [],
|
|
138
|
+
summary: action === 'set'
|
|
139
|
+
? `Would set volume to ${percent}%`
|
|
140
|
+
: `Would ${action.replace('_', ' ')}`,
|
|
141
|
+
};
|
|
142
|
+
},
|
|
126
143
|
async execute(args, _ctx) {
|
|
127
144
|
if (!(0, _psHelpers_1.isWindows)())
|
|
128
145
|
return (0, _psHelpers_1.windowsOnlyError)('volume_set');
|
|
@@ -8,17 +8,34 @@
|
|
|
8
8
|
/**
|
|
9
9
|
* tools/v4/terminal/shellExec.ts — `shell_exec` wrapper.
|
|
10
10
|
*
|
|
11
|
-
* Routes a shell command to
|
|
12
|
-
* Windows, bash on POSIX)
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Routes a shell command to one of three backends:
|
|
12
|
+
* - local backend (status quo: PowerShell on Windows, bash on POSIX)
|
|
13
|
+
* - docker single-shot backend (status quo for explicit
|
|
14
|
+
* `ctx.terminalBackend='docker'` with AIDEN_SANDBOX=0)
|
|
15
|
+
* - docker session backend (v4.4 Phase 3: long-lived container reuse
|
|
16
|
+
* with hardening + resource limits when AIDEN_SANDBOX=1)
|
|
15
17
|
*
|
|
16
|
-
*
|
|
18
|
+
* Backend selection precedence:
|
|
19
|
+
* 1. Per-call override `ctx.terminalBackend` wins. When that's
|
|
20
|
+
* `'docker'` AND AIDEN_SANDBOX is enabled, the session-backed
|
|
21
|
+
* `dockerSessionExec` is used (reuse + hardening). When
|
|
22
|
+
* `'docker'` AND AIDEN_SANDBOX is disabled, the legacy
|
|
23
|
+
* single-shot `dockerBackendExecute` runs (tests rely on this).
|
|
24
|
+
* 2. No override + AIDEN_SANDBOX=1 → docker session backend.
|
|
25
|
+
* 3. No override + AIDEN_SANDBOX=0 → local (current behavior).
|
|
26
|
+
*
|
|
27
|
+
* Phase 9's approval engine still gates this tool the same way. The
|
|
28
|
+
* tool stays `riskTier: 'dangerous'` — sandbox isolation does not
|
|
29
|
+
* promote a shell command's tier; it only constrains the blast radius.
|
|
30
|
+
*
|
|
31
|
+
* Status: PHASE 8 → v4.4 Phase 3.
|
|
17
32
|
*/
|
|
18
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
34
|
exports.shellExecTool = void 0;
|
|
20
35
|
const local_1 = require("../backends/local");
|
|
21
36
|
const docker_1 = require("../backends/docker");
|
|
37
|
+
const dockerSession_1 = require("../../../core/v4/dockerSession");
|
|
38
|
+
const sandboxConfig_1 = require("../../../core/v4/sandboxConfig");
|
|
22
39
|
exports.shellExecTool = {
|
|
23
40
|
schema: {
|
|
24
41
|
name: 'shell_exec',
|
|
@@ -43,6 +60,41 @@ exports.shellExecTool = {
|
|
|
43
60
|
category: 'execute',
|
|
44
61
|
mutates: true,
|
|
45
62
|
toolset: 'terminal',
|
|
63
|
+
riskTier: 'dangerous', // v4.4 Phase 1 — arbitrary shell command
|
|
64
|
+
// v4.4 Phase 4 — dry-run preview.
|
|
65
|
+
buildPreview(args, ctx) {
|
|
66
|
+
const command = String(args.command ?? args.cmd ?? '').trim();
|
|
67
|
+
const cwd = typeof args.cwd === 'string' ? args.cwd : ctx.cwd;
|
|
68
|
+
const config = (0, sandboxConfig_1.getSandboxConfig)();
|
|
69
|
+
const userOverride = ctx.terminalBackend;
|
|
70
|
+
const effective = userOverride ?? (config.enabled ? config.defaultBackend : 'local');
|
|
71
|
+
// Lightweight risk hints — same patterns ApprovalEngine uses
|
|
72
|
+
// in smart mode. Kept inline to avoid pulling moat/ into the
|
|
73
|
+
// tool layer.
|
|
74
|
+
const risks = [];
|
|
75
|
+
if (/\brm\s+-rf?\b/.test(command))
|
|
76
|
+
risks.push('rm -rf');
|
|
77
|
+
if (/sudo\b/.test(command))
|
|
78
|
+
risks.push('sudo');
|
|
79
|
+
if (/\bcurl\s.+\|\s*(sh|bash)/.test(command))
|
|
80
|
+
risks.push('curl|sh');
|
|
81
|
+
if (/\bwget\s.+\|\s*(sh|bash)/.test(command))
|
|
82
|
+
risks.push('wget|sh');
|
|
83
|
+
if (/\bdd\s+if=/.test(command))
|
|
84
|
+
risks.push('dd');
|
|
85
|
+
if (/:\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;\s*:/.test(command))
|
|
86
|
+
risks.push('fork bomb');
|
|
87
|
+
if (/format\s+[a-zA-Z]:/i.test(command))
|
|
88
|
+
risks.push('format');
|
|
89
|
+
return {
|
|
90
|
+
tool: 'shell_exec',
|
|
91
|
+
args,
|
|
92
|
+
riskTier: 'dangerous',
|
|
93
|
+
sideEffects: [{ type: 'shell_command', command, cwd, backend: effective }],
|
|
94
|
+
detectedRisks: risks,
|
|
95
|
+
summary: `Would run \`${command.length > 80 ? command.slice(0, 80) + '…' : command}\` via ${effective} backend in ${cwd}`,
|
|
96
|
+
};
|
|
97
|
+
},
|
|
46
98
|
async execute(args, ctx) {
|
|
47
99
|
const command = String(args.command ?? args.cmd ?? '').trim();
|
|
48
100
|
if (!command)
|
|
@@ -56,10 +108,30 @@ exports.shellExecTool = {
|
|
|
56
108
|
: true,
|
|
57
109
|
};
|
|
58
110
|
const cb = ctx.log ? { log: ctx.log } : {};
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
111
|
+
// v4.4 Phase 3 — effective backend selection.
|
|
112
|
+
const config = (0, sandboxConfig_1.getSandboxConfig)();
|
|
113
|
+
const userOverride = ctx.terminalBackend;
|
|
114
|
+
const effective = userOverride ?? (config.enabled ? config.defaultBackend : 'local');
|
|
115
|
+
let result;
|
|
116
|
+
if (effective === 'docker') {
|
|
117
|
+
if (config.enabled) {
|
|
118
|
+
// Long-lived session container + hardening flags.
|
|
119
|
+
result = await (0, dockerSession_1.dockerSessionExec)({
|
|
120
|
+
...shellArgs,
|
|
121
|
+
sessionId: ctx.sessionId,
|
|
122
|
+
image: ctx.dockerImage,
|
|
123
|
+
}, cb);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// Status-quo single-shot docker path (AIDEN_SANDBOX=0 +
|
|
127
|
+
// explicit ctx.terminalBackend='docker'). No reuse, no
|
|
128
|
+
// hardening — kept for backward compatibility.
|
|
129
|
+
result = await (0, docker_1.dockerBackendExecute)(shellArgs, { image: ctx.dockerImage }, cb);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
result = await (0, local_1.localBackendExecute)(shellArgs, cb);
|
|
134
|
+
}
|
|
63
135
|
return {
|
|
64
136
|
success: result.exitCode === 0,
|
|
65
137
|
exitCode: result.exitCode,
|