Compare commits

...

3 Commits

Author SHA1 Message Date
cb683c43bb fix: avoid clobbering sensitive config fields during configure
Reading the entire plugins tree via openclaw config get returns redacted
values for sensitive fields. Writing it back overwrites real secrets with
the __OPENCLAW_REDACTED__ sentinel. Changed to set individual leaf paths
only when missing.
2026-04-16 14:34:07 +00:00
h z
392eafccf2 Merge pull request 'feat(ego-mgr): add lookup subcommand' (#15) from feat/ego-mgr-lookup into main
Reviewed-on: #15
2026-04-14 21:35:37 +00:00
39856a3060 feat(ego-mgr): add lookup subcommand
ego-mgr lookup <username>
  - Finds agent whose default-username == username
  - Echoes the agent-id (map key in agent-scope)
  - Exits 7 if not found or column missing
2026-04-14 21:33:09 +00:00
2 changed files with 56 additions and 23 deletions

View File

@@ -17,13 +17,14 @@ const (
// Exit codes per spec
const (
ExitSuccess = 0
ExitUsageError = 1
ExitColumnNotFound = 2
ExitColumnExists = 3
ExitPermission = 4
ExitLockFailed = 5
ExitJSONError = 6
ExitSuccess = 0
ExitUsageError = 1
ExitColumnNotFound = 2
ExitColumnExists = 3
ExitPermission = 4
ExitLockFailed = 5
ExitJSONError = 6
ExitNotFound = 7
)
// EgoData is the on-disk JSON structure
@@ -185,7 +186,7 @@ Examples:
ego-mgr delete name`,
}
rootCmd.AddCommand(addCmd(), deleteCmd(), setCmd(), getCmd(), showCmd(), listCmd())
rootCmd.AddCommand(addCmd(), deleteCmd(), setCmd(), getCmd(), showCmd(), listCmd(), lookupCmd())
if err := rootCmd.Execute(); err != nil {
os.Exit(ExitUsageError)
@@ -480,3 +481,37 @@ func listColumnsCmd() *cobra.Command {
}
return cmd
}
func lookupCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "lookup <username>",
Short: "Look up an agent ID by default-username",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
username := args[0]
data, err := readEgoData()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(ExitJSONError)
}
// Verify default-username column exists
if !isAgentColumn(data, "default-username") {
fmt.Fprintf(os.Stderr, "Error: column 'default-username' does not exist\n")
os.Exit(ExitColumnNotFound)
}
for agentID, agentData := range data.AgentScope {
if agentData["default-username"] == username {
fmt.Print(agentID)
return
}
}
fmt.Fprintf(os.Stderr, "Error: no agent found with default-username '%s'\n", username)
os.Exit(ExitNotFound)
},
}
return cmd
}

View File

@@ -349,23 +349,21 @@ async function configure() {
if (!allow.includes(PLUGIN_NAME)) { allow.push(PLUGIN_NAME); setOpenclawConfig('plugins.allow', allow); }
logOk(`plugins.allow includes ${PLUGIN_NAME}`);
const plugins = getOpenclawConfig('plugins', {});
plugins.entries = plugins.entries || {};
const entryPath = `plugins.entries.${PLUGIN_NAME}`;
const existingEnabled = getOpenclawConfig(`${entryPath}.enabled`, undefined);
if (existingEnabled === undefined) setOpenclawConfig(`${entryPath}.enabled`, true);
const existingEntry = plugins.entries[PLUGIN_NAME] || {};
const existingConfig = existingEntry.config || {};
const defaultConfig = { enabled: true, secretMgrPath, openclawProfilePath: openclawPath };
const cfgPath = `${entryPath}.config`;
const existingCfgEnabled = getOpenclawConfig(`${cfgPath}.enabled`, undefined);
if (existingCfgEnabled === undefined) setOpenclawConfig(`${cfgPath}.enabled`, true);
plugins.entries[PLUGIN_NAME] = {
...existingEntry,
enabled: existingEntry.enabled ?? true,
config: {
...defaultConfig,
...existingConfig,
},
};
setOpenclawConfig('plugins', plugins);
logOk('Plugin entry configured (preserved existing config, added missing defaults)');
const existingSecretMgr = getOpenclawConfig(`${cfgPath}.secretMgrPath`, undefined);
if (existingSecretMgr === undefined) setOpenclawConfig(`${cfgPath}.secretMgrPath`, secretMgrPath);
const existingProfile = getOpenclawConfig(`${cfgPath}.openclawProfilePath`, undefined);
if (existingProfile === undefined) setOpenclawConfig(`${cfgPath}.openclawProfilePath`, openclawPath);
logOk('Plugin entry configured (set missing defaults only)');
} catch (err) {
logWarn(`Config failed: ${err.message}`);
}