@phuetz/code-buddy 0.1.25 → 0.1.26
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 +1049 -741
- package/dist/agent/codebuddy-agent.d.ts +5 -0
- package/dist/agent/codebuddy-agent.js +46 -1
- package/dist/agent/codebuddy-agent.js.map +1 -1
- package/dist/agent/execution/agent-executor.d.ts +12 -0
- package/dist/agent/execution/agent-executor.js +147 -6
- package/dist/agent/execution/agent-executor.js.map +1 -1
- package/dist/agent/lessons-tracker.d.ts +50 -0
- package/dist/agent/lessons-tracker.js +234 -0
- package/dist/agent/lessons-tracker.js.map +1 -0
- package/dist/agent/message-queue.d.ts +39 -2
- package/dist/agent/message-queue.js +67 -2
- package/dist/agent/message-queue.js.map +1 -1
- package/dist/agent/middleware/index.d.ts +1 -0
- package/dist/agent/middleware/index.js +1 -0
- package/dist/agent/middleware/index.js.map +1 -1
- package/dist/agent/middleware/workflow-guard.d.ts +21 -0
- package/dist/agent/middleware/workflow-guard.js +94 -0
- package/dist/agent/middleware/workflow-guard.js.map +1 -0
- package/dist/agent/repo-profiler.d.ts +61 -0
- package/dist/agent/repo-profiler.js +295 -0
- package/dist/agent/repo-profiler.js.map +1 -0
- package/dist/agent/response-constraint.d.ts +61 -0
- package/dist/agent/response-constraint.js +91 -0
- package/dist/agent/response-constraint.js.map +1 -0
- package/dist/agent/todo-tracker.d.ts +67 -0
- package/dist/agent/todo-tracker.js +245 -0
- package/dist/agent/todo-tracker.js.map +1 -0
- package/dist/agent/tool-handler.d.ts +11 -0
- package/dist/agent/tool-handler.js +79 -1
- package/dist/agent/tool-handler.js.map +1 -1
- package/dist/agent/types.d.ts +20 -2
- package/dist/agent/wide-research.d.ts +93 -0
- package/dist/agent/wide-research.js +232 -0
- package/dist/agent/wide-research.js.map +1 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.js +2 -0
- package/dist/channels/index.js.map +1 -1
- package/dist/channels/pro/callback-router.d.ts +54 -0
- package/dist/channels/pro/callback-router.js +178 -0
- package/dist/channels/pro/callback-router.js.map +1 -0
- package/dist/channels/pro/ci-watcher.d.ts +86 -0
- package/dist/channels/pro/ci-watcher.js +343 -0
- package/dist/channels/pro/ci-watcher.js.map +1 -0
- package/dist/channels/pro/diff-first.d.ts +63 -0
- package/dist/channels/pro/diff-first.js +187 -0
- package/dist/channels/pro/diff-first.js.map +1 -0
- package/dist/channels/pro/enhanced-commands.d.ts +83 -0
- package/dist/channels/pro/enhanced-commands.js +218 -0
- package/dist/channels/pro/enhanced-commands.js.map +1 -0
- package/dist/channels/pro/index.d.ts +19 -0
- package/dist/channels/pro/index.js +21 -0
- package/dist/channels/pro/index.js.map +1 -0
- package/dist/channels/pro/pro-features.d.ts +79 -0
- package/dist/channels/pro/pro-features.js +203 -0
- package/dist/channels/pro/pro-features.js.map +1 -0
- package/dist/channels/pro/run-commands.d.ts +59 -0
- package/dist/channels/pro/run-commands.js +122 -0
- package/dist/channels/pro/run-commands.js.map +1 -0
- package/dist/channels/pro/run-tracker.d.ts +74 -0
- package/dist/channels/pro/run-tracker.js +252 -0
- package/dist/channels/pro/run-tracker.js.map +1 -0
- package/dist/channels/pro/scoped-auth.d.ts +97 -0
- package/dist/channels/pro/scoped-auth.js +340 -0
- package/dist/channels/pro/scoped-auth.js.map +1 -0
- package/dist/channels/pro/text-formatter.d.ts +27 -0
- package/dist/channels/pro/text-formatter.js +269 -0
- package/dist/channels/pro/text-formatter.js.map +1 -0
- package/dist/channels/pro/types.d.ts +242 -0
- package/dist/channels/pro/types.js +14 -0
- package/dist/channels/pro/types.js.map +1 -0
- package/dist/channels/streaming-policy.d.ts +66 -0
- package/dist/channels/streaming-policy.js +266 -0
- package/dist/channels/streaming-policy.js.map +1 -0
- package/dist/channels/telegram/ci-watcher.d.ts +5 -0
- package/dist/channels/telegram/ci-watcher.js +5 -0
- package/dist/channels/telegram/ci-watcher.js.map +1 -0
- package/dist/channels/telegram/client.d.ts +28 -0
- package/dist/channels/telegram/client.js +147 -1
- package/dist/channels/telegram/client.js.map +1 -1
- package/dist/channels/telegram/diff-first.d.ts +5 -0
- package/dist/channels/telegram/diff-first.js +5 -0
- package/dist/channels/telegram/diff-first.js.map +1 -0
- package/dist/channels/telegram/enhanced-commands.d.ts +6 -0
- package/dist/channels/telegram/enhanced-commands.js +6 -0
- package/dist/channels/telegram/enhanced-commands.js.map +1 -0
- package/dist/channels/telegram/index.d.ts +6 -0
- package/dist/channels/telegram/index.js +6 -0
- package/dist/channels/telegram/index.js.map +1 -1
- package/dist/channels/telegram/pro-formatter.d.ts +30 -0
- package/dist/channels/telegram/pro-formatter.js +276 -0
- package/dist/channels/telegram/pro-formatter.js.map +1 -0
- package/dist/channels/telegram/run-commands.d.ts +5 -0
- package/dist/channels/telegram/run-commands.js +6 -0
- package/dist/channels/telegram/run-commands.js.map +1 -0
- package/dist/channels/telegram/run-tracker.d.ts +5 -0
- package/dist/channels/telegram/run-tracker.js +5 -0
- package/dist/channels/telegram/run-tracker.js.map +1 -0
- package/dist/channels/telegram/scoped-auth.d.ts +6 -0
- package/dist/channels/telegram/scoped-auth.js +5 -0
- package/dist/channels/telegram/scoped-auth.js.map +1 -0
- package/dist/channels/telegram/types.d.ts +34 -0
- package/dist/codebuddy/client.js +14 -1
- package/dist/codebuddy/client.js.map +1 -1
- package/dist/commands/dev/index.d.ts +12 -0
- package/dist/commands/dev/index.js +231 -0
- package/dist/commands/dev/index.js.map +1 -0
- package/dist/commands/dev/workflows.d.ts +31 -0
- package/dist/commands/dev/workflows.js +214 -0
- package/dist/commands/dev/workflows.js.map +1 -0
- package/dist/commands/execpolicy.d.ts +17 -0
- package/dist/commands/execpolicy.js +155 -0
- package/dist/commands/execpolicy.js.map +1 -0
- package/dist/commands/knowledge.d.ts +13 -0
- package/dist/commands/knowledge.js +142 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/lessons.d.ts +11 -0
- package/dist/commands/lessons.js +129 -0
- package/dist/commands/lessons.js.map +1 -0
- package/dist/commands/pairing.d.ts +14 -0
- package/dist/commands/pairing.js +132 -0
- package/dist/commands/pairing.js.map +1 -0
- package/dist/commands/research/index.d.ts +13 -0
- package/dist/commands/research/index.js +91 -0
- package/dist/commands/research/index.js.map +1 -0
- package/dist/commands/run-cli/index.d.ts +11 -0
- package/dist/commands/run-cli/index.js +49 -0
- package/dist/commands/run-cli/index.js.map +1 -0
- package/dist/commands/todos.d.ts +9 -0
- package/dist/commands/todos.js +119 -0
- package/dist/commands/todos.js.map +1 -0
- package/dist/config/toml-config.d.ts +21 -0
- package/dist/config/toml-config.js +15 -0
- package/dist/config/toml-config.js.map +1 -1
- package/dist/context/enhanced-compression.js +12 -1
- package/dist/context/enhanced-compression.js.map +1 -1
- package/dist/context/observation-variator.d.ts +44 -0
- package/dist/context/observation-variator.js +83 -0
- package/dist/context/observation-variator.js.map +1 -0
- package/dist/context/precompaction-flush.d.ts +40 -0
- package/dist/context/precompaction-flush.js +134 -0
- package/dist/context/precompaction-flush.js.map +1 -0
- package/dist/context/restorable-compression.d.ts +80 -0
- package/dist/context/restorable-compression.js +228 -0
- package/dist/context/restorable-compression.js.map +1 -0
- package/dist/daemon/daily-reset.d.ts +77 -0
- package/dist/daemon/daily-reset.js +175 -0
- package/dist/daemon/daily-reset.js.map +1 -0
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.js +1 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -1
- package/dist/knowledge/knowledge-manager.d.ts +77 -0
- package/dist/knowledge/knowledge-manager.js +244 -0
- package/dist/knowledge/knowledge-manager.js.map +1 -0
- package/dist/observability/run-store.d.ts +133 -0
- package/dist/observability/run-store.js +419 -0
- package/dist/observability/run-store.js.map +1 -0
- package/dist/observability/run-viewer.d.ts +33 -0
- package/dist/observability/run-viewer.js +254 -0
- package/dist/observability/run-viewer.js.map +1 -0
- package/dist/optimization/cache-breakpoints.d.ts +52 -0
- package/dist/optimization/cache-breakpoints.js +97 -0
- package/dist/optimization/cache-breakpoints.js.map +1 -0
- package/dist/persistence/session-store.d.ts +3 -1
- package/dist/persistence/session-store.js +1 -1
- package/dist/persistence/session-store.js.map +1 -1
- package/dist/prompts/system-base.js +51 -7
- package/dist/prompts/system-base.js.map +1 -1
- package/dist/prompts/variation-injector.d.ts +55 -0
- package/dist/prompts/variation-injector.js +171 -0
- package/dist/prompts/variation-injector.js.map +1 -0
- package/dist/prompts/workflow-rules.d.ts +10 -0
- package/dist/prompts/workflow-rules.js +79 -0
- package/dist/prompts/workflow-rules.js.map +1 -0
- package/dist/sandbox/execpolicy.d.ts +45 -0
- package/dist/sandbox/execpolicy.js +80 -0
- package/dist/sandbox/execpolicy.js.map +1 -1
- package/dist/sandbox/os-sandbox.d.ts +25 -0
- package/dist/sandbox/os-sandbox.js +73 -0
- package/dist/sandbox/os-sandbox.js.map +1 -1
- package/dist/security/security-audit.d.ts +10 -0
- package/dist/security/security-audit.js +116 -0
- package/dist/security/security-audit.js.map +1 -1
- package/dist/security/shell-env-policy.d.ts +45 -0
- package/dist/security/shell-env-policy.js +141 -0
- package/dist/security/shell-env-policy.js.map +1 -0
- package/dist/security/ssrf-guard.d.ts +61 -0
- package/dist/security/ssrf-guard.js +382 -0
- package/dist/security/ssrf-guard.js.map +1 -0
- package/dist/security/write-policy.d.ts +57 -0
- package/dist/security/write-policy.js +117 -0
- package/dist/security/write-policy.js.map +1 -0
- package/dist/services/prompt-builder.js +37 -0
- package/dist/services/prompt-builder.js.map +1 -1
- package/dist/themes/theme-schema.d.ts +10 -10
- package/dist/tools/ask-human-tool.d.ts +62 -0
- package/dist/tools/ask-human-tool.js +112 -0
- package/dist/tools/ask-human-tool.js.map +1 -0
- package/dist/tools/bash/bash-tool.d.ts +15 -0
- package/dist/tools/bash/bash-tool.js +62 -0
- package/dist/tools/bash/bash-tool.js.map +1 -1
- package/dist/tools/bash/command-validator.d.ts +1 -0
- package/dist/tools/bash/command-validator.js +5 -0
- package/dist/tools/bash/command-validator.js.map +1 -1
- package/dist/tools/create-skill-tool.d.ts +87 -0
- package/dist/tools/create-skill-tool.js +142 -0
- package/dist/tools/create-skill-tool.js.map +1 -0
- package/dist/tools/fetch-tool.js +5 -3
- package/dist/tools/fetch-tool.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/plan-tool.d.ts +22 -0
- package/dist/tools/plan-tool.js +128 -0
- package/dist/tools/plan-tool.js.map +1 -0
- package/dist/tools/registry/attention-tools.d.ts +32 -0
- package/dist/tools/registry/attention-tools.js +225 -0
- package/dist/tools/registry/attention-tools.js.map +1 -0
- package/dist/tools/registry/index.d.ts +9 -1
- package/dist/tools/registry/index.js +30 -2
- package/dist/tools/registry/index.js.map +1 -1
- package/dist/tools/registry/knowledge-tools.d.ts +46 -0
- package/dist/tools/registry/knowledge-tools.js +293 -0
- package/dist/tools/registry/knowledge-tools.js.map +1 -0
- package/dist/tools/registry/lessons-tools.d.ts +48 -0
- package/dist/tools/registry/lessons-tools.js +359 -0
- package/dist/tools/registry/lessons-tools.js.map +1 -0
- package/dist/tools/registry/plan-tools.d.ts +2 -0
- package/dist/tools/registry/plan-tools.js +7 -0
- package/dist/tools/registry/plan-tools.js.map +1 -0
- package/dist/tools/registry/script-tools.d.ts +2 -0
- package/dist/tools/registry/script-tools.js +7 -0
- package/dist/tools/registry/script-tools.js.map +1 -0
- package/dist/tools/registry/tool-aliases.d.ts +44 -0
- package/dist/tools/registry/tool-aliases.js +130 -0
- package/dist/tools/registry/tool-aliases.js.map +1 -0
- package/dist/tools/run-script-tool.d.ts +13 -0
- package/dist/tools/run-script-tool.js +146 -0
- package/dist/tools/run-script-tool.js.map +1 -0
- package/dist/tools/web-search.d.ts +25 -0
- package/dist/tools/web-search.js +68 -6
- package/dist/tools/web-search.js.map +1 -1
- package/dist/utils/config-validation/schema.d.ts +2 -2
- package/dist/utils/debug-logger.d.ts +1 -1
- package/dist/utils/stable-json.d.ts +27 -0
- package/dist/utils/stable-json.js +50 -0
- package/dist/utils/stable-json.js.map +1 -0
- package/dist/webhooks/webhook-manager.d.ts +7 -0
- package/dist/webhooks/webhook-manager.js +29 -0
- package/dist/webhooks/webhook-manager.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoped Authorization Manager
|
|
3
|
+
*
|
|
4
|
+
* Enterprise-grade permission model for channel interactions.
|
|
5
|
+
* Supports tiered scopes, secret handles, temporary access, and double confirmation.
|
|
6
|
+
* Channel-agnostic - works with any channel adapter.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
import os from 'os';
|
|
11
|
+
import { randomBytes } from 'crypto';
|
|
12
|
+
import { SCOPE_LEVEL } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Manages scoped authorization for channel users.
|
|
15
|
+
*/
|
|
16
|
+
export class ScopedAuthManager {
|
|
17
|
+
permissions = new Map();
|
|
18
|
+
secrets = new Map();
|
|
19
|
+
temporaryAccess = new Map();
|
|
20
|
+
pendingConfirms = new Map();
|
|
21
|
+
configPath;
|
|
22
|
+
adminUsers;
|
|
23
|
+
/** Confirmation timeout in ms (default 2 minutes) */
|
|
24
|
+
confirmTimeoutMs = 120_000;
|
|
25
|
+
constructor(adminUsers = [], configDir) {
|
|
26
|
+
const dir = configDir || join(os.homedir(), '.codebuddy');
|
|
27
|
+
this.configPath = join(dir, 'channel-scoped-auth.json');
|
|
28
|
+
this.adminUsers = new Set(adminUsers);
|
|
29
|
+
this.load();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if a user has the required scope
|
|
33
|
+
*/
|
|
34
|
+
checkScope(userId, scope, context) {
|
|
35
|
+
if (this.adminUsers.has(userId)) {
|
|
36
|
+
return { allowed: true };
|
|
37
|
+
}
|
|
38
|
+
const tempAccess = this.temporaryAccess.get(userId);
|
|
39
|
+
if (tempAccess && Date.now() < tempAccess.expiresAt) {
|
|
40
|
+
return { allowed: true };
|
|
41
|
+
}
|
|
42
|
+
if (tempAccess && Date.now() >= tempAccess.expiresAt) {
|
|
43
|
+
this.temporaryAccess.delete(userId);
|
|
44
|
+
this.save();
|
|
45
|
+
}
|
|
46
|
+
const perm = this.permissions.get(userId);
|
|
47
|
+
if (!perm) {
|
|
48
|
+
return {
|
|
49
|
+
allowed: false,
|
|
50
|
+
reason: 'No permissions configured for this user',
|
|
51
|
+
requiredScope: scope,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (perm.expiresAt && new Date(perm.expiresAt).getTime() < Date.now()) {
|
|
55
|
+
return {
|
|
56
|
+
allowed: false,
|
|
57
|
+
reason: 'Permissions have expired',
|
|
58
|
+
requiredScope: scope,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const hasScope = perm.scopes.some((s) => SCOPE_LEVEL[s] >= SCOPE_LEVEL[scope]);
|
|
62
|
+
if (!hasScope) {
|
|
63
|
+
return {
|
|
64
|
+
allowed: false,
|
|
65
|
+
reason: `Requires '${scope}' scope`,
|
|
66
|
+
requiredScope: scope,
|
|
67
|
+
userScopes: perm.scopes,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (context?.command && perm.denyCommands.length > 0) {
|
|
71
|
+
const denied = perm.denyCommands.some((pattern) => {
|
|
72
|
+
if (pattern.includes('*')) {
|
|
73
|
+
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
|
74
|
+
return regex.test(context.command);
|
|
75
|
+
}
|
|
76
|
+
return context.command === pattern;
|
|
77
|
+
});
|
|
78
|
+
if (denied) {
|
|
79
|
+
return {
|
|
80
|
+
allowed: false,
|
|
81
|
+
reason: `Command '${context.command}' is denied`,
|
|
82
|
+
requiredScope: scope,
|
|
83
|
+
userScopes: perm.scopes,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (context?.repo && perm.repos.length > 0) {
|
|
88
|
+
const repoAllowed = perm.repos.some((pattern) => {
|
|
89
|
+
if (pattern === '*')
|
|
90
|
+
return true;
|
|
91
|
+
if (pattern.includes('*')) {
|
|
92
|
+
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
|
93
|
+
return regex.test(context.repo);
|
|
94
|
+
}
|
|
95
|
+
return context.repo === pattern;
|
|
96
|
+
});
|
|
97
|
+
if (!repoAllowed) {
|
|
98
|
+
return {
|
|
99
|
+
allowed: false,
|
|
100
|
+
reason: `Repo '${context.repo}' not in allowed list`,
|
|
101
|
+
requiredScope: scope,
|
|
102
|
+
userScopes: perm.scopes,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (context?.folder && perm.folders.length > 0) {
|
|
107
|
+
const folderAllowed = perm.folders.some((pattern) => {
|
|
108
|
+
if (pattern === '*' || pattern === '**')
|
|
109
|
+
return true;
|
|
110
|
+
if (pattern.includes('*')) {
|
|
111
|
+
const regex = new RegExp('^' + pattern.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*') + '$');
|
|
112
|
+
return regex.test(context.folder);
|
|
113
|
+
}
|
|
114
|
+
return context.folder.startsWith(pattern);
|
|
115
|
+
});
|
|
116
|
+
if (!folderAllowed) {
|
|
117
|
+
return {
|
|
118
|
+
allowed: false,
|
|
119
|
+
reason: `Folder '${context.folder}' not in allowed list`,
|
|
120
|
+
requiredScope: scope,
|
|
121
|
+
userScopes: perm.scopes,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { allowed: true, userScopes: perm.scopes };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Grant scopes to a user
|
|
129
|
+
*/
|
|
130
|
+
grantScope(userId, scopes, options) {
|
|
131
|
+
const perm = {
|
|
132
|
+
userId,
|
|
133
|
+
scopes,
|
|
134
|
+
repos: options?.repos || ['*'],
|
|
135
|
+
folders: options?.folders || ['**'],
|
|
136
|
+
denyCommands: options?.denyCommands || [],
|
|
137
|
+
grantedAt: new Date().toISOString(),
|
|
138
|
+
grantedBy: options?.grantedBy,
|
|
139
|
+
};
|
|
140
|
+
if (options?.ttlMs) {
|
|
141
|
+
perm.expiresAt = new Date(Date.now() + options.ttlMs).toISOString();
|
|
142
|
+
}
|
|
143
|
+
this.permissions.set(userId, perm);
|
|
144
|
+
this.save();
|
|
145
|
+
return perm;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Revoke all scopes from a user
|
|
149
|
+
*/
|
|
150
|
+
revokeScope(userId) {
|
|
151
|
+
const deleted = this.permissions.delete(userId);
|
|
152
|
+
if (deleted) {
|
|
153
|
+
this.save();
|
|
154
|
+
}
|
|
155
|
+
return deleted;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get permissions for a user
|
|
159
|
+
*/
|
|
160
|
+
getPermission(userId) {
|
|
161
|
+
return this.permissions.get(userId);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* List all permissions
|
|
165
|
+
*/
|
|
166
|
+
listPermissions() {
|
|
167
|
+
return Array.from(this.permissions.values());
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Register a secret handle (maps friendly name to env var)
|
|
171
|
+
*/
|
|
172
|
+
registerSecret(handle, envVar, description) {
|
|
173
|
+
const secret = {
|
|
174
|
+
handle,
|
|
175
|
+
envVar,
|
|
176
|
+
description,
|
|
177
|
+
addedAt: new Date().toISOString(),
|
|
178
|
+
};
|
|
179
|
+
this.secrets.set(handle, secret);
|
|
180
|
+
this.save();
|
|
181
|
+
return secret;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Resolve a secret handle to its value (from env)
|
|
185
|
+
*/
|
|
186
|
+
resolveSecret(handle) {
|
|
187
|
+
const secret = this.secrets.get(handle);
|
|
188
|
+
if (!secret)
|
|
189
|
+
return undefined;
|
|
190
|
+
return process.env[secret.envVar];
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* List secret handles (never exposes values)
|
|
194
|
+
*/
|
|
195
|
+
listHandles() {
|
|
196
|
+
return Array.from(this.secrets.values()).map((s) => ({
|
|
197
|
+
handle: s.handle,
|
|
198
|
+
description: s.description,
|
|
199
|
+
hasValue: !!process.env[s.envVar],
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Remove a secret handle
|
|
204
|
+
*/
|
|
205
|
+
removeSecret(handle) {
|
|
206
|
+
const deleted = this.secrets.delete(handle);
|
|
207
|
+
if (deleted) {
|
|
208
|
+
this.save();
|
|
209
|
+
}
|
|
210
|
+
return deleted;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Grant temporary full access to a user
|
|
214
|
+
*/
|
|
215
|
+
grantTemporaryFullAccess(userId, durationMs, grantedBy) {
|
|
216
|
+
const access = {
|
|
217
|
+
userId,
|
|
218
|
+
grantedAt: Date.now(),
|
|
219
|
+
expiresAt: Date.now() + durationMs,
|
|
220
|
+
grantedBy,
|
|
221
|
+
};
|
|
222
|
+
this.temporaryAccess.set(userId, access);
|
|
223
|
+
this.save();
|
|
224
|
+
return access;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Revoke temporary access
|
|
228
|
+
*/
|
|
229
|
+
revokeTemporaryAccess(userId) {
|
|
230
|
+
const deleted = this.temporaryAccess.delete(userId);
|
|
231
|
+
if (deleted) {
|
|
232
|
+
this.save();
|
|
233
|
+
}
|
|
234
|
+
return deleted;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Require double confirmation for a risky operation
|
|
238
|
+
*/
|
|
239
|
+
requireDoubleConfirm(userId, operation, details) {
|
|
240
|
+
const confirm = {
|
|
241
|
+
id: randomBytes(3).toString('hex'),
|
|
242
|
+
userId,
|
|
243
|
+
operation,
|
|
244
|
+
details,
|
|
245
|
+
createdAt: Date.now(),
|
|
246
|
+
expiresAt: Date.now() + this.confirmTimeoutMs,
|
|
247
|
+
};
|
|
248
|
+
this.pendingConfirms.set(confirm.id, confirm);
|
|
249
|
+
return confirm;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Verify a double confirmation
|
|
253
|
+
*/
|
|
254
|
+
verifyDoubleConfirm(confirmId, userId) {
|
|
255
|
+
const confirm = this.pendingConfirms.get(confirmId);
|
|
256
|
+
if (!confirm) {
|
|
257
|
+
return { valid: false, reason: 'Confirmation not found' };
|
|
258
|
+
}
|
|
259
|
+
if (confirm.userId !== userId) {
|
|
260
|
+
return { valid: false, reason: 'Confirmation belongs to a different user' };
|
|
261
|
+
}
|
|
262
|
+
if (Date.now() > confirm.expiresAt) {
|
|
263
|
+
this.pendingConfirms.delete(confirmId);
|
|
264
|
+
return { valid: false, reason: 'Confirmation has expired' };
|
|
265
|
+
}
|
|
266
|
+
this.pendingConfirms.delete(confirmId);
|
|
267
|
+
return { valid: true };
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Check if user is an admin
|
|
271
|
+
*/
|
|
272
|
+
isAdmin(userId) {
|
|
273
|
+
return this.adminUsers.has(userId);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Clean up expired entries
|
|
277
|
+
*/
|
|
278
|
+
cleanup() {
|
|
279
|
+
const now = Date.now();
|
|
280
|
+
for (const [userId, perm] of this.permissions) {
|
|
281
|
+
if (perm.expiresAt && new Date(perm.expiresAt).getTime() < now) {
|
|
282
|
+
this.permissions.delete(userId);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
for (const [userId, access] of this.temporaryAccess) {
|
|
286
|
+
if (now >= access.expiresAt) {
|
|
287
|
+
this.temporaryAccess.delete(userId);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
for (const [id, confirm] of this.pendingConfirms) {
|
|
291
|
+
if (now > confirm.expiresAt) {
|
|
292
|
+
this.pendingConfirms.delete(id);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
this.save();
|
|
296
|
+
}
|
|
297
|
+
load() {
|
|
298
|
+
try {
|
|
299
|
+
if (existsSync(this.configPath)) {
|
|
300
|
+
const data = JSON.parse(readFileSync(this.configPath, 'utf-8'));
|
|
301
|
+
if (data.permissions) {
|
|
302
|
+
for (const perm of data.permissions) {
|
|
303
|
+
this.permissions.set(perm.userId, perm);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (data.secrets) {
|
|
307
|
+
for (const secret of data.secrets) {
|
|
308
|
+
this.secrets.set(secret.handle, secret);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (data.temporaryAccess) {
|
|
312
|
+
for (const access of data.temporaryAccess) {
|
|
313
|
+
this.temporaryAccess.set(access.userId, access);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// Start fresh on load failure
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
save() {
|
|
323
|
+
try {
|
|
324
|
+
const dir = dirname(this.configPath);
|
|
325
|
+
if (!existsSync(dir)) {
|
|
326
|
+
mkdirSync(dir, { recursive: true });
|
|
327
|
+
}
|
|
328
|
+
const state = {
|
|
329
|
+
permissions: Array.from(this.permissions.values()),
|
|
330
|
+
secrets: Array.from(this.secrets.values()),
|
|
331
|
+
temporaryAccess: Array.from(this.temporaryAccess.values()),
|
|
332
|
+
};
|
|
333
|
+
writeFileSync(this.configPath, JSON.stringify(state, null, 2));
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
// Silently fail on save errors
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=scoped-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoped-auth.js","sourceRoot":"","sources":["../../../src/channels/pro/scoped-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Text Formatter
|
|
3
|
+
*
|
|
4
|
+
* Plain-text implementation of ChannelProFormatter.
|
|
5
|
+
* Works with any channel adapter. Uses `pro:<feature>:<action>:<id>`
|
|
6
|
+
* callback data scheme for buttons.
|
|
7
|
+
*/
|
|
8
|
+
import type { ChannelProFormatter, ProFormattedMessage, CommandEntry, PendingDiff, RunRecord, RunStep, CIEvent, RepoInfo, BranchInfo, PRInfo, PRSummary } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Default text-based formatter for pro features.
|
|
11
|
+
* Any channel without a custom formatter gets this automatically.
|
|
12
|
+
*/
|
|
13
|
+
export declare class TextProFormatter implements ChannelProFormatter {
|
|
14
|
+
formatDiffMessage(pending: PendingDiff): ProFormattedMessage;
|
|
15
|
+
formatFullDiff(pending: PendingDiff): string;
|
|
16
|
+
formatPlanMessage(plan: string, filesTouched: string[], commands: string[]): ProFormattedMessage;
|
|
17
|
+
formatRunsList(runs: RunRecord[]): ProFormattedMessage;
|
|
18
|
+
formatRunTimeline(run: RunRecord): ProFormattedMessage;
|
|
19
|
+
formatRunDetail(run: RunRecord, testSteps: RunStep[], commitRefs: string[]): ProFormattedMessage;
|
|
20
|
+
formatCIAlert(event: CIEvent, analysis?: string): ProFormattedMessage;
|
|
21
|
+
formatRepoInfo(info: RepoInfo): ProFormattedMessage;
|
|
22
|
+
formatBranchInfo(info: BranchInfo): ProFormattedMessage;
|
|
23
|
+
formatPRInfo(pr: PRInfo): ProFormattedMessage;
|
|
24
|
+
formatPRList(prs: PRSummary[]): ProFormattedMessage;
|
|
25
|
+
getCommandList(): CommandEntry[];
|
|
26
|
+
private getActionIcon;
|
|
27
|
+
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Text Formatter
|
|
3
|
+
*
|
|
4
|
+
* Plain-text implementation of ChannelProFormatter.
|
|
5
|
+
* Works with any channel adapter. Uses `pro:<feature>:<action>:<id>`
|
|
6
|
+
* callback data scheme for buttons.
|
|
7
|
+
*/
|
|
8
|
+
import { RunTracker } from './run-tracker.js';
|
|
9
|
+
import { CIWatcher } from './ci-watcher.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default text-based formatter for pro features.
|
|
12
|
+
* Any channel without a custom formatter gets this automatically.
|
|
13
|
+
*/
|
|
14
|
+
export class TextProFormatter {
|
|
15
|
+
formatDiffMessage(pending) {
|
|
16
|
+
const lines = [];
|
|
17
|
+
const totalAdded = pending.diffs.reduce((sum, d) => sum + d.linesAdded, 0);
|
|
18
|
+
const totalRemoved = pending.diffs.reduce((sum, d) => sum + d.linesRemoved, 0);
|
|
19
|
+
lines.push(`Code Changes (Turn #${pending.turnId})`);
|
|
20
|
+
lines.push(`${pending.diffs.length} file(s) | +${totalAdded} -${totalRemoved}`);
|
|
21
|
+
lines.push('');
|
|
22
|
+
for (const diff of pending.diffs) {
|
|
23
|
+
const icon = this.getActionIcon(diff.action);
|
|
24
|
+
lines.push(`${icon} ${diff.path}`);
|
|
25
|
+
lines.push(` +${diff.linesAdded} -${diff.linesRemoved}`);
|
|
26
|
+
if (diff.excerpt) {
|
|
27
|
+
const excerptLines = diff.excerpt.split('\n');
|
|
28
|
+
const maxLines = Math.min(excerptLines.length, 30);
|
|
29
|
+
for (let i = 0; i < maxLines; i++) {
|
|
30
|
+
lines.push(` ${excerptLines[i]}`);
|
|
31
|
+
}
|
|
32
|
+
if (excerptLines.length > maxLines) {
|
|
33
|
+
lines.push(` ... (${excerptLines.length - maxLines} more lines)`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
lines.push('');
|
|
37
|
+
}
|
|
38
|
+
const buttons = [
|
|
39
|
+
{ text: 'Apply', type: 'callback', data: `pro:diff:apply:${pending.id}` },
|
|
40
|
+
{ text: 'Full Diff', type: 'callback', data: `pro:diff:view:${pending.id}` },
|
|
41
|
+
{ text: 'Cancel', type: 'callback', data: `pro:diff:cancel:${pending.id}` },
|
|
42
|
+
];
|
|
43
|
+
return { text: lines.join('\n'), buttons };
|
|
44
|
+
}
|
|
45
|
+
formatFullDiff(pending) {
|
|
46
|
+
if (pending.fullDiff) {
|
|
47
|
+
return pending.fullDiff;
|
|
48
|
+
}
|
|
49
|
+
const lines = [];
|
|
50
|
+
for (const diff of pending.diffs) {
|
|
51
|
+
lines.push(`--- a/${diff.path}`);
|
|
52
|
+
lines.push(`+++ b/${diff.path}`);
|
|
53
|
+
if (diff.excerpt) {
|
|
54
|
+
lines.push(diff.excerpt);
|
|
55
|
+
}
|
|
56
|
+
lines.push('');
|
|
57
|
+
}
|
|
58
|
+
return lines.join('\n');
|
|
59
|
+
}
|
|
60
|
+
formatPlanMessage(plan, filesTouched, commands) {
|
|
61
|
+
const lines = [];
|
|
62
|
+
lines.push('Execution Plan');
|
|
63
|
+
lines.push('');
|
|
64
|
+
lines.push(plan);
|
|
65
|
+
lines.push('');
|
|
66
|
+
if (filesTouched.length > 0) {
|
|
67
|
+
lines.push(`Files: ${filesTouched.join(', ')}`);
|
|
68
|
+
}
|
|
69
|
+
if (commands.length > 0) {
|
|
70
|
+
lines.push(`Commands: ${commands.join(', ')}`);
|
|
71
|
+
}
|
|
72
|
+
const buttons = [
|
|
73
|
+
{ text: 'Approve Plan', type: 'callback', data: `pro:plan:approve:${Date.now().toString(36)}` },
|
|
74
|
+
{ text: 'Reject', type: 'callback', data: `pro:plan:reject:${Date.now().toString(36)}` },
|
|
75
|
+
];
|
|
76
|
+
return { text: lines.join('\n'), buttons };
|
|
77
|
+
}
|
|
78
|
+
formatRunsList(runs) {
|
|
79
|
+
if (runs.length === 0) {
|
|
80
|
+
return { text: 'No runs recorded yet.' };
|
|
81
|
+
}
|
|
82
|
+
const lines = ['Recent Runs:', ''];
|
|
83
|
+
for (const run of runs) {
|
|
84
|
+
const statusIcon = RunTracker.getStatusIcon(run.status);
|
|
85
|
+
const duration = RunTracker.formatDuration(run.startedAt, run.endedAt);
|
|
86
|
+
const cost = run.totalCost > 0 ? ` | $${run.totalCost.toFixed(4)}` : '';
|
|
87
|
+
lines.push(`${statusIcon} ${run.id.slice(0, 16)}`);
|
|
88
|
+
lines.push(` ${RunTracker.truncate(run.objective, 60)}`);
|
|
89
|
+
lines.push(` ${run.steps.length} steps | ${duration}${cost}`);
|
|
90
|
+
lines.push('');
|
|
91
|
+
}
|
|
92
|
+
const buttons = runs.slice(0, 5).map((run) => ({
|
|
93
|
+
text: `Details: ${run.id.slice(0, 12)}`,
|
|
94
|
+
type: 'callback',
|
|
95
|
+
data: `pro:run:detail:${run.id.slice(0, 16)}`,
|
|
96
|
+
}));
|
|
97
|
+
return { text: lines.join('\n'), buttons: buttons.length > 0 ? buttons : undefined };
|
|
98
|
+
}
|
|
99
|
+
formatRunTimeline(run) {
|
|
100
|
+
const lines = [];
|
|
101
|
+
const statusIcon = RunTracker.getStatusIcon(run.status);
|
|
102
|
+
const duration = RunTracker.formatDuration(run.startedAt, run.endedAt);
|
|
103
|
+
lines.push(`${statusIcon} Run: ${run.id}`);
|
|
104
|
+
lines.push(`Objective: ${run.objective}`);
|
|
105
|
+
lines.push(`Status: ${run.status} | Duration: ${duration}`);
|
|
106
|
+
if (run.totalCost > 0) {
|
|
107
|
+
lines.push(`Tokens: ${run.tokenCount} | Cost: $${run.totalCost.toFixed(4)}`);
|
|
108
|
+
}
|
|
109
|
+
lines.push('');
|
|
110
|
+
lines.push('Timeline:');
|
|
111
|
+
for (const step of run.steps) {
|
|
112
|
+
const stepDuration = step.endedAt
|
|
113
|
+
? RunTracker.formatDuration(step.startedAt, step.endedAt)
|
|
114
|
+
: 'running...';
|
|
115
|
+
const icon = step.success === true ? '[OK]' : step.success === false ? '[FAIL]' : '[...]';
|
|
116
|
+
lines.push(` ${icon} ${step.toolName} (${stepDuration})`);
|
|
117
|
+
const argsStr = RunTracker.formatArgs(step.args);
|
|
118
|
+
if (argsStr) {
|
|
119
|
+
lines.push(` ${argsStr}`);
|
|
120
|
+
}
|
|
121
|
+
if (step.filesChanged && step.filesChanged.length > 0) {
|
|
122
|
+
lines.push(` Files: ${step.filesChanged.join(', ')}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (run.artifacts.length > 0) {
|
|
126
|
+
lines.push('');
|
|
127
|
+
lines.push('Artifacts:');
|
|
128
|
+
for (const art of run.artifacts) {
|
|
129
|
+
const ref = art.ref ? ` (${art.ref})` : '';
|
|
130
|
+
const artPath = art.path ? ` ${art.path}` : '';
|
|
131
|
+
lines.push(` [${art.type}]${artPath}${ref} - ${art.description}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { text: lines.join('\n') };
|
|
135
|
+
}
|
|
136
|
+
formatRunDetail(run, testSteps, commitRefs) {
|
|
137
|
+
const formatted = this.formatRunTimeline(run);
|
|
138
|
+
const buttons = [];
|
|
139
|
+
if (run.status !== 'running') {
|
|
140
|
+
buttons.push({
|
|
141
|
+
text: 'Re-run',
|
|
142
|
+
type: 'callback',
|
|
143
|
+
data: `pro:run:rerun:${run.id.slice(0, 16)}`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (testSteps.length > 0) {
|
|
147
|
+
buttons.push({
|
|
148
|
+
text: 'Tests',
|
|
149
|
+
type: 'callback',
|
|
150
|
+
data: `pro:run:tests:${run.id.slice(0, 16)}`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (commitRefs.length > 0 && run.status !== 'rolled_back') {
|
|
154
|
+
buttons.push({
|
|
155
|
+
text: 'Rollback',
|
|
156
|
+
type: 'callback',
|
|
157
|
+
data: `pro:run:rollback:${run.id.slice(0, 16)}`,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
text: formatted.text,
|
|
162
|
+
buttons: buttons.length > 0 ? buttons : undefined,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
formatCIAlert(event, analysis) {
|
|
166
|
+
const severityIcon = CIWatcher.getSeverityIcon(event.severity);
|
|
167
|
+
const lines = [];
|
|
168
|
+
lines.push(`${severityIcon} CI Alert: ${event.title}`);
|
|
169
|
+
lines.push(`Repo: ${event.repo} | Branch: ${event.branch}`);
|
|
170
|
+
if (event.commit) {
|
|
171
|
+
lines.push(`Commit: ${event.commit}`);
|
|
172
|
+
}
|
|
173
|
+
lines.push('');
|
|
174
|
+
lines.push(event.details.slice(0, 500));
|
|
175
|
+
if (analysis) {
|
|
176
|
+
lines.push('');
|
|
177
|
+
lines.push('Analysis:');
|
|
178
|
+
lines.push(analysis.slice(0, 300));
|
|
179
|
+
}
|
|
180
|
+
const buttons = [
|
|
181
|
+
{ text: 'Fix it', type: 'callback', data: `pro:ci:fix:${event.id}` },
|
|
182
|
+
{ text: 'Mute', type: 'callback', data: `pro:ci:mute:${event.id}` },
|
|
183
|
+
];
|
|
184
|
+
if (event.logUrl) {
|
|
185
|
+
buttons.splice(1, 0, { text: 'Logs', type: 'url', url: event.logUrl });
|
|
186
|
+
}
|
|
187
|
+
return { text: lines.join('\n'), buttons };
|
|
188
|
+
}
|
|
189
|
+
formatRepoInfo(info) {
|
|
190
|
+
const lines = [];
|
|
191
|
+
lines.push('Repository Info');
|
|
192
|
+
lines.push(`Remote: ${info.remote}`);
|
|
193
|
+
lines.push(`Branch: ${info.branch}`);
|
|
194
|
+
lines.push(`Commits: ${info.commitCount}`);
|
|
195
|
+
lines.push(`Latest: ${info.lastCommit}`);
|
|
196
|
+
if (info.recentCommits) {
|
|
197
|
+
lines.push('');
|
|
198
|
+
lines.push('Recent Commits:');
|
|
199
|
+
lines.push(info.recentCommits);
|
|
200
|
+
}
|
|
201
|
+
if (info.openPRs) {
|
|
202
|
+
lines.push('');
|
|
203
|
+
lines.push(`Open PRs: ~${info.openPRs}`);
|
|
204
|
+
}
|
|
205
|
+
return { text: lines.join('\n') };
|
|
206
|
+
}
|
|
207
|
+
formatBranchInfo(info) {
|
|
208
|
+
const lines = [];
|
|
209
|
+
lines.push(`Branch: ${info.branch}`);
|
|
210
|
+
if (info.diffStat) {
|
|
211
|
+
lines.push('');
|
|
212
|
+
lines.push(`Changes vs ${info.mainBranch}:`);
|
|
213
|
+
lines.push(info.diffStat);
|
|
214
|
+
}
|
|
215
|
+
lines.push('');
|
|
216
|
+
lines.push(`Ahead: ${info.commitsAhead} | Behind: ${info.commitsBehind}`);
|
|
217
|
+
return { text: lines.join('\n') };
|
|
218
|
+
}
|
|
219
|
+
formatPRInfo(pr) {
|
|
220
|
+
const lines = [
|
|
221
|
+
`PR #${pr.number}: ${pr.title}`,
|
|
222
|
+
`State: ${pr.state} | Author: ${pr.author}`,
|
|
223
|
+
`+${pr.additions} -${pr.deletions} | ${pr.changedFiles} files`,
|
|
224
|
+
'',
|
|
225
|
+
pr.body.slice(0, 500),
|
|
226
|
+
];
|
|
227
|
+
const buttons = [];
|
|
228
|
+
if (pr.url) {
|
|
229
|
+
buttons.push({ text: 'View on GitHub', type: 'url', url: pr.url });
|
|
230
|
+
}
|
|
231
|
+
if (pr.state === 'OPEN') {
|
|
232
|
+
buttons.push({ text: 'Merge', type: 'callback', data: `pro:pr:merge:${pr.number}` }, { text: 'Review', type: 'callback', data: `pro:pr:review:${pr.number}` });
|
|
233
|
+
}
|
|
234
|
+
return { text: lines.join('\n'), buttons: buttons.length > 0 ? buttons : undefined };
|
|
235
|
+
}
|
|
236
|
+
formatPRList(prs) {
|
|
237
|
+
if (prs.length === 0) {
|
|
238
|
+
return { text: 'No open PRs.' };
|
|
239
|
+
}
|
|
240
|
+
const lines = ['Open PRs:', ''];
|
|
241
|
+
for (const pr of prs) {
|
|
242
|
+
lines.push(`#${pr.number} ${pr.title} (${pr.author})`);
|
|
243
|
+
}
|
|
244
|
+
return { text: lines.join('\n') };
|
|
245
|
+
}
|
|
246
|
+
getCommandList() {
|
|
247
|
+
return [
|
|
248
|
+
{ command: 'repo', description: 'Repository info' },
|
|
249
|
+
{ command: 'branch', description: 'Branch info and diff stats' },
|
|
250
|
+
{ command: 'pr', description: 'List or view pull requests' },
|
|
251
|
+
{ command: 'task', description: 'Create an agent task' },
|
|
252
|
+
{ command: 'runs', description: 'List recent agent runs' },
|
|
253
|
+
{ command: 'run', description: 'View run details' },
|
|
254
|
+
{ command: 'yolo', description: 'Timed full access mode' },
|
|
255
|
+
{ command: 'pins', description: 'View pinned context' },
|
|
256
|
+
{ command: 'status', description: 'Bot and session status' },
|
|
257
|
+
];
|
|
258
|
+
}
|
|
259
|
+
getActionIcon(action) {
|
|
260
|
+
switch (action) {
|
|
261
|
+
case 'create': return '[NEW]';
|
|
262
|
+
case 'modify': return '[MOD]';
|
|
263
|
+
case 'delete': return '[DEL]';
|
|
264
|
+
case 'rename': return '[REN]';
|
|
265
|
+
default: return '[???]';
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=text-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-formatter.js","sourceRoot":"","sources":["../../../src/channels/pro/text-formatter.ts"],"names":[],"mappings":"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"}
|