@aman_asmuei/aman 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aman Asmuei
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ <div align="center">
2
+
3
+ <br>
4
+
5
+ <picture>
6
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/badge/aman-AI_companion-white?style=for-the-badge&labelColor=0d1117&color=58a6ff">
7
+ <img alt="aman" src="https://img.shields.io/badge/aman-AI_companion-black?style=for-the-badge&labelColor=f6f8fa&color=24292f">
8
+ </picture>
9
+
10
+ ### Your complete AI companion.
11
+
12
+ Identity + Memory + Tools — one command, any AI.
13
+
14
+ <br>
15
+
16
+ [![npm](https://img.shields.io/npm/v/@aman_asmuei/aman?style=flat-square&color=cb3837)](https://www.npmjs.com/package/@aman_asmuei/aman)
17
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## One Command
24
+
25
+ ```bash
26
+ npx @aman_asmuei/aman
27
+ ```
28
+
29
+ Sets up your complete AI ecosystem:
30
+
31
+ ```
32
+ ◆ aman — your complete AI companion
33
+
34
+ ✔ Created ~/.acore/core.md (identity)
35
+ ✔ Memory: run npx @aman_asmuei/amem to add automated memory
36
+ ✔ Tools: run npx @aman_asmuei/akit add github to add capabilities
37
+
38
+ ✔ Your AI companion is ready.
39
+
40
+ aman status See your full ecosystem
41
+ acore customize Change personality
42
+ akit add <tool> Add tools
43
+ npx @aman_asmuei/amem Enable automated memory
44
+ ```
45
+
46
+ ---
47
+
48
+ ## The Ecosystem
49
+
50
+ ```
51
+ aman
52
+ ├── acore → identity → who your AI IS
53
+ ├── amem → memory → what your AI KNOWS
54
+ └── akit → tools → what your AI CAN DO
55
+ ```
56
+
57
+ | Layer | Package | What it does |
58
+ |:------|:--------|:-------------|
59
+ | Identity | [acore](https://github.com/amanasmuei/acore) | Personality, values, relationship memory |
60
+ | Memory | [amem](https://github.com/amanasmuei/amem) | Automated knowledge storage (MCP) |
61
+ | Tools | [akit](https://github.com/amanasmuei/akit) | Portable AI capabilities (MCP + manual) |
62
+ | **Unified** | **aman** | **One command to set up everything** |
63
+
64
+ Each package works independently. `aman` is the front door.
65
+
66
+ ---
67
+
68
+ ## Commands
69
+
70
+ | Command | What it does |
71
+ |:--------|:------------|
72
+ | `aman` | First run: setup. After that: show status |
73
+ | `aman setup` | Set up identity + memory + tools |
74
+ | `aman status` | View your full ecosystem status |
75
+
76
+ After setup, use the individual CLIs for detailed management:
77
+
78
+ ```bash
79
+ acore customize # change AI personality
80
+ acore show # view identity
81
+ akit add github # add tools
82
+ akit search database # find tools
83
+ acore doctor # health check identity
84
+ akit doctor # health check tools
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Ecosystem Status
90
+
91
+ ```bash
92
+ $ aman status
93
+
94
+ ◆ aman — ecosystem status
95
+
96
+ ✔ Identity: Companion + Aman
97
+ ✔ Memory: amem connected (automated)
98
+ ✔ Tools: 3 installed
99
+ ✔ Platform: Claude Code (auto-save + MCP)
100
+
101
+ Ecosystem: Complete ecosystem (3/3 layers active)
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Works With
107
+
108
+ ChatGPT, Claude, Claude Code, Cursor, Windsurf, Gemini, and any AI that accepts a system prompt.
109
+
110
+ ## License
111
+
112
+ [MIT](LICENSE)
113
+
114
+ ---
115
+
116
+ <div align="center">
117
+
118
+ **One command. Complete AI companion. Any platform.**
119
+
120
+ </div>
package/bin/aman.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../dist/index.js";
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,428 @@
1
+ // src/index.ts
2
+ import { Command } from "commander";
3
+
4
+ // src/commands/setup.ts
5
+ import * as p from "@clack/prompts";
6
+ import pc from "picocolors";
7
+ import fs4 from "fs";
8
+ import path3 from "path";
9
+ import os2 from "os";
10
+
11
+ // src/lib/detect.ts
12
+ import fs from "fs";
13
+ import path from "path";
14
+ import os from "os";
15
+ import { execFileSync } from "child_process";
16
+ function detectUserName() {
17
+ try {
18
+ const name = execFileSync("git", ["config", "user.name"], {
19
+ encoding: "utf-8",
20
+ timeout: 3e3
21
+ }).trim();
22
+ return name || null;
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+ function detectPlatform(cwd) {
28
+ const dir = cwd ?? process.cwd();
29
+ const configPath = path.join(dir, ".acore", "config.json");
30
+ if (fs.existsSync(configPath)) {
31
+ try {
32
+ const raw = fs.readFileSync(configPath, "utf-8");
33
+ const parsed = JSON.parse(raw);
34
+ if (typeof parsed.platform === "string") {
35
+ const p3 = parsed.platform;
36
+ if (p3 === "claude-code" || p3 === "cursor" || p3 === "windsurf") return p3;
37
+ }
38
+ } catch {
39
+ }
40
+ }
41
+ if (fs.existsSync(path.join(dir, "CLAUDE.md"))) return "claude-code";
42
+ if (fs.existsSync(path.join(dir, ".cursorrules"))) return "cursor";
43
+ if (fs.existsSync(path.join(dir, ".windsurfrules"))) return "windsurf";
44
+ return "other";
45
+ }
46
+ function detectStack(cwd) {
47
+ const dir = cwd ?? process.cwd();
48
+ const parts = [];
49
+ const hasTs = fs.existsSync(path.join(dir, "tsconfig.json"));
50
+ if (hasTs) parts.push("TypeScript");
51
+ if (fs.existsSync(path.join(dir, "Cargo.toml"))) parts.push("Rust");
52
+ if (fs.existsSync(path.join(dir, "go.mod"))) parts.push("Go");
53
+ if (fs.existsSync(path.join(dir, "pyproject.toml")) || fs.existsSync(path.join(dir, "requirements.txt"))) parts.push("Python");
54
+ if (fs.existsSync(path.join(dir, "package.json"))) {
55
+ try {
56
+ const raw = fs.readFileSync(path.join(dir, "package.json"), "utf-8");
57
+ const pkg = JSON.parse(raw);
58
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
59
+ const frameworks = [["react", "React"], ["next", "Next.js"], ["vue", "Vue"], ["svelte", "Svelte"], ["express", "Express"]];
60
+ for (const [dep, label] of frameworks) {
61
+ if (dep in deps) {
62
+ if (!hasTs && !parts.includes("JavaScript")) parts.push("JavaScript");
63
+ parts.push(label);
64
+ }
65
+ }
66
+ } catch {
67
+ }
68
+ }
69
+ return parts.join(", ");
70
+ }
71
+ function detectRole(cwd) {
72
+ const dir = cwd ?? process.cwd();
73
+ const manifests = ["package.json", "tsconfig.json", "Cargo.toml", "go.mod", "pyproject.toml", "requirements.txt"];
74
+ return manifests.some((m) => fs.existsSync(path.join(dir, m))) ? "Developer" : "Professional";
75
+ }
76
+ function isMcpPlatform(platform) {
77
+ return platform === "claude-code" || platform === "cursor" || platform === "windsurf";
78
+ }
79
+ function detectEcosystem() {
80
+ const home = os.homedir();
81
+ const acorePath = path.join(home, ".acore", "core.md");
82
+ const akitPath = path.join(home, ".akit", "kit.md");
83
+ const akitInstalledPath = path.join(home, ".akit", "installed.json");
84
+ let akitToolCount = 0;
85
+ if (fs.existsSync(akitInstalledPath)) {
86
+ try {
87
+ const tools = JSON.parse(fs.readFileSync(akitInstalledPath, "utf-8"));
88
+ akitToolCount = Array.isArray(tools) ? tools.length : 0;
89
+ } catch {
90
+ }
91
+ }
92
+ let amemInstalled = false;
93
+ const mcpPaths = [
94
+ path.join(home, ".claude", "settings.json"),
95
+ path.join(process.cwd(), ".cursor", "mcp.json"),
96
+ path.join(home, ".windsurf", "mcp.json")
97
+ ];
98
+ for (const mcpPath of mcpPaths) {
99
+ if (fs.existsSync(mcpPath)) {
100
+ try {
101
+ const raw = fs.readFileSync(mcpPath, "utf-8");
102
+ if (raw.includes("amem")) amemInstalled = true;
103
+ } catch {
104
+ }
105
+ }
106
+ }
107
+ return {
108
+ acore: { installed: fs.existsSync(acorePath), path: acorePath },
109
+ amem: { installed: amemInstalled },
110
+ akit: { installed: fs.existsSync(akitPath), path: akitPath, toolCount: akitToolCount }
111
+ };
112
+ }
113
+
114
+ // src/lib/template.ts
115
+ import fs2 from "fs";
116
+ import path2 from "path";
117
+ import { fileURLToPath } from "url";
118
+ var __dirname = path2.dirname(fileURLToPath(import.meta.url));
119
+ function getTemplatePath(name) {
120
+ const fromDist = path2.join(__dirname, "..", "template", `${name}.md`);
121
+ if (fs2.existsSync(fromDist)) return fromDist;
122
+ const fromSrc = path2.join(__dirname, "..", "..", "template", `${name}.md`);
123
+ return fromSrc;
124
+ }
125
+ function loadTemplate(name) {
126
+ return fs2.readFileSync(getTemplatePath(name), "utf-8");
127
+ }
128
+ function fillTemplate(template, values) {
129
+ let result = template;
130
+ for (const [key, value] of Object.entries(values)) {
131
+ result = result.replaceAll(`{{${key}}}`, value);
132
+ }
133
+ return result;
134
+ }
135
+
136
+ // src/lib/instructions.ts
137
+ var FILE_BASED_INSTRUCTIONS = `### Update Protocol
138
+ When user says "update core" OR when session is winding down:
139
+ 1. Review conversation for new insights
140
+ 2. Flag any Identity-level changes for explicit approval BEFORE proceeding
141
+ 3. Read current ~/.acore/core.md
142
+ 4. Write updated version directly to ~/.acore/core.md
143
+ 5. Confirm what changed in 1-2 sentences
144
+
145
+ If file write fails for any reason, fall back to outputting the updated core.md in a code block.
146
+
147
+ ### Update Permissions
148
+ - Auto-update (no approval needed): Session, Relationship.Work, Relationship.Learned patterns
149
+ - Approval required: Identity (any field), adding new sections
150
+ - Suggest only: structural changes to core.md
151
+
152
+ ### Session Awareness
153
+ When the conversation is winding down:
154
+ - Proactively offer: "I noticed a few things this session. Want me to save them to your core?"
155
+ - If yes: follow Update Protocol (write directly)
156
+ - If no: respect it, don't ask again`;
157
+ var CLIPBOARD_INSTRUCTIONS = `### Update Protocol
158
+ When user says "update core" OR when session is winding down:
159
+ 1. Review conversation for new insights
160
+ 2. Flag any Identity-level changes for explicit approval
161
+ 3. Output the complete updated core.md in a code block
162
+ 4. User saves manually (paste into acore pull or replace file directly)
163
+
164
+ ### Update Permissions
165
+ - Auto-update (no approval needed): Session, Relationship.Work, Relationship.Learned patterns
166
+ - Approval required: Identity (any field), adding new sections
167
+ - Suggest only: structural changes to core.md
168
+
169
+ ### Session Awareness
170
+ When the conversation is winding down:
171
+ - Proactively offer: "Want me to generate an updated core.md with what I learned this session?"
172
+ - If yes: follow Update Protocol
173
+ - If no: respect it, don't ask again`;
174
+ function getUpdateInstructions(platform) {
175
+ if (platform === "claude-code" || platform === "cursor" || platform === "windsurf") {
176
+ return FILE_BASED_INSTRUCTIONS;
177
+ }
178
+ return CLIPBOARD_INSTRUCTIONS;
179
+ }
180
+
181
+ // src/lib/inject.ts
182
+ import fs3 from "fs";
183
+ var START_MARKER = "<!-- acore:start -->";
184
+ var END_MARKER = "<!-- acore:end -->";
185
+ function injectIntoFile(filePath, content) {
186
+ const wrapped = `${START_MARKER}
187
+ ${content}
188
+ ${END_MARKER}`;
189
+ if (!fs3.existsSync(filePath)) {
190
+ fs3.writeFileSync(filePath, wrapped + "\n", "utf-8");
191
+ return { created: true };
192
+ }
193
+ const existing = fs3.readFileSync(filePath, "utf-8");
194
+ const startIdx = existing.indexOf(START_MARKER);
195
+ const endIdx = existing.indexOf(END_MARKER);
196
+ if (startIdx !== -1 && endIdx !== -1) {
197
+ const before = existing.slice(0, startIdx);
198
+ const after = existing.slice(endIdx + END_MARKER.length);
199
+ fs3.writeFileSync(filePath, before + wrapped + after, "utf-8");
200
+ } else {
201
+ fs3.writeFileSync(filePath, existing + "\n" + wrapped + "\n", "utf-8");
202
+ }
203
+ return { created: false };
204
+ }
205
+ function getPlatformFile(platform) {
206
+ switch (platform) {
207
+ case "claude-code":
208
+ return "CLAUDE.md";
209
+ case "cursor":
210
+ return ".cursorrules";
211
+ case "windsurf":
212
+ return ".windsurfrules";
213
+ default:
214
+ return null;
215
+ }
216
+ }
217
+
218
+ // src/commands/setup.ts
219
+ var ARCHETYPES = {
220
+ pragmatist: {
221
+ personality: "concise, practical, efficient",
222
+ communication: "lead with the answer, then explain if asked",
223
+ values: "simplicity over cleverness, shipping over perfection"
224
+ },
225
+ mentor: {
226
+ personality: "patient, thorough, encouraging",
227
+ communication: "explain step-by-step, celebrate progress",
228
+ values: "understanding over speed, safety over velocity"
229
+ },
230
+ "sparring-partner": {
231
+ personality: "direct, challenging, honest",
232
+ communication: "push back on weak ideas, ask hard questions",
233
+ values: "honesty over comfort, shipping over perfection"
234
+ },
235
+ collaborator: {
236
+ personality: "curious, supportive, adaptive",
237
+ communication: "explore ideas together, match your energy",
238
+ values: "understanding over speed"
239
+ },
240
+ architect: {
241
+ personality: "systematic, precise, forward-thinking",
242
+ communication: "plan before building, cover edge cases",
243
+ values: "safety over velocity, simplicity over cleverness"
244
+ }
245
+ };
246
+ async function setupCommand() {
247
+ p.intro(pc.bold("aman") + " \u2014 your complete AI companion");
248
+ const ecosystem = detectEcosystem();
249
+ if (ecosystem.acore.installed) {
250
+ p.log.success(`Identity: ${pc.dim("~/.acore/core.md")} already exists`);
251
+ } else {
252
+ p.log.step("Setting up your AI identity...");
253
+ let userName = detectUserName();
254
+ if (!userName) {
255
+ const prompted = await p.text({
256
+ message: "What's your name?",
257
+ validate: (v) => v.length === 0 ? "Name is required" : void 0
258
+ });
259
+ if (p.isCancel(prompted)) process.exit(0);
260
+ userName = prompted;
261
+ }
262
+ const platform = detectPlatform();
263
+ const stack = detectStack();
264
+ const userRole = detectRole();
265
+ const archetype = await p.select({
266
+ message: "Choose your AI's personality",
267
+ options: [
268
+ { value: "collaborator", label: "Collaborator", hint: "curious, supportive, adaptive (recommended)" },
269
+ { value: "pragmatist", label: "Pragmatist", hint: "concise, practical, efficient" },
270
+ { value: "mentor", label: "Mentor", hint: "patient, thorough, encouraging" },
271
+ { value: "sparring-partner", label: "Sparring Partner", hint: "direct, challenging, honest" },
272
+ { value: "architect", label: "Architect", hint: "systematic, precise, forward-thinking" }
273
+ ],
274
+ initialValue: "collaborator"
275
+ });
276
+ if (p.isCancel(archetype)) process.exit(0);
277
+ const arch = ARCHETYPES[archetype];
278
+ const aiName = await p.text({
279
+ message: "Name your AI companion",
280
+ placeholder: "Companion",
281
+ defaultValue: "Companion"
282
+ });
283
+ if (p.isCancel(aiName)) process.exit(0);
284
+ const template = loadTemplate("core-starter");
285
+ const content = fillTemplate(template, {
286
+ AI_NAME: aiName || "Companion",
287
+ USER_NAME: userName,
288
+ USER_ROLE: userRole,
289
+ PERSONALITY: arch.personality,
290
+ COMMUNICATION: arch.communication,
291
+ VALUES: arch.values,
292
+ BOUNDARIES: "won't pretend to be human, flags when out of depth",
293
+ DATE: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
294
+ UPDATE_INSTRUCTIONS: getUpdateInstructions(platform)
295
+ });
296
+ const globalDir = path3.join(os2.homedir(), ".acore");
297
+ fs4.mkdirSync(globalDir, { recursive: true });
298
+ fs4.writeFileSync(path3.join(globalDir, "core.md"), content, "utf-8");
299
+ p.log.success(`Created ${pc.dim("~/.acore/core.md")} (identity)`);
300
+ if (stack) {
301
+ const localDir = path3.join(process.cwd(), ".acore");
302
+ fs4.mkdirSync(localDir, { recursive: true });
303
+ const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
304
+ const contextContent = `## Work
305
+ - Stack: ${stack}
306
+ - Domain:
307
+ - Focus:
308
+
309
+ ## Session
310
+ - Last updated: ${today}
311
+ - Resume: [starting fresh]
312
+ - Active topics: []
313
+ - Recent decisions: []
314
+ - Temp notes: []
315
+
316
+ ## Project Patterns
317
+ - [observations specific to this project \u2014 built over time]
318
+ `;
319
+ fs4.writeFileSync(path3.join(localDir, "context.md"), contextContent, "utf-8");
320
+ const configContent = JSON.stringify({ platform: platform || "other" }, null, 2) + "\n";
321
+ fs4.writeFileSync(path3.join(localDir, "config.json"), configContent, "utf-8");
322
+ }
323
+ const platformFile = getPlatformFile(platform);
324
+ if (platformFile) {
325
+ const globalContent = fs4.readFileSync(path3.join(globalDir, "core.md"), "utf-8");
326
+ const filePath = path3.join(process.cwd(), platformFile);
327
+ const result = injectIntoFile(filePath, globalContent);
328
+ if (result.created) {
329
+ p.log.success(`Created ${pc.dim(platformFile)} with identity`);
330
+ } else {
331
+ p.log.success(`Updated ${pc.dim(platformFile)} with identity`);
332
+ }
333
+ }
334
+ const inferredParts = [userName, userRole];
335
+ if (stack) inferredParts.push(stack);
336
+ p.log.info(`Inferred: ${pc.dim(inferredParts.join(" \xB7 "))}`);
337
+ }
338
+ if (ecosystem.amem.installed) {
339
+ p.log.success("Memory: amem connected");
340
+ } else {
341
+ const platform = detectPlatform();
342
+ if (isMcpPlatform(platform)) {
343
+ p.log.info(`Memory: run ${pc.bold("npx @aman_asmuei/amem")} to add automated memory`);
344
+ } else {
345
+ p.log.info(`Memory: built-in via core.md (upgrade with ${pc.bold("npx @aman_asmuei/amem")})`);
346
+ }
347
+ }
348
+ if (ecosystem.akit.installed) {
349
+ p.log.success(`Tools: ${ecosystem.akit.toolCount} tools configured`);
350
+ } else {
351
+ p.log.info(`Tools: run ${pc.bold("npx @aman_asmuei/akit add github")} to add capabilities`);
352
+ }
353
+ const card = [
354
+ "",
355
+ ` ${pc.green("\u2714")} Your AI companion is ready.`,
356
+ "",
357
+ ` ${pc.bold("aman status")} See your full ecosystem`,
358
+ ` ${pc.bold("acore customize")} Change personality`,
359
+ ` ${pc.bold("akit add <tool>")} Add tools`,
360
+ ` ${pc.bold("npx @aman_asmuei/amem")} Enable automated memory`,
361
+ ""
362
+ ];
363
+ p.note(card.join("\n"), "");
364
+ p.outro(pc.dim("Identity + Memory + Tools \u2014 one ecosystem."));
365
+ }
366
+
367
+ // src/commands/status.ts
368
+ import * as p2 from "@clack/prompts";
369
+ import pc2 from "picocolors";
370
+ import fs5 from "fs";
371
+ function statusCommand() {
372
+ p2.intro(pc2.bold("aman") + " \u2014 ecosystem status");
373
+ const ecosystem = detectEcosystem();
374
+ const platform = detectPlatform();
375
+ if (ecosystem.acore.installed) {
376
+ const content = fs5.readFileSync(ecosystem.acore.path, "utf-8");
377
+ const aiName = content.match(/^# (.+)$/m)?.[1] || "Companion";
378
+ const userName = content.match(/- Name: (.+)$/m)?.[1] || "Unknown";
379
+ p2.log.success(`Identity: ${pc2.bold(aiName)} + ${pc2.bold(userName)}`);
380
+ } else {
381
+ p2.log.error(`Identity: not set up \u2014 run ${pc2.bold("aman setup")}`);
382
+ }
383
+ if (ecosystem.amem.installed) {
384
+ p2.log.success("Memory: amem connected (automated)");
385
+ } else {
386
+ p2.log.warning(`Memory: standalone mode \u2014 ${pc2.dim("npx @aman_asmuei/amem to upgrade")}`);
387
+ }
388
+ if (ecosystem.akit.installed) {
389
+ p2.log.success(`Tools: ${ecosystem.akit.toolCount} installed \u2014 ${pc2.dim("akit list for details")}`);
390
+ } else {
391
+ p2.log.warning(`Tools: none \u2014 ${pc2.dim("npx @aman_asmuei/akit add github")}`);
392
+ }
393
+ const platformLabels = {
394
+ "claude-code": "Claude Code",
395
+ cursor: "Cursor",
396
+ windsurf: "Windsurf",
397
+ other: "Manual"
398
+ };
399
+ const platLabel = platformLabels[platform] || platform;
400
+ if (isMcpPlatform(platform)) {
401
+ p2.log.success(`Platform: ${pc2.bold(platLabel)} (auto-save + MCP)`);
402
+ } else {
403
+ p2.log.info(`Platform: ${pc2.bold(platLabel)}`);
404
+ }
405
+ let score = 0;
406
+ if (ecosystem.acore.installed) score += 1;
407
+ if (ecosystem.amem.installed) score += 1;
408
+ if (ecosystem.akit.installed) score += 1;
409
+ const levels = ["Not started", "Getting started", "Growing", "Complete ecosystem"];
410
+ const colors = [pc2.red, pc2.yellow, pc2.cyan, pc2.green];
411
+ p2.log.message("");
412
+ p2.log.info(`Ecosystem: ${colors[score](levels[score])} (${score}/3 layers active)`);
413
+ p2.outro("");
414
+ }
415
+
416
+ // src/index.ts
417
+ var program = new Command();
418
+ program.name("aman").description("Your complete AI companion \u2014 identity, memory, and tools in one command").version("0.1.0").action(() => {
419
+ const ecosystem = detectEcosystem();
420
+ if (ecosystem.acore.installed) {
421
+ statusCommand();
422
+ } else {
423
+ setupCommand();
424
+ }
425
+ });
426
+ program.command("setup").description("Set up your AI companion (identity + memory + tools)").action(() => setupCommand());
427
+ program.command("status").description("View your full ecosystem status").action(() => statusCommand());
428
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@aman_asmuei/aman",
3
+ "version": "0.1.0",
4
+ "description": "Your complete AI companion — identity, memory, and tools in one command",
5
+ "type": "module",
6
+ "bin": {
7
+ "aman": "./bin/aman.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "bin",
13
+ "template"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest",
20
+ "lint": "tsc --noEmit",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "keywords": [
27
+ "ai",
28
+ "llm",
29
+ "identity",
30
+ "memory",
31
+ "tools",
32
+ "agent",
33
+ "cli",
34
+ "acore",
35
+ "amem",
36
+ "akit"
37
+ ],
38
+ "author": "Aman Asmuei",
39
+ "license": "MIT",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/amanasmuei/aman.git"
43
+ },
44
+ "dependencies": {
45
+ "@clack/prompts": "^0.9.1",
46
+ "commander": "^13.1.0",
47
+ "picocolors": "^1.1.1"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^22.0.0",
51
+ "tsup": "^8.4.0",
52
+ "typescript": "^5.7.0",
53
+ "vitest": "^3.0.0"
54
+ }
55
+ }
@@ -0,0 +1,47 @@
1
+ # {{AI_NAME}}
2
+
3
+ ## Identity
4
+ - Role: {{AI_NAME}} is {{USER_NAME}}'s personal AI partner ({{USER_ROLE}})
5
+ - Personality: {{PERSONALITY}}
6
+ - Communication: {{COMMUNICATION}}
7
+ - Values: {{VALUES}}
8
+ - Boundaries: {{BOUNDARIES}}
9
+
10
+ ---
11
+
12
+ ## Relationship
13
+ - Name: {{USER_NAME}}
14
+ - Role: {{USER_ROLE}}
15
+ - Communication: [learns over time]
16
+ - Work: [set per project]
17
+ - Learned patterns: [builds over time]
18
+
19
+ ---
20
+
21
+ ## Session
22
+ - Last updated: {{DATE}}
23
+ - Resume: [first session]
24
+
25
+ ---
26
+
27
+ ## Instructions
28
+
29
+ {{UPDATE_INSTRUCTIONS}}
30
+
31
+ ### Growth Protocol
32
+ After 3 sessions: suggest adding Dynamics (trust, emotional patterns, conflict history)
33
+ After 5 sessions: suggest adding Context Modes (coding, creative, personal behavior)
34
+ After 10 sessions: suggest adding Memory Lifecycle rules (consolidation, compression, forgetting)
35
+ Each addition requires explicit user approval.
36
+
37
+ ### amem Integration (full mode)
38
+ When amem MCP tools are available:
39
+ - Session start: call `memory_recall` to enrich context
40
+ - During session: call `memory_store` for significant observations
41
+ - Session end: call `memory_context` for consolidation candidates
42
+ - Overflow: move details to amem, keep `[→ amem: topic]` pointer
43
+
44
+ ### Without amem (standalone mode)
45
+ - All updates via "update core" command or automatic file write
46
+ - AI follows Memory Lifecycle rules when generating updates
47
+ - AI reminds user to update if 3+ sessions have passed