@aman_asmuei/aman 0.5.1 → 0.5.3
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/dist/index.js +142 -69
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import { Command } from "commander";
|
|
|
4
4
|
// src/commands/setup.ts
|
|
5
5
|
import * as p from "@clack/prompts";
|
|
6
6
|
import pc from "picocolors";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
7
|
+
import fs5 from "fs";
|
|
8
|
+
import path4 from "path";
|
|
9
|
+
import os3 from "os";
|
|
10
10
|
|
|
11
11
|
// src/lib/detect.ts
|
|
12
12
|
import fs from "fs";
|
|
@@ -76,9 +76,18 @@ function detectRole(cwd) {
|
|
|
76
76
|
function isMcpPlatform(platform) {
|
|
77
77
|
return platform === "claude-code" || platform === "cursor" || platform === "windsurf";
|
|
78
78
|
}
|
|
79
|
+
function resolveLayerFile(layerDir, filename, home) {
|
|
80
|
+
const homeDir = home ?? os.homedir();
|
|
81
|
+
const scopedPath = path.join(homeDir, layerDir, "dev", "plugin", filename);
|
|
82
|
+
const legacyPath = path.join(homeDir, layerDir, filename);
|
|
83
|
+
if (fs.existsSync(scopedPath)) return scopedPath;
|
|
84
|
+
if (fs.existsSync(legacyPath)) return legacyPath;
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
79
87
|
function detectEcosystem() {
|
|
80
88
|
const home = os.homedir();
|
|
81
|
-
const
|
|
89
|
+
const acoreResolvedPath = resolveLayerFile(".acore", "core.md");
|
|
90
|
+
const acorePath = acoreResolvedPath ?? path.join(home, ".acore", "dev", "plugin", "core.md");
|
|
82
91
|
const akitPath = path.join(home, ".akit", "kit.md");
|
|
83
92
|
const akitInstalledPath = path.join(home, ".akit", "installed.json");
|
|
84
93
|
let akitToolCount = 0;
|
|
@@ -113,11 +122,12 @@ function detectEcosystem() {
|
|
|
113
122
|
} catch {
|
|
114
123
|
}
|
|
115
124
|
}
|
|
116
|
-
const
|
|
125
|
+
const arulesResolvedPath = resolveLayerFile(".arules", "rules.md");
|
|
126
|
+
const arulesPath = arulesResolvedPath ?? path.join(home, ".arules", "dev", "plugin", "rules.md");
|
|
117
127
|
let arulesRuleCount = 0;
|
|
118
|
-
if (
|
|
128
|
+
if (arulesResolvedPath) {
|
|
119
129
|
try {
|
|
120
|
-
const content = fs.readFileSync(
|
|
130
|
+
const content = fs.readFileSync(arulesResolvedPath, "utf-8");
|
|
121
131
|
arulesRuleCount = (content.match(/^- /gm) || []).length;
|
|
122
132
|
} catch {
|
|
123
133
|
}
|
|
@@ -142,11 +152,11 @@ function detectEcosystem() {
|
|
|
142
152
|
}
|
|
143
153
|
}
|
|
144
154
|
return {
|
|
145
|
-
acore: { installed:
|
|
155
|
+
acore: { installed: acoreResolvedPath !== null, path: acorePath },
|
|
146
156
|
amem: { installed: amemInstalled },
|
|
147
157
|
akit: { installed: fs.existsSync(akitPath), path: akitPath, toolCount: akitToolCount },
|
|
148
158
|
aflow: { installed: fs.existsSync(aflowPath), path: aflowPath, workflowCount: aflowWorkflowCount },
|
|
149
|
-
arules: { installed:
|
|
159
|
+
arules: { installed: arulesResolvedPath !== null, path: arulesPath, ruleCount: arulesRuleCount },
|
|
150
160
|
aeval: { installed: fs.existsSync(aevalPath), path: aevalPath, sessions: aevalSessions },
|
|
151
161
|
askill: { installed: fs.existsSync(askillPath), path: askillPath, skillCount: askillCount }
|
|
152
162
|
};
|
|
@@ -256,6 +266,58 @@ function getPlatformFile(platform) {
|
|
|
256
266
|
}
|
|
257
267
|
}
|
|
258
268
|
|
|
269
|
+
// src/lib/heal.ts
|
|
270
|
+
import fs4 from "fs";
|
|
271
|
+
import path3 from "path";
|
|
272
|
+
import os2 from "os";
|
|
273
|
+
var TEMPLATE_MARKERS = /\[your name\]|\[YOUR_NAME\]|\[AI_NAME\]/;
|
|
274
|
+
function healLayerScope(layerDir, filename, home) {
|
|
275
|
+
const homeDir = home ?? os2.homedir();
|
|
276
|
+
const scopedPath = path3.join(homeDir, layerDir, "dev", "plugin", filename);
|
|
277
|
+
const legacyPath = path3.join(homeDir, layerDir, filename);
|
|
278
|
+
const scopedExists = fs4.existsSync(scopedPath);
|
|
279
|
+
const legacyExists = fs4.existsSync(legacyPath);
|
|
280
|
+
if (!legacyExists) {
|
|
281
|
+
return scopedExists ? "ok" : "no-op";
|
|
282
|
+
}
|
|
283
|
+
const legacyContent = fs4.readFileSync(legacyPath, "utf-8");
|
|
284
|
+
if (TEMPLATE_MARKERS.test(legacyContent)) {
|
|
285
|
+
return "no-op";
|
|
286
|
+
}
|
|
287
|
+
if (!scopedExists) {
|
|
288
|
+
fs4.mkdirSync(path3.dirname(scopedPath), { recursive: true });
|
|
289
|
+
fs4.writeFileSync(scopedPath, legacyContent, "utf-8");
|
|
290
|
+
return "migrated";
|
|
291
|
+
}
|
|
292
|
+
const scopedContent = fs4.readFileSync(scopedPath, "utf-8");
|
|
293
|
+
if (TEMPLATE_MARKERS.test(scopedContent)) {
|
|
294
|
+
fs4.writeFileSync(scopedPath, legacyContent, "utf-8");
|
|
295
|
+
return "repaired";
|
|
296
|
+
}
|
|
297
|
+
return "ok";
|
|
298
|
+
}
|
|
299
|
+
function healResultMessage(layerDir, filename, result) {
|
|
300
|
+
if (result === "migrated") {
|
|
301
|
+
return `${layerDir.replace(/^\./, "")}: migrated ~/${layerDir}/${filename} \u2192 ~/${layerDir}/dev/plugin/${filename}`;
|
|
302
|
+
}
|
|
303
|
+
if (result === "repaired") {
|
|
304
|
+
return `${layerDir.replace(/^\./, "")}: replaced unfilled template at ~/${layerDir}/dev/plugin/${filename} with your personalised content`;
|
|
305
|
+
}
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
function runAutoHeal(home) {
|
|
309
|
+
const messages = [];
|
|
310
|
+
for (const [layerDir, filename] of [
|
|
311
|
+
[".acore", "core.md"],
|
|
312
|
+
[".arules", "rules.md"]
|
|
313
|
+
]) {
|
|
314
|
+
const result = healLayerScope(layerDir, filename, home);
|
|
315
|
+
const msg = healResultMessage(layerDir, filename, result);
|
|
316
|
+
if (msg) messages.push(msg);
|
|
317
|
+
}
|
|
318
|
+
return messages;
|
|
319
|
+
}
|
|
320
|
+
|
|
259
321
|
// src/templates.ts
|
|
260
322
|
var STARTER_FLOW = `# My Workflows
|
|
261
323
|
|
|
@@ -373,9 +435,12 @@ var ARCHETYPES = {
|
|
|
373
435
|
};
|
|
374
436
|
async function setupCommand() {
|
|
375
437
|
p.intro(pc.bold("aman") + " \u2014 your complete AI companion");
|
|
438
|
+
for (const msg of runAutoHeal()) {
|
|
439
|
+
p.log.success(msg);
|
|
440
|
+
}
|
|
376
441
|
const ecosystem = detectEcosystem();
|
|
377
442
|
if (ecosystem.acore.installed) {
|
|
378
|
-
p.log.success(`Identity: ${pc.dim(
|
|
443
|
+
p.log.success(`Identity: ${pc.dim(ecosystem.acore.path)} already exists`);
|
|
379
444
|
} else {
|
|
380
445
|
p.log.step("Setting up your AI identity...");
|
|
381
446
|
let userName = detectUserName();
|
|
@@ -421,13 +486,13 @@ async function setupCommand() {
|
|
|
421
486
|
DATE: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
422
487
|
UPDATE_INSTRUCTIONS: getUpdateInstructions(platform)
|
|
423
488
|
});
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
p.log.success(`Created ${pc.dim("~/.acore/core.md")} (identity)`);
|
|
489
|
+
const scopedAcoreDir = path4.join(os3.homedir(), ".acore", "dev", "plugin");
|
|
490
|
+
fs5.mkdirSync(scopedAcoreDir, { recursive: true });
|
|
491
|
+
fs5.writeFileSync(path4.join(scopedAcoreDir, "core.md"), content, "utf-8");
|
|
492
|
+
p.log.success(`Created ${pc.dim("~/.acore/dev/plugin/core.md")} (identity)`);
|
|
428
493
|
if (stack) {
|
|
429
|
-
const localDir =
|
|
430
|
-
|
|
494
|
+
const localDir = path4.join(process.cwd(), ".acore");
|
|
495
|
+
fs5.mkdirSync(localDir, { recursive: true });
|
|
431
496
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
432
497
|
const contextContent = `## Work
|
|
433
498
|
- Stack: ${stack}
|
|
@@ -444,9 +509,9 @@ async function setupCommand() {
|
|
|
444
509
|
## Project Patterns
|
|
445
510
|
- [observations specific to this project \u2014 built over time]
|
|
446
511
|
`;
|
|
447
|
-
|
|
512
|
+
fs5.writeFileSync(path4.join(localDir, "context.md"), contextContent, "utf-8");
|
|
448
513
|
const configContent = JSON.stringify({ platform: platform || "other" }, null, 2) + "\n";
|
|
449
|
-
|
|
514
|
+
fs5.writeFileSync(path4.join(localDir, "config.json"), configContent, "utf-8");
|
|
450
515
|
} else {
|
|
451
516
|
p.log.info(
|
|
452
517
|
`No project detected here \u2014 run ${pc.bold("aman here")} later from inside any repo to add per-project context.`
|
|
@@ -454,9 +519,8 @@ async function setupCommand() {
|
|
|
454
519
|
}
|
|
455
520
|
const platformFile = getPlatformFile(platform);
|
|
456
521
|
if (platformFile) {
|
|
457
|
-
const
|
|
458
|
-
const
|
|
459
|
-
const result = injectIntoFile(filePath, globalContent);
|
|
522
|
+
const filePath = path4.join(process.cwd(), platformFile);
|
|
523
|
+
const result = injectIntoFile(filePath, content);
|
|
460
524
|
if (result.created) {
|
|
461
525
|
p.log.success(`Created ${pc.dim(platformFile)} with identity`);
|
|
462
526
|
} else {
|
|
@@ -467,7 +531,7 @@ async function setupCommand() {
|
|
|
467
531
|
if (stack) inferredParts.push(stack);
|
|
468
532
|
p.log.info(`Inferred: ${pc.dim(inferredParts.join(" \xB7 "))}`);
|
|
469
533
|
}
|
|
470
|
-
const home =
|
|
534
|
+
const home = os3.homedir();
|
|
471
535
|
const aflowExists = ecosystem.aflow.installed;
|
|
472
536
|
const arulesExists = ecosystem.arules.installed;
|
|
473
537
|
const aevalExists = ecosystem.aeval.installed;
|
|
@@ -510,26 +574,26 @@ async function setupCommand() {
|
|
|
510
574
|
doEval = selected.includes("eval");
|
|
511
575
|
}
|
|
512
576
|
if (doFlow) {
|
|
513
|
-
const aflowDir =
|
|
514
|
-
|
|
515
|
-
|
|
577
|
+
const aflowDir = path4.join(home, ".aflow");
|
|
578
|
+
fs5.mkdirSync(aflowDir, { recursive: true });
|
|
579
|
+
fs5.writeFileSync(path4.join(aflowDir, "flow.md"), STARTER_FLOW, "utf-8");
|
|
516
580
|
p.log.success(`Workflows: created ${pc.dim("~/.aflow/flow.md")} (4 starter workflows)`);
|
|
517
581
|
} else if (aflowExists) {
|
|
518
582
|
p.log.success(`Workflows: ${ecosystem.aflow.workflowCount} defined`);
|
|
519
583
|
}
|
|
520
584
|
if (doRules) {
|
|
521
|
-
const arulesDir =
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
p.log.success(`Guardrails: created ${pc.dim("~/.arules/rules.md")} (24 rules)`);
|
|
585
|
+
const arulesDir = path4.join(home, ".arules", "dev", "plugin");
|
|
586
|
+
fs5.mkdirSync(arulesDir, { recursive: true });
|
|
587
|
+
fs5.writeFileSync(path4.join(arulesDir, "rules.md"), STARTER_RULES, "utf-8");
|
|
588
|
+
p.log.success(`Guardrails: created ${pc.dim("~/.arules/dev/plugin/rules.md")} (24 rules)`);
|
|
525
589
|
} else if (arulesExists) {
|
|
526
590
|
p.log.success(`Guardrails: ${ecosystem.arules.ruleCount} rules`);
|
|
527
591
|
}
|
|
528
592
|
if (doEval) {
|
|
529
|
-
const aevalDir =
|
|
530
|
-
|
|
593
|
+
const aevalDir = path4.join(home, ".aeval");
|
|
594
|
+
fs5.mkdirSync(aevalDir, { recursive: true });
|
|
531
595
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
532
|
-
|
|
596
|
+
fs5.writeFileSync(path4.join(aevalDir, "eval.md"), STARTER_EVAL.replace("{{DATE}}", today), "utf-8");
|
|
533
597
|
p.log.success(`Evaluation: created ${pc.dim("~/.aeval/eval.md")}`);
|
|
534
598
|
} else if (aevalExists) {
|
|
535
599
|
p.log.success("Evaluation: already configured");
|
|
@@ -563,13 +627,13 @@ async function setupCommand() {
|
|
|
563
627
|
// src/commands/status.ts
|
|
564
628
|
import * as p2 from "@clack/prompts";
|
|
565
629
|
import pc2 from "picocolors";
|
|
566
|
-
import
|
|
630
|
+
import fs6 from "fs";
|
|
567
631
|
function statusCommand() {
|
|
568
632
|
p2.intro(pc2.bold("aman") + " \u2014 ecosystem status");
|
|
569
633
|
const ecosystem = detectEcosystem();
|
|
570
634
|
const platform = detectPlatform();
|
|
571
635
|
if (ecosystem.acore.installed) {
|
|
572
|
-
const content =
|
|
636
|
+
const content = fs6.readFileSync(ecosystem.acore.path, "utf-8");
|
|
573
637
|
const aiName = content.match(/^# (.+)$/m)?.[1] || "Companion";
|
|
574
638
|
const userName = content.match(/- Name: (.+)$/m)?.[1] || "Unknown";
|
|
575
639
|
p2.log.success(`Identity: ${pc2.bold(aiName)} + ${pc2.bold(userName)}`);
|
|
@@ -634,8 +698,8 @@ function statusCommand() {
|
|
|
634
698
|
}
|
|
635
699
|
|
|
636
700
|
// src/commands/deploy.ts
|
|
637
|
-
import
|
|
638
|
-
import
|
|
701
|
+
import fs7 from "fs";
|
|
702
|
+
import path5 from "path";
|
|
639
703
|
import * as p3 from "@clack/prompts";
|
|
640
704
|
import pc3 from "picocolors";
|
|
641
705
|
async function deployCommand() {
|
|
@@ -692,15 +756,15 @@ AMAN_MODEL=${isAnthropic ? "claude-sonnet-4-6" : "gpt-4o"}
|
|
|
692
756
|
# TELEGRAM_BOT_TOKEN=
|
|
693
757
|
# DISCORD_BOT_TOKEN=
|
|
694
758
|
`;
|
|
695
|
-
const envPath =
|
|
696
|
-
|
|
759
|
+
const envPath = path5.join(cwd, ".env");
|
|
760
|
+
fs7.writeFileSync(envPath, envContent, "utf-8");
|
|
697
761
|
p3.log.success(`Created ${pc3.bold(".env")} with API key`);
|
|
698
762
|
const pkgDir = findPackageDir();
|
|
699
763
|
copyDeployFile(pkgDir, cwd, "Dockerfile");
|
|
700
764
|
copyDeployFile(pkgDir, cwd, "docker-entrypoint.sh");
|
|
701
765
|
copyDeployFile(pkgDir, cwd, "docker-compose.yml");
|
|
702
766
|
try {
|
|
703
|
-
|
|
767
|
+
fs7.chmodSync(path5.join(cwd, "docker-entrypoint.sh"), 493);
|
|
704
768
|
} catch {
|
|
705
769
|
}
|
|
706
770
|
p3.log.success(`Created ${pc3.bold("Dockerfile")} + ${pc3.bold("docker-compose.yml")}`);
|
|
@@ -736,20 +800,20 @@ AMAN_MODEL=${model}
|
|
|
736
800
|
# TELEGRAM_BOT_TOKEN=
|
|
737
801
|
# DISCORD_BOT_TOKEN=
|
|
738
802
|
`;
|
|
739
|
-
const envPath =
|
|
740
|
-
|
|
803
|
+
const envPath = path5.join(cwd, ".env");
|
|
804
|
+
fs7.writeFileSync(envPath, envContent, "utf-8");
|
|
741
805
|
p3.log.success(`Created ${pc3.bold(".env")} with Ollama config`);
|
|
742
806
|
const pkgDir = findPackageDir();
|
|
743
807
|
copyDeployFile(pkgDir, cwd, "Dockerfile");
|
|
744
808
|
copyDeployFile(pkgDir, cwd, "docker-entrypoint.sh");
|
|
745
809
|
copyDeployFile(pkgDir, cwd, "docker-compose.ollama.yml");
|
|
746
|
-
const src =
|
|
747
|
-
const dest =
|
|
748
|
-
if (
|
|
749
|
-
|
|
810
|
+
const src = path5.join(cwd, "docker-compose.ollama.yml");
|
|
811
|
+
const dest = path5.join(cwd, "docker-compose.yml");
|
|
812
|
+
if (fs7.existsSync(src) && !fs7.existsSync(dest)) {
|
|
813
|
+
fs7.renameSync(src, dest);
|
|
750
814
|
}
|
|
751
815
|
try {
|
|
752
|
-
|
|
816
|
+
fs7.chmodSync(path5.join(cwd, "docker-entrypoint.sh"), 493);
|
|
753
817
|
} catch {
|
|
754
818
|
}
|
|
755
819
|
p3.log.success(`Created ${pc3.bold("Dockerfile")} + ${pc3.bold("docker-compose.yml")} (with Ollama)`);
|
|
@@ -826,18 +890,18 @@ ${pc3.bold("Raspberry Pi:")}
|
|
|
826
890
|
function findPackageDir() {
|
|
827
891
|
let dir = new URL(".", import.meta.url).pathname;
|
|
828
892
|
for (let i = 0; i < 5; i++) {
|
|
829
|
-
if (
|
|
830
|
-
dir =
|
|
893
|
+
if (fs7.existsSync(path5.join(dir, "Dockerfile"))) return dir;
|
|
894
|
+
dir = path5.dirname(dir);
|
|
831
895
|
}
|
|
832
|
-
const globalDir =
|
|
833
|
-
if (
|
|
896
|
+
const globalDir = path5.join(process.env.npm_config_prefix || "/usr/local", "lib/node_modules/@aman_asmuei/aman");
|
|
897
|
+
if (fs7.existsSync(path5.join(globalDir, "Dockerfile"))) return globalDir;
|
|
834
898
|
return process.cwd();
|
|
835
899
|
}
|
|
836
900
|
function copyDeployFile(pkgDir, destDir, filename) {
|
|
837
|
-
const src =
|
|
838
|
-
const dest =
|
|
839
|
-
if (
|
|
840
|
-
|
|
901
|
+
const src = path5.join(pkgDir, filename);
|
|
902
|
+
const dest = path5.join(destDir, filename);
|
|
903
|
+
if (fs7.existsSync(src)) {
|
|
904
|
+
fs7.copyFileSync(src, dest);
|
|
841
905
|
}
|
|
842
906
|
}
|
|
843
907
|
|
|
@@ -967,14 +1031,14 @@ async function showcaseCommand(nameArg, opts = {}) {
|
|
|
967
1031
|
// src/commands/here.ts
|
|
968
1032
|
import * as p5 from "@clack/prompts";
|
|
969
1033
|
import pc5 from "picocolors";
|
|
970
|
-
import
|
|
971
|
-
import
|
|
1034
|
+
import fs8 from "fs";
|
|
1035
|
+
import path6 from "path";
|
|
972
1036
|
async function hereCommand(opts = {}) {
|
|
973
1037
|
const cwd = process.cwd();
|
|
974
|
-
const acoreDir =
|
|
975
|
-
const contextPath =
|
|
976
|
-
const configPath =
|
|
977
|
-
if (
|
|
1038
|
+
const acoreDir = path6.join(cwd, ".acore");
|
|
1039
|
+
const contextPath = path6.join(acoreDir, "context.md");
|
|
1040
|
+
const configPath = path6.join(acoreDir, "config.json");
|
|
1041
|
+
if (fs8.existsSync(contextPath) && !opts.force) {
|
|
978
1042
|
p5.intro(pc5.bold("aman here") + " \u2014 project context card");
|
|
979
1043
|
const overwrite = await p5.confirm({
|
|
980
1044
|
message: `${pc5.dim(".acore/context.md")} already exists. Overwrite?`,
|
|
@@ -988,7 +1052,7 @@ async function hereCommand(opts = {}) {
|
|
|
988
1052
|
const stack = detectStack() || "unknown";
|
|
989
1053
|
const platform = detectPlatform();
|
|
990
1054
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
991
|
-
|
|
1055
|
+
fs8.mkdirSync(acoreDir, { recursive: true });
|
|
992
1056
|
const contextContent = `## Work
|
|
993
1057
|
- Stack: ${stack}
|
|
994
1058
|
- Domain:
|
|
@@ -1004,21 +1068,21 @@ async function hereCommand(opts = {}) {
|
|
|
1004
1068
|
## Project Patterns
|
|
1005
1069
|
- [observations specific to this project \u2014 built over time]
|
|
1006
1070
|
`;
|
|
1007
|
-
|
|
1008
|
-
if (
|
|
1071
|
+
fs8.writeFileSync(contextPath, contextContent, "utf-8");
|
|
1072
|
+
if (fs8.existsSync(configPath)) {
|
|
1009
1073
|
try {
|
|
1010
|
-
const existing = JSON.parse(
|
|
1074
|
+
const existing = JSON.parse(fs8.readFileSync(configPath, "utf-8"));
|
|
1011
1075
|
if (typeof existing.platform !== "string" || existing.platform === "") {
|
|
1012
1076
|
existing.platform = platform || "other";
|
|
1013
|
-
|
|
1077
|
+
fs8.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
1014
1078
|
}
|
|
1015
1079
|
} catch {
|
|
1016
1080
|
const fresh = { platform: platform || "other" };
|
|
1017
|
-
|
|
1081
|
+
fs8.writeFileSync(configPath, JSON.stringify(fresh, null, 2) + "\n", "utf-8");
|
|
1018
1082
|
}
|
|
1019
1083
|
} else {
|
|
1020
1084
|
const fresh = { platform: platform || "other" };
|
|
1021
|
-
|
|
1085
|
+
fs8.writeFileSync(configPath, JSON.stringify(fresh, null, 2) + "\n", "utf-8");
|
|
1022
1086
|
}
|
|
1023
1087
|
if (opts.force) {
|
|
1024
1088
|
return;
|
|
@@ -1031,8 +1095,12 @@ async function hereCommand(opts = {}) {
|
|
|
1031
1095
|
}
|
|
1032
1096
|
|
|
1033
1097
|
// src/index.ts
|
|
1098
|
+
import pc6 from "picocolors";
|
|
1034
1099
|
var program = new Command();
|
|
1035
|
-
program.name("aman").description("Your complete AI companion \u2014 identity, memory, and tools in one command").version("0.5.
|
|
1100
|
+
program.name("aman").description("Your complete AI companion \u2014 identity, memory, and tools in one command").version("0.5.3").action(() => {
|
|
1101
|
+
for (const msg of runAutoHeal()) {
|
|
1102
|
+
console.log(` ${pc6.green("\u2714")} ${msg}`);
|
|
1103
|
+
}
|
|
1036
1104
|
const ecosystem = detectEcosystem();
|
|
1037
1105
|
if (ecosystem.acore.installed) {
|
|
1038
1106
|
statusCommand();
|
|
@@ -1041,7 +1109,12 @@ program.name("aman").description("Your complete AI companion \u2014 identity, me
|
|
|
1041
1109
|
}
|
|
1042
1110
|
});
|
|
1043
1111
|
program.command("setup").description("Set up your AI companion (identity + memory + tools)").action(() => setupCommand());
|
|
1044
|
-
program.command("status").description("View your full ecosystem status").action(() =>
|
|
1112
|
+
program.command("status").description("View your full ecosystem status").action(() => {
|
|
1113
|
+
for (const msg of runAutoHeal()) {
|
|
1114
|
+
console.log(` ${pc6.green("\u2714")} ${msg}`);
|
|
1115
|
+
}
|
|
1116
|
+
statusCommand();
|
|
1117
|
+
});
|
|
1045
1118
|
program.command("deploy").description("Deploy your AI companion (Docker, systemd, or cloud)").action(() => deployCommand());
|
|
1046
1119
|
program.command("showcase [name]").description("Set up a showcase AI companion (rutin, kedai, monitor, ...)").option("--dry-run", "preview files without installing").option("--list", "list all available showcases").action(
|
|
1047
1120
|
(name, opts) => showcaseCommand(name, opts)
|