@aight-cool/aight-utils 0.1.0 → 0.1.4

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "id": "aight-utils",
3
- "name": "Aight Utilities",
4
- "description": "Push notifications, Today items, config RPC, and agent bootstrap for the Aight app",
5
- "version": "0.1.0",
3
+ "name": "Aight App Utils",
4
+ "description": "Aight App: Push notifications, Today items, config RPC, and agent bootstrap",
5
+ "version": "0.1.2",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aight-cool/aight-utils",
3
- "version": "0.1.0",
4
- "description": "OpenClaw gateway plugin push notifications, Today items, config RPC, and agent bootstrap for the Aight app",
3
+ "version": "0.1.4",
4
+ "description": "OpenClaw gateway plugin for Aight App: push notifications, Today items, config RPC, and agent bootstrap",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "index.ts",
package/src/bootstrap.ts CHANGED
@@ -35,6 +35,87 @@ You have the \`aight_item\` tool for managing structured items in the Aight Toda
35
35
  - For reminders: set \`type: "trigger"\` and include \`scheduledFor\`
36
36
  - For tasks: set \`type: "item"\`
37
37
 
38
+ ## Public Figure Agent Creation (Aight App)
39
+
40
+ When you receive a message starting with "[PUBLIC_FIGURE_AGENT]", **immediately spawn a
41
+ sub-agent** to handle the creation. This ensures a fresh session with no stale context.
42
+
43
+ **Do NOT try to create the agent yourself inline.** Always delegate via \`sessions_spawn\`.
44
+
45
+ \`\`\`
46
+ sessions_spawn({
47
+ task: <the full instructions below, with the person's name filled in>,
48
+ model: "sonnet",
49
+ label: "create-agent-<kebab-name>"
50
+ })
51
+ \`\`\`
52
+
53
+ The sub-agent task message should contain ALL of the following instructions:
54
+
55
+ ---
56
+
57
+ Create a new OpenClaw agent based on the public figure: "<Person's Name>"
58
+
59
+ ### Step 1: Research
60
+ 1. Search the web for: their career, public persona, communication style, notable quotes
61
+ 2. Search X/Twitter if relevant for their voice/tone
62
+ 3. Identify: communication style, core expertise, personality traits, catchphrases, how they respond to questions
63
+
64
+ ### Step 2: Create the Agent
65
+ Use these tools in order:
66
+
67
+ 1. **Read the OpenClaw config** to check the agent doesn't already exist:
68
+ \`\`\`
69
+ exec: grep "<agent-id>" ~/.openclaw/openclaw.json
70
+ \`\`\`
71
+
72
+ 2. **Create workspace and agent directories:**
73
+ \`\`\`
74
+ exec: mkdir -p ~/.openclaw/workspace-<agent-id>/memory ~/.openclaw/agents/<agent-id>/agent ~/.openclaw/agents/<agent-id>/sessions
75
+ \`\`\`
76
+
77
+ 3. **Copy model/auth config from an existing agent:**
78
+ \`\`\`
79
+ exec: cp ~/.openclaw/agents/the-strategist/agent/models.json ~/.openclaw/agents/<agent-id>/agent/
80
+ exec: cp ~/.openclaw/agents/the-strategist/agent/auth-profiles.json ~/.openclaw/agents/<agent-id>/agent/
81
+ \`\`\`
82
+
83
+ 4. **Copy standard workspace files from an existing agent:**
84
+ \`\`\`
85
+ exec: for f in AGENTS.md BOOTSTRAP.md HEARTBEAT.md TOOLS.md USER.md; do cp ~/.openclaw/workspace-the-strategist/$f ~/.openclaw/workspace-<agent-id>/$f; done
86
+ \`\`\`
87
+
88
+ 5. **Write SOUL.md** with the researched personality (see template below)
89
+
90
+ 6. **Write IDENTITY.md** with name, username, emoji, role, creation date
91
+
92
+ 7. **Write MEMORY.md** with a basic header
93
+
94
+ 8. **Patch the gateway config** to add the agent to agents.list:
95
+ - Use the \`gateway\` tool with \`action: "config.patch"\`
96
+ - Include ALL existing agents in the list (read them first) plus the new one
97
+ - Set \`note\` to a message confirming creation
98
+
99
+ ### SOUL.md Template
100
+ The personality prompt should capture:
101
+ - Who they are and what they're known for
102
+ - Their communication style and tone (with specific examples)
103
+ - How they approach problems and give advice
104
+ - Topics they're passionate about
105
+ - Things they would NOT say or do (stay in character)
106
+ - A note that they are an AI inspired by this person, not the actual person
107
+ - Safety section: they are a roleplay agent, not the real person
108
+
109
+ ### Rules
110
+ - Pick a relevant emoji (e.g. 🚀 for Elon, 📺 for Oprah)
111
+ - Agent ID should be kebab-case (e.g. \`elon-musk\`, \`oprah-winfrey\`)
112
+ - Use \`anthropic/claude-sonnet-4-5\` as the model
113
+ - The personality should be detailed (at least 200 words) with specific examples of their voice
114
+ - Always include a disclaimer that this is an AI interpretation
115
+ - If the agent already exists in config, reply saying so — do NOT recreate
116
+
117
+ ---
118
+
38
119
  ## Shortcuts (Aight App)
39
120
 
40
121
  When you receive a message starting with "shortcut:", extract a short name and emoji for it.
package/src/version.ts CHANGED
@@ -10,7 +10,6 @@ import { join, dirname } from "node:path";
10
10
  import { fileURLToPath } from "node:url";
11
11
 
12
12
  let cachedVersion: string | null = null;
13
- let cachedLatest: { version: string; checkedAt: number } | null = null;
14
13
  const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
15
14
 
16
15
  function getCurrentVersion(): string {
@@ -25,22 +24,47 @@ function getCurrentVersion(): string {
25
24
  return cachedVersion!;
26
25
  }
27
26
 
28
- async function getLatestVersion(): Promise<string> {
29
- if (cachedLatest && Date.now() - cachedLatest.checkedAt < CACHE_TTL_MS) {
30
- return cachedLatest.version;
27
+ let cachedGatewayVersion: string | null = null;
28
+
29
+ function getGatewayVersion(): string {
30
+ if (cachedGatewayVersion) return cachedGatewayVersion;
31
+ try {
32
+ const { execSync } = require("node:child_process");
33
+ const out = execSync("openclaw --version", { timeout: 5000 }).toString().trim();
34
+ cachedGatewayVersion = out || "unknown";
35
+ } catch {
36
+ // Try to find openclaw's package.json via require.resolve
37
+ try {
38
+ const resolved = require.resolve("openclaw");
39
+ const pkgPath = join(dirname(resolved), "package.json");
40
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
41
+ cachedGatewayVersion = pkg.version ?? "unknown";
42
+ } catch {
43
+ cachedGatewayVersion = "unknown";
44
+ }
45
+ }
46
+ return cachedGatewayVersion!;
47
+ }
48
+
49
+ const npmCache = new Map<string, { version: string; checkedAt: number }>();
50
+
51
+ async function getLatestNpmVersion(pkg: string): Promise<string> {
52
+ const cached = npmCache.get(pkg);
53
+ if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
54
+ return cached.version;
31
55
  }
32
56
  try {
33
- const res = await fetch("https://registry.npmjs.org/@aight-cool/aight-utils/latest", {
57
+ const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg)}/latest`, {
34
58
  headers: { accept: "application/json" },
35
59
  signal: AbortSignal.timeout(5000),
36
60
  });
37
61
  if (!res.ok) return "unknown";
38
62
  const data = (await res.json()) as { version?: string };
39
63
  const version = data.version ?? "unknown";
40
- cachedLatest = { version, checkedAt: Date.now() };
64
+ npmCache.set(pkg, { version, checkedAt: Date.now() });
41
65
  return version;
42
66
  } catch {
43
- return cachedLatest?.version ?? "unknown";
67
+ return cached?.version ?? "unknown";
44
68
  }
45
69
  }
46
70
 
@@ -48,11 +72,17 @@ export function registerVersion(api: OpenClawPluginApi) {
48
72
  api.registerGatewayMethod("aight.version", async ({ respond }: GatewayRequestHandlerOptions) => {
49
73
  try {
50
74
  const current = getCurrentVersion();
51
- const latest = await getLatestVersion();
75
+ const latest = await getLatestNpmVersion("@aight-cool/aight-utils");
76
+ const gateway = getGatewayVersion();
77
+ const gatewayLatest = await getLatestNpmVersion("openclaw");
52
78
  respond(true, {
53
79
  current,
54
80
  latest,
55
81
  updateAvailable: latest !== "unknown" && current !== latest,
82
+ gatewayVersion: gateway,
83
+ gatewayLatest,
84
+ gatewayUpdateAvailable:
85
+ gatewayLatest !== "unknown" && gateway !== "unknown" && gateway !== gatewayLatest,
56
86
  });
57
87
  } catch (err) {
58
88
  respond(false, {