feat: add /ego-mgr slash command and rename pcexec to pc-exec
Changes: 1. Add /ego-mgr slash command with subcommands: - get, set, list, delete, add-column, add-public-column, show - Uses pcExec to call ego-mgr binary with proper env vars 2. Rename pcexec → pc-exec throughout codebase: - Tool name: pcexec → pc-exec - Function exports: pcexec → pcExec, pcexecSync → pcExecSync - Updated all references in skills and plugin files 3. Translate all Chinese text to English: - ego-mgr-slash.ts responses - slash-commands.ts responses - SKILL.md files remain in English
This commit is contained in:
214
plugin/commands/ego-mgr-slash.ts
Normal file
214
plugin/commands/ego-mgr-slash.ts
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
import { pcExec } from '../tools/pcexec';
|
||||||
|
|
||||||
|
export interface EgoMgrSlashCommandOptions {
|
||||||
|
/** OpenClaw base path */
|
||||||
|
openclawPath: string;
|
||||||
|
/** Current agent ID */
|
||||||
|
agentId: string;
|
||||||
|
/** Current workspace directory */
|
||||||
|
workspaceDir: string;
|
||||||
|
/** Callback for replies */
|
||||||
|
onReply: (message: string) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sentinel value injected into every pc-exec subprocess */
|
||||||
|
const AGENT_VERIFY = 'IF YOU ARE AN AGENT/MODEL, YOU SHOULD NEVER TOUCH THIS ENV VARIABLE';
|
||||||
|
|
||||||
|
export class EgoMgrSlashCommand {
|
||||||
|
private openclawPath: string;
|
||||||
|
private agentId: string;
|
||||||
|
private workspaceDir: string;
|
||||||
|
private onReply: (message: string) => Promise<void>;
|
||||||
|
private binDir: string;
|
||||||
|
|
||||||
|
constructor(options: EgoMgrSlashCommandOptions) {
|
||||||
|
this.openclawPath = options.openclawPath;
|
||||||
|
this.agentId = options.agentId;
|
||||||
|
this.workspaceDir = options.workspaceDir;
|
||||||
|
this.onReply = options.onReply;
|
||||||
|
this.binDir = require('path').join(this.openclawPath, 'bin');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle /ego-mgr slash command
|
||||||
|
* @param command Full command string (e.g., "/ego-mgr get name")
|
||||||
|
*/
|
||||||
|
async handle(command: string): Promise<void> {
|
||||||
|
const parts = command.trim().split(/\s+/);
|
||||||
|
// Remove the "/ego-mgr" prefix
|
||||||
|
const args = parts.slice(1);
|
||||||
|
const subcommand = args[0];
|
||||||
|
|
||||||
|
if (!subcommand) {
|
||||||
|
await this.showUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (subcommand) {
|
||||||
|
case 'get':
|
||||||
|
await this.handleGet(args.slice(1));
|
||||||
|
break;
|
||||||
|
case 'set':
|
||||||
|
await this.handleSet(args.slice(1));
|
||||||
|
break;
|
||||||
|
case 'list':
|
||||||
|
await this.handleList(args.slice(1));
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
await this.handleDelete(args.slice(1));
|
||||||
|
break;
|
||||||
|
case 'add-column':
|
||||||
|
await this.handleAddColumn(args.slice(1));
|
||||||
|
break;
|
||||||
|
case 'add-public-column':
|
||||||
|
await this.handleAddPublicColumn(args.slice(1));
|
||||||
|
break;
|
||||||
|
case 'show':
|
||||||
|
await this.handleShow();
|
||||||
|
break;
|
||||||
|
case 'help':
|
||||||
|
default:
|
||||||
|
await this.showUsage();
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
await this.onReply(`Error: ${error.message || error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async showUsage(): Promise<void> {
|
||||||
|
const usage = [
|
||||||
|
'**ego-mgr Commands**',
|
||||||
|
'',
|
||||||
|
'`/ego-mgr get <column-name>` - Get field value',
|
||||||
|
'`/ego-mgr set <column-name> <value>` - Set field value',
|
||||||
|
'`/ego-mgr list` - List all field names',
|
||||||
|
'`/ego-mgr delete <column-name>` - Delete a field',
|
||||||
|
'`/ego-mgr add-column <column-name>` - Add an Agent Scope field',
|
||||||
|
'`/ego-mgr add-public-column <column-name>` - Add a Public Scope field',
|
||||||
|
'`/ego-mgr show` - Show all fields and values',
|
||||||
|
'',
|
||||||
|
'Examples:',
|
||||||
|
'`/ego-mgr get name`',
|
||||||
|
'`/ego-mgr set timezone Asia/Shanghai`',
|
||||||
|
].join('\n');
|
||||||
|
await this.onReply(usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleGet(args: string[]): Promise<void> {
|
||||||
|
if (args.length < 1) {
|
||||||
|
await this.onReply('Usage: `/ego-mgr get <column-name>`');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const columnName = args[0];
|
||||||
|
const result = await this.execEgoMgr(['get', columnName]);
|
||||||
|
await this.onReply(`**${columnName}**: ${result || '(empty)'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleSet(args: string[]): Promise<void> {
|
||||||
|
if (args.length < 2) {
|
||||||
|
await this.onReply('Usage: `/ego-mgr set <column-name> <value>`');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const columnName = args[0];
|
||||||
|
const value = args.slice(1).join(' '); // Support values with spaces
|
||||||
|
await this.execEgoMgr(['set', columnName, value]);
|
||||||
|
await this.onReply(`Set **${columnName}** = \`${value}\``);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleList(args: string[]): Promise<void> {
|
||||||
|
const result = await this.execEgoMgr(['list', 'columns']);
|
||||||
|
if (!result.trim()) {
|
||||||
|
await this.onReply('No fields defined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const columns = result.split('\n').filter(Boolean);
|
||||||
|
const lines = ['**Fields**:', ''];
|
||||||
|
for (const col of columns) {
|
||||||
|
lines.push(`• ${col}`);
|
||||||
|
}
|
||||||
|
await this.onReply(lines.join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleDelete(args: string[]): Promise<void> {
|
||||||
|
if (args.length < 1) {
|
||||||
|
await this.onReply('Usage: `/ego-mgr delete <column-name>`');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const columnName = args[0];
|
||||||
|
await this.execEgoMgr(['delete', columnName]);
|
||||||
|
await this.onReply(`Deleted field **${columnName}**`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleAddColumn(args: string[]): Promise<void> {
|
||||||
|
if (args.length < 1) {
|
||||||
|
await this.onReply('Usage: `/ego-mgr add-column <column-name>`');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const columnName = args[0];
|
||||||
|
await this.execEgoMgr(['add', 'column', columnName]);
|
||||||
|
await this.onReply(`Added Agent Scope field **${columnName}**`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleAddPublicColumn(args: string[]): Promise<void> {
|
||||||
|
if (args.length < 1) {
|
||||||
|
await this.onReply('Usage: `/ego-mgr add-public-column <column-name>`');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const columnName = args[0];
|
||||||
|
await this.execEgoMgr(['add', 'public-column', columnName]);
|
||||||
|
await this.onReply(`Added Public Scope field **${columnName}**`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleShow(): Promise<void> {
|
||||||
|
const result = await this.execEgoMgr(['show']);
|
||||||
|
if (!result.trim()) {
|
||||||
|
await this.onReply('No field data');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const lines = ['**Field Data**:', ''];
|
||||||
|
lines.push('```');
|
||||||
|
lines.push(result);
|
||||||
|
lines.push('```');
|
||||||
|
await this.onReply(lines.join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute ego-mgr binary via pc-exec
|
||||||
|
*/
|
||||||
|
private async execEgoMgr(args: string[]): Promise<string> {
|
||||||
|
const currentPath = process.env.PATH || '';
|
||||||
|
const newPath = currentPath.includes(this.binDir)
|
||||||
|
? currentPath
|
||||||
|
: `${currentPath}:${this.binDir}`;
|
||||||
|
|
||||||
|
const command = `ego-mgr ${args.map(a => this.shellEscape(a)).join(' ')}`;
|
||||||
|
|
||||||
|
const result = await pcExec(command, {
|
||||||
|
cwd: this.workspaceDir,
|
||||||
|
env: {
|
||||||
|
AGENT_ID: this.agentId,
|
||||||
|
AGENT_WORKSPACE: this.workspaceDir,
|
||||||
|
AGENT_VERIFY,
|
||||||
|
PATH: newPath,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.exitCode !== 0 && result.stderr) {
|
||||||
|
throw new Error(result.stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape a string for shell usage
|
||||||
|
*/
|
||||||
|
private shellEscape(str: string): string {
|
||||||
|
// Simple escaping for common cases
|
||||||
|
if (/^[a-zA-Z0-9._-]+$/.test(str)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return `'${str.replace(/'/g, "'\"'\"'")}'`;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,7 +48,7 @@ export class SlashCommandHandler {
|
|||||||
async handle(command: string, userId: string): Promise<void> {
|
async handle(command: string, userId: string): Promise<void> {
|
||||||
// Check authorization
|
// Check authorization
|
||||||
if (!this.authorizedUsers.includes(userId)) {
|
if (!this.authorizedUsers.includes(userId)) {
|
||||||
await this.onReply('❌ 无权执行此命令');
|
await this.onReply('Unauthorized');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,10 +68,10 @@ export class SlashCommandHandler {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
await this.onReply(
|
await this.onReply(
|
||||||
'用法:\n' +
|
'Usage:\n' +
|
||||||
'`/padded-cell-ctrl status` - 查看状态\n' +
|
'`/padded-cell-ctrl status` - Show status\n' +
|
||||||
'`/padded-cell-ctrl enable pass-mgr|safe-restart` - 启用功能\n' +
|
'`/padded-cell-ctrl enable pass-mgr|safe-restart` - Enable feature\n' +
|
||||||
'`/padded-cell-ctrl disable pass-mgr|safe-restart` - 禁用功能'
|
'`/padded-cell-ctrl disable pass-mgr|safe-restart` - Disable feature'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,12 +81,12 @@ export class SlashCommandHandler {
|
|||||||
const agents = this.statusManager.getAllAgents();
|
const agents = this.statusManager.getAllAgents();
|
||||||
|
|
||||||
const lines = [
|
const lines = [
|
||||||
'**PaddedCell 状态**',
|
'**PaddedCell Status**',
|
||||||
'',
|
'',
|
||||||
`🔐 密码管理: ${this.state.passMgrEnabled ? '✅ 启用' : '❌ 禁用'}`,
|
`Secret Manager: ${this.state.passMgrEnabled ? 'Enabled' : 'Disabled'}`,
|
||||||
`🔄 安全重启: ${this.state.safeRestartEnabled ? '✅ 启用' : '❌ 禁用'}`,
|
`Safe Restart: ${this.state.safeRestartEnabled ? 'Enabled' : 'Disabled'}`,
|
||||||
'',
|
'',
|
||||||
'**Agent 状态:**',
|
'**Agent Status:**',
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const agent of agents) {
|
for (const agent of agents) {
|
||||||
@@ -95,14 +95,14 @@ export class SlashCommandHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (agents.length === 0) {
|
if (agents.length === 0) {
|
||||||
lines.push('(暂无 agent 注册)');
|
lines.push('(No agents registered)');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.restartStatus !== 'idle') {
|
if (global.restartStatus !== 'idle') {
|
||||||
lines.push('');
|
lines.push('');
|
||||||
lines.push(`⚠️ 重启状态: ${global.restartStatus}`);
|
lines.push(`Restart Status: ${global.restartStatus}`);
|
||||||
if (global.restartScheduledBy) {
|
if (global.restartScheduledBy) {
|
||||||
lines.push(` 由 ${global.restartScheduledBy} 发起`);
|
lines.push(` Initiated by ${global.restartScheduledBy}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,12 +111,12 @@ export class SlashCommandHandler {
|
|||||||
|
|
||||||
private async handleEnable(feature: 'pass-mgr' | 'safe-restart'): Promise<void> {
|
private async handleEnable(feature: 'pass-mgr' | 'safe-restart'): Promise<void> {
|
||||||
if (!this.isValidFeature(feature)) {
|
if (!this.isValidFeature(feature)) {
|
||||||
await this.onReply('❌ 未知功能。可用选项: pass-mgr, safe-restart');
|
await this.onReply('Unknown feature. Available: pass-mgr, safe-restart');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isOnCooldown(feature)) {
|
if (this.isOnCooldown(feature)) {
|
||||||
await this.onReply('⏳ 该功能最近刚被修改过,请稍后再试');
|
await this.onReply('This feature was recently modified. Please try again later.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,17 +127,17 @@ export class SlashCommandHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.state.lastToggle[feature] = Date.now();
|
this.state.lastToggle[feature] = Date.now();
|
||||||
await this.onReply(`✅ 已启用 ${feature}`);
|
await this.onReply(`Enabled ${feature}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleDisable(feature: 'pass-mgr' | 'safe-restart'): Promise<void> {
|
private async handleDisable(feature: 'pass-mgr' | 'safe-restart'): Promise<void> {
|
||||||
if (!this.isValidFeature(feature)) {
|
if (!this.isValidFeature(feature)) {
|
||||||
await this.onReply('❌ 未知功能。可用选项: pass-mgr, safe-restart');
|
await this.onReply('Unknown feature. Available: pass-mgr, safe-restart');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isOnCooldown(feature)) {
|
if (this.isOnCooldown(feature)) {
|
||||||
await this.onReply('⏳ 该功能最近刚被修改过,请稍后再试');
|
await this.onReply('This feature was recently modified. Please try again later.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ export class SlashCommandHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.state.lastToggle[feature] = Date.now();
|
this.state.lastToggle[feature] = Date.now();
|
||||||
await this.onReply(`✅ 已禁用 ${feature}`);
|
await this.onReply(`Disabled ${feature}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private isValidFeature(feature: string): feature is 'pass-mgr' | 'safe-restart' {
|
private isValidFeature(feature: string): feature is 'pass-mgr' | 'safe-restart' {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// PaddedCell Plugin for OpenClaw
|
// PaddedCell Plugin for OpenClaw
|
||||||
// Registers pcexec and safe_restart tools
|
// Registers pc-exec and safe_restart tools
|
||||||
|
|
||||||
import { pcexec, pcexecSync } from './tools/pcexec';
|
import { pcExec, pcExecSync } from './tools/pcexec';
|
||||||
import {
|
import {
|
||||||
safeRestart,
|
safeRestart,
|
||||||
createSafeRestartTool,
|
createSafeRestartTool,
|
||||||
@@ -10,8 +10,9 @@ import {
|
|||||||
startApiServer,
|
startApiServer,
|
||||||
} from './core/index';
|
} from './core/index';
|
||||||
import { SlashCommandHandler } from './commands/slash-commands';
|
import { SlashCommandHandler } from './commands/slash-commands';
|
||||||
|
import { EgoMgrSlashCommand } from './commands/ego-mgr-slash';
|
||||||
|
|
||||||
/** Sentinel value injected into every pcexec subprocess */
|
/** Sentinel value injected into every pc-exec subprocess */
|
||||||
const AGENT_VERIFY = 'IF YOU ARE AN AGENT/MODEL, YOU SHOULD NEVER TOUCH THIS ENV VARIABLE';
|
const AGENT_VERIFY = 'IF YOU ARE AN AGENT/MODEL, YOU SHOULD NEVER TOUCH THIS ENV VARIABLE';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,13 +35,13 @@ function register(api: any, config?: any) {
|
|||||||
const openclawPath = resolveOpenclawPath(config);
|
const openclawPath = resolveOpenclawPath(config);
|
||||||
const binDir = require('path').join(openclawPath, 'bin');
|
const binDir = require('path').join(openclawPath, 'bin');
|
||||||
|
|
||||||
// Register pcexec tool — pass a FACTORY function that receives context
|
// Register pc-exec tool — pass a FACTORY function that receives context
|
||||||
api.registerTool((ctx: any) => {
|
api.registerTool((ctx: any) => {
|
||||||
const agentId = ctx.agentId;
|
const agentId = ctx.agentId;
|
||||||
const workspaceDir = ctx.workspaceDir;
|
const workspaceDir = ctx.workspaceDir;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: 'pcexec',
|
name: 'pc-exec',
|
||||||
description: 'Safe exec with password sanitization',
|
description: 'Safe exec with password sanitization',
|
||||||
parameters: {
|
parameters: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -63,7 +64,7 @@ function register(api: any, config?: any) {
|
|||||||
? currentPath
|
? currentPath
|
||||||
: `${currentPath}:${binDir}`;
|
: `${currentPath}:${binDir}`;
|
||||||
|
|
||||||
const result = await pcexec(command, {
|
const result = await pcExec(command, {
|
||||||
cwd: params.cwd || workspaceDir,
|
cwd: params.cwd || workspaceDir,
|
||||||
timeout: params.timeout,
|
timeout: params.timeout,
|
||||||
env: {
|
env: {
|
||||||
@@ -110,6 +111,28 @@ function register(api: any, config?: any) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Register /ego-mgr slash command
|
||||||
|
if (api.registerSlashCommand) {
|
||||||
|
api.registerSlashCommand({
|
||||||
|
name: 'ego-mgr',
|
||||||
|
description: 'Manage agent identity/profile fields',
|
||||||
|
handler: async (ctx: any, command: string) => {
|
||||||
|
const egoMgrSlash = new EgoMgrSlashCommand({
|
||||||
|
openclawPath,
|
||||||
|
agentId: ctx.agentId || '',
|
||||||
|
workspaceDir: ctx.workspaceDir || '',
|
||||||
|
onReply: async (message: string) => {
|
||||||
|
if (ctx.reply) {
|
||||||
|
await ctx.reply(message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await egoMgrSlash.handle(command);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
logger.info('Registered /ego-mgr slash command');
|
||||||
|
}
|
||||||
|
|
||||||
logger.info('PaddedCell plugin initialized');
|
logger.info('PaddedCell plugin initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,12 +140,13 @@ function register(api: any, config?: any) {
|
|||||||
module.exports = { register };
|
module.exports = { register };
|
||||||
|
|
||||||
// Also export individual modules for direct use
|
// Also export individual modules for direct use
|
||||||
module.exports.pcexec = pcexec;
|
module.exports.pcExec = pcExec;
|
||||||
module.exports.pcexecSync = pcexecSync;
|
module.exports.pcExecSync = pcExecSync;
|
||||||
module.exports.safeRestart = safeRestart;
|
module.exports.safeRestart = safeRestart;
|
||||||
module.exports.createSafeRestartTool = createSafeRestartTool;
|
module.exports.createSafeRestartTool = createSafeRestartTool;
|
||||||
module.exports.StatusManager = StatusManager;
|
module.exports.StatusManager = StatusManager;
|
||||||
module.exports.createApiServer = createApiServer;
|
module.exports.createApiServer = createApiServer;
|
||||||
module.exports.startApiServer = startApiServer;
|
module.exports.startApiServer = startApiServer;
|
||||||
module.exports.SlashCommandHandler = SlashCommandHandler;
|
module.exports.SlashCommandHandler = SlashCommandHandler;
|
||||||
|
module.exports.EgoMgrSlashCommand = EgoMgrSlashCommand;
|
||||||
module.exports.AGENT_VERIFY = AGENT_VERIFY;
|
module.exports.AGENT_VERIFY = AGENT_VERIFY;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"id": "padded-cell",
|
"id": "padded-cell",
|
||||||
"name": "PaddedCell",
|
"name": "PaddedCell",
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"description": "Secure password management, safe execution, and coordinated agent restart",
|
"description": "Secure secret management, agent identity management, safe execution, and coordinated agent restart",
|
||||||
"entry": "./index.js",
|
"entry": "./index.js",
|
||||||
"configSchema": {
|
"configSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
@@ -201,9 +201,9 @@ async function replaceSecretMgrGets(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safe exec wrapper that handles pass_mgr get commands and sanitizes output.
|
* Safe exec wrapper that handles secret-mgr get commands and sanitizes output.
|
||||||
*/
|
*/
|
||||||
export async function pcexec(
|
export async function pcExec(
|
||||||
command: string,
|
command: string,
|
||||||
options: PcExecOptions = {},
|
options: PcExecOptions = {},
|
||||||
): Promise<PcExecResult> {
|
): Promise<PcExecResult> {
|
||||||
@@ -297,9 +297,9 @@ export async function pcexec(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronous version — password substitution is NOT supported here
|
* Synchronous version — password substitution is NOT supported here
|
||||||
* (use async pcexec for pass_mgr integration).
|
* (use async pcExec for secret-mgr integration).
|
||||||
*/
|
*/
|
||||||
export function pcexecSync(
|
export function pcExecSync(
|
||||||
command: string,
|
command: string,
|
||||||
options: PcExecOptions = {},
|
options: PcExecOptions = {},
|
||||||
): PcExecResult {
|
): PcExecResult {
|
||||||
@@ -336,4 +336,4 @@ export function pcexecSync(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default pcexec;
|
export default pcExec;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: ego-mgr
|
name: ego-mgr
|
||||||
description: Manage agent personal information (name, email, timezone, etc.). Use when storing, retrieving, listing, or managing agent profile fields. Trigger on requests about agent identity, personal info, profile settings, or ego-mgr usage. MUST call ego-mgr via the pcexec tool.
|
description: Manage agent personal information (name, email, timezone, etc.). Use when storing, retrieving, listing, or managing agent profile fields. Trigger on requests about agent identity, personal info, profile settings, or ego-mgr usage. MUST call ego-mgr via the pc-exec tool.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Ego Manager
|
# Ego Manager
|
||||||
@@ -9,7 +9,7 @@ description: Manage agent personal information (name, email, timezone, etc.). Us
|
|||||||
Use ego-mgr to manage agent personal information fields. Supports per-agent fields (Agent Scope) and shared fields (Public Scope).
|
Use ego-mgr to manage agent personal information fields. Supports per-agent fields (Agent Scope) and shared fields (Public Scope).
|
||||||
|
|
||||||
## Mandatory safety rule
|
## Mandatory safety rule
|
||||||
Always invoke ego-mgr through the `pcexec` tool. Do NOT run ego-mgr directly.
|
Always invoke ego-mgr through the `pc-exec` tool. Do NOT run ego-mgr directly.
|
||||||
|
|
||||||
## Concepts
|
## Concepts
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ Always invoke ego-mgr through the `pcexec` tool. Do NOT run ego-mgr directly.
|
|||||||
2. Then, set its value: `ego-mgr set <name> <value>`
|
2. Then, set its value: `ego-mgr set <name> <value>`
|
||||||
3. Read it: `ego-mgr get <name>` or `ego-mgr show`
|
3. Read it: `ego-mgr get <name>` or `ego-mgr show`
|
||||||
|
|
||||||
## Commands (run via pcexec)
|
## Commands (run via pc-exec)
|
||||||
|
|
||||||
### Add columns
|
### Add columns
|
||||||
```bash
|
```bash
|
||||||
@@ -72,7 +72,7 @@ Lists all column names (public first, then agent-scope).
|
|||||||
| 1 | Usage error |
|
| 1 | Usage error |
|
||||||
| 2 | Column not found |
|
| 2 | Column not found |
|
||||||
| 3 | Column already exists |
|
| 3 | Column already exists |
|
||||||
| 4 | Permission error (not via pcexec) |
|
| 4 | Permission error (not via pc-exec) |
|
||||||
| 5 | File lock failed |
|
| 5 | File lock failed |
|
||||||
| 6 | JSON read/write error |
|
| 6 | JSON read/write error |
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: secret-mgr
|
name: secret-mgr
|
||||||
description: Manage OpenClaw agent credentials (usernames/secrets). Use when storing, retrieving, listing, generating, or removing credentials for an agent. Trigger on requests about saving or fetching usernames, passwords, tokens, API keys, or other secrets. MUST call secret-mgr via the pcexec tool.
|
description: Manage OpenClaw agent credentials (usernames/secrets). Use when storing, retrieving, listing, generating, or removing credentials for an agent. Trigger on requests about saving or fetching usernames, passwords, tokens, API keys, or other secrets. MUST call secret-mgr via the pc-exec tool.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Secret Manager
|
# Secret Manager
|
||||||
@@ -9,9 +9,9 @@ description: Manage OpenClaw agent credentials (usernames/secrets). Use when sto
|
|||||||
Use secret-mgr to store and retrieve agent-scoped credentials (username/secret pairs) and generate secrets.
|
Use secret-mgr to store and retrieve agent-scoped credentials (username/secret pairs) and generate secrets.
|
||||||
|
|
||||||
## Mandatory safety rule
|
## Mandatory safety rule
|
||||||
Always invoke secret-mgr through the `pcexec` tool. Do NOT run secret-mgr directly.
|
Always invoke secret-mgr through the `pc-exec` tool. Do NOT run secret-mgr directly.
|
||||||
|
|
||||||
## Commands (run via pcexec)
|
## Commands (run via pc-exec)
|
||||||
|
|
||||||
- List keys for current agent
|
- List keys for current agent
|
||||||
- `secret-mgr list`
|
- `secret-mgr list`
|
||||||
@@ -50,19 +50,19 @@ Always invoke secret-mgr through the `pcexec` tool. Do NOT run secret-mgr direct
|
|||||||
- Storing can be explicit (user asks) or proactive after the agent successfully registers/creates an account.
|
- Storing can be explicit (user asks) or proactive after the agent successfully registers/creates an account.
|
||||||
- Secrets should be fetched and used immediately in a command, not displayed (e.g., `xxx_cli login --user $(secret-mgr get-username --key some_key) --pass $(secret-mgr get-secret --key some_key)`).
|
- Secrets should be fetched and used immediately in a command, not displayed (e.g., `xxx_cli login --user $(secret-mgr get-username --key some_key) --pass $(secret-mgr get-secret --key some_key)`).
|
||||||
|
|
||||||
## Examples (pcexec)
|
## Examples (pc-exec)
|
||||||
|
|
||||||
- Store credentials
|
- Store credentials
|
||||||
- pcexec: `secret-mgr set --key github --username alice --secret <secret>`
|
- pc-exec: `secret-mgr set --key github --username alice --secret <secret>`
|
||||||
|
|
||||||
- Retrieve username
|
- Retrieve username
|
||||||
- pcexec: `secret-mgr get-username --key github`
|
- pc-exec: `secret-mgr get-username --key github`
|
||||||
|
|
||||||
- Retrieve secret
|
- Retrieve secret
|
||||||
- pcexec: `secret-mgr get-secret --key github`
|
- pc-exec: `secret-mgr get-secret --key github`
|
||||||
|
|
||||||
- Generate secret
|
- Generate secret
|
||||||
- pcexec: `secret-mgr generate --key github`
|
- pc-exec: `secret-mgr generate --key github`
|
||||||
|
|
||||||
- Delete entry
|
- Delete entry
|
||||||
- pcexec: `secret-mgr unset --key github`
|
- pc-exec: `secret-mgr unset --key github`
|
||||||
|
|||||||
Reference in New Issue
Block a user