@aman_asmuei/aman 0.5.2 → 0.5.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.
- package/dist/index.js +140 -90
- 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";
|
|
@@ -266,6 +266,75 @@ function getPlatformFile(platform) {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
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
|
+
if (scopedContent === legacyContent) {
|
|
298
|
+
return "ok";
|
|
299
|
+
}
|
|
300
|
+
const legacyMtime = fs4.statSync(legacyPath).mtimeMs;
|
|
301
|
+
const scopedMtime = fs4.statSync(scopedPath).mtimeMs;
|
|
302
|
+
if (legacyMtime > scopedMtime) {
|
|
303
|
+
fs4.writeFileSync(scopedPath, legacyContent, "utf-8");
|
|
304
|
+
return "synced";
|
|
305
|
+
}
|
|
306
|
+
if (scopedMtime > legacyMtime) {
|
|
307
|
+
fs4.writeFileSync(legacyPath, scopedContent, "utf-8");
|
|
308
|
+
return "synced";
|
|
309
|
+
}
|
|
310
|
+
fs4.writeFileSync(legacyPath, scopedContent, "utf-8");
|
|
311
|
+
return "synced";
|
|
312
|
+
}
|
|
313
|
+
function healResultMessage(layerDir, filename, result) {
|
|
314
|
+
if (result === "migrated") {
|
|
315
|
+
return `${layerDir.replace(/^\./, "")}: migrated ~/${layerDir}/${filename} \u2192 ~/${layerDir}/dev/plugin/${filename}`;
|
|
316
|
+
}
|
|
317
|
+
if (result === "repaired") {
|
|
318
|
+
return `${layerDir.replace(/^\./, "")}: replaced unfilled template at ~/${layerDir}/dev/plugin/${filename} with your personalised content`;
|
|
319
|
+
}
|
|
320
|
+
if (result === "synced") {
|
|
321
|
+
return `${layerDir.replace(/^\./, "")}: synced diverged content between ~/${layerDir}/${filename} and ~/${layerDir}/dev/plugin/${filename} (newer wins)`;
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
function runAutoHeal(home) {
|
|
326
|
+
const messages = [];
|
|
327
|
+
for (const [layerDir, filename] of [
|
|
328
|
+
[".acore", "core.md"],
|
|
329
|
+
[".arules", "rules.md"]
|
|
330
|
+
]) {
|
|
331
|
+
const result = healLayerScope(layerDir, filename, home);
|
|
332
|
+
const msg = healResultMessage(layerDir, filename, result);
|
|
333
|
+
if (msg) messages.push(msg);
|
|
334
|
+
}
|
|
335
|
+
return messages;
|
|
336
|
+
}
|
|
337
|
+
|
|
269
338
|
// src/templates.ts
|
|
270
339
|
var STARTER_FLOW = `# My Workflows
|
|
271
340
|
|
|
@@ -383,40 +452,12 @@ var ARCHETYPES = {
|
|
|
383
452
|
};
|
|
384
453
|
async function setupCommand() {
|
|
385
454
|
p.intro(pc.bold("aman") + " \u2014 your complete AI companion");
|
|
455
|
+
for (const msg of runAutoHeal()) {
|
|
456
|
+
p.log.success(msg);
|
|
457
|
+
}
|
|
386
458
|
const ecosystem = detectEcosystem();
|
|
387
|
-
const scopedCorePath = path3.join(os2.homedir(), ".acore", "dev", "plugin", "core.md");
|
|
388
|
-
const legacyCorePath = path3.join(os2.homedir(), ".acore", "core.md");
|
|
389
459
|
if (ecosystem.acore.installed) {
|
|
390
|
-
|
|
391
|
-
const legacyExists = fs4.existsSync(legacyCorePath);
|
|
392
|
-
if (legacyExists) {
|
|
393
|
-
const legacyContent = fs4.readFileSync(legacyCorePath, "utf-8");
|
|
394
|
-
const legacyIsTemplate = /\[your name\]|\[YOUR_NAME\]|\[AI_NAME\]/.test(legacyContent);
|
|
395
|
-
if (!legacyIsTemplate) {
|
|
396
|
-
if (!scopedExists) {
|
|
397
|
-
fs4.mkdirSync(path3.dirname(scopedCorePath), { recursive: true });
|
|
398
|
-
fs4.writeFileSync(scopedCorePath, legacyContent, "utf-8");
|
|
399
|
-
p.log.success(
|
|
400
|
-
`Identity: migrated ${pc.dim("~/.acore/core.md")} \u2192 ${pc.dim("~/.acore/dev/plugin/core.md")}`
|
|
401
|
-
);
|
|
402
|
-
} else {
|
|
403
|
-
const scopedContent = fs4.readFileSync(scopedCorePath, "utf-8");
|
|
404
|
-
const scopedIsTemplate = /\[your name\]|\[YOUR_NAME\]|\[AI_NAME\]/.test(scopedContent);
|
|
405
|
-
if (scopedIsTemplate) {
|
|
406
|
-
fs4.writeFileSync(scopedCorePath, legacyContent, "utf-8");
|
|
407
|
-
p.log.success(
|
|
408
|
-
`Identity: replaced unfilled template at ${pc.dim("~/.acore/dev/plugin/core.md")} with your personalized identity`
|
|
409
|
-
);
|
|
410
|
-
} else {
|
|
411
|
-
p.log.success(`Identity: ${pc.dim(ecosystem.acore.path)} already exists`);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
} else {
|
|
415
|
-
p.log.success(`Identity: ${pc.dim(ecosystem.acore.path)} already exists`);
|
|
416
|
-
}
|
|
417
|
-
} else {
|
|
418
|
-
p.log.success(`Identity: ${pc.dim(ecosystem.acore.path)} already exists`);
|
|
419
|
-
}
|
|
460
|
+
p.log.success(`Identity: ${pc.dim(ecosystem.acore.path)} already exists`);
|
|
420
461
|
} else {
|
|
421
462
|
p.log.step("Setting up your AI identity...");
|
|
422
463
|
let userName = detectUserName();
|
|
@@ -462,13 +503,13 @@ async function setupCommand() {
|
|
|
462
503
|
DATE: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
463
504
|
UPDATE_INSTRUCTIONS: getUpdateInstructions(platform)
|
|
464
505
|
});
|
|
465
|
-
const scopedAcoreDir =
|
|
466
|
-
|
|
467
|
-
|
|
506
|
+
const scopedAcoreDir = path4.join(os3.homedir(), ".acore", "dev", "plugin");
|
|
507
|
+
fs5.mkdirSync(scopedAcoreDir, { recursive: true });
|
|
508
|
+
fs5.writeFileSync(path4.join(scopedAcoreDir, "core.md"), content, "utf-8");
|
|
468
509
|
p.log.success(`Created ${pc.dim("~/.acore/dev/plugin/core.md")} (identity)`);
|
|
469
510
|
if (stack) {
|
|
470
|
-
const localDir =
|
|
471
|
-
|
|
511
|
+
const localDir = path4.join(process.cwd(), ".acore");
|
|
512
|
+
fs5.mkdirSync(localDir, { recursive: true });
|
|
472
513
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
473
514
|
const contextContent = `## Work
|
|
474
515
|
- Stack: ${stack}
|
|
@@ -485,9 +526,9 @@ async function setupCommand() {
|
|
|
485
526
|
## Project Patterns
|
|
486
527
|
- [observations specific to this project \u2014 built over time]
|
|
487
528
|
`;
|
|
488
|
-
|
|
529
|
+
fs5.writeFileSync(path4.join(localDir, "context.md"), contextContent, "utf-8");
|
|
489
530
|
const configContent = JSON.stringify({ platform: platform || "other" }, null, 2) + "\n";
|
|
490
|
-
|
|
531
|
+
fs5.writeFileSync(path4.join(localDir, "config.json"), configContent, "utf-8");
|
|
491
532
|
} else {
|
|
492
533
|
p.log.info(
|
|
493
534
|
`No project detected here \u2014 run ${pc.bold("aman here")} later from inside any repo to add per-project context.`
|
|
@@ -495,7 +536,7 @@ async function setupCommand() {
|
|
|
495
536
|
}
|
|
496
537
|
const platformFile = getPlatformFile(platform);
|
|
497
538
|
if (platformFile) {
|
|
498
|
-
const filePath =
|
|
539
|
+
const filePath = path4.join(process.cwd(), platformFile);
|
|
499
540
|
const result = injectIntoFile(filePath, content);
|
|
500
541
|
if (result.created) {
|
|
501
542
|
p.log.success(`Created ${pc.dim(platformFile)} with identity`);
|
|
@@ -507,7 +548,7 @@ async function setupCommand() {
|
|
|
507
548
|
if (stack) inferredParts.push(stack);
|
|
508
549
|
p.log.info(`Inferred: ${pc.dim(inferredParts.join(" \xB7 "))}`);
|
|
509
550
|
}
|
|
510
|
-
const home =
|
|
551
|
+
const home = os3.homedir();
|
|
511
552
|
const aflowExists = ecosystem.aflow.installed;
|
|
512
553
|
const arulesExists = ecosystem.arules.installed;
|
|
513
554
|
const aevalExists = ecosystem.aeval.installed;
|
|
@@ -550,26 +591,26 @@ async function setupCommand() {
|
|
|
550
591
|
doEval = selected.includes("eval");
|
|
551
592
|
}
|
|
552
593
|
if (doFlow) {
|
|
553
|
-
const aflowDir =
|
|
554
|
-
|
|
555
|
-
|
|
594
|
+
const aflowDir = path4.join(home, ".aflow");
|
|
595
|
+
fs5.mkdirSync(aflowDir, { recursive: true });
|
|
596
|
+
fs5.writeFileSync(path4.join(aflowDir, "flow.md"), STARTER_FLOW, "utf-8");
|
|
556
597
|
p.log.success(`Workflows: created ${pc.dim("~/.aflow/flow.md")} (4 starter workflows)`);
|
|
557
598
|
} else if (aflowExists) {
|
|
558
599
|
p.log.success(`Workflows: ${ecosystem.aflow.workflowCount} defined`);
|
|
559
600
|
}
|
|
560
601
|
if (doRules) {
|
|
561
|
-
const arulesDir =
|
|
562
|
-
|
|
563
|
-
|
|
602
|
+
const arulesDir = path4.join(home, ".arules", "dev", "plugin");
|
|
603
|
+
fs5.mkdirSync(arulesDir, { recursive: true });
|
|
604
|
+
fs5.writeFileSync(path4.join(arulesDir, "rules.md"), STARTER_RULES, "utf-8");
|
|
564
605
|
p.log.success(`Guardrails: created ${pc.dim("~/.arules/dev/plugin/rules.md")} (24 rules)`);
|
|
565
606
|
} else if (arulesExists) {
|
|
566
607
|
p.log.success(`Guardrails: ${ecosystem.arules.ruleCount} rules`);
|
|
567
608
|
}
|
|
568
609
|
if (doEval) {
|
|
569
|
-
const aevalDir =
|
|
570
|
-
|
|
610
|
+
const aevalDir = path4.join(home, ".aeval");
|
|
611
|
+
fs5.mkdirSync(aevalDir, { recursive: true });
|
|
571
612
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
572
|
-
|
|
613
|
+
fs5.writeFileSync(path4.join(aevalDir, "eval.md"), STARTER_EVAL.replace("{{DATE}}", today), "utf-8");
|
|
573
614
|
p.log.success(`Evaluation: created ${pc.dim("~/.aeval/eval.md")}`);
|
|
574
615
|
} else if (aevalExists) {
|
|
575
616
|
p.log.success("Evaluation: already configured");
|
|
@@ -603,13 +644,13 @@ async function setupCommand() {
|
|
|
603
644
|
// src/commands/status.ts
|
|
604
645
|
import * as p2 from "@clack/prompts";
|
|
605
646
|
import pc2 from "picocolors";
|
|
606
|
-
import
|
|
647
|
+
import fs6 from "fs";
|
|
607
648
|
function statusCommand() {
|
|
608
649
|
p2.intro(pc2.bold("aman") + " \u2014 ecosystem status");
|
|
609
650
|
const ecosystem = detectEcosystem();
|
|
610
651
|
const platform = detectPlatform();
|
|
611
652
|
if (ecosystem.acore.installed) {
|
|
612
|
-
const content =
|
|
653
|
+
const content = fs6.readFileSync(ecosystem.acore.path, "utf-8");
|
|
613
654
|
const aiName = content.match(/^# (.+)$/m)?.[1] || "Companion";
|
|
614
655
|
const userName = content.match(/- Name: (.+)$/m)?.[1] || "Unknown";
|
|
615
656
|
p2.log.success(`Identity: ${pc2.bold(aiName)} + ${pc2.bold(userName)}`);
|
|
@@ -674,8 +715,8 @@ function statusCommand() {
|
|
|
674
715
|
}
|
|
675
716
|
|
|
676
717
|
// src/commands/deploy.ts
|
|
677
|
-
import
|
|
678
|
-
import
|
|
718
|
+
import fs7 from "fs";
|
|
719
|
+
import path5 from "path";
|
|
679
720
|
import * as p3 from "@clack/prompts";
|
|
680
721
|
import pc3 from "picocolors";
|
|
681
722
|
async function deployCommand() {
|
|
@@ -732,15 +773,15 @@ AMAN_MODEL=${isAnthropic ? "claude-sonnet-4-6" : "gpt-4o"}
|
|
|
732
773
|
# TELEGRAM_BOT_TOKEN=
|
|
733
774
|
# DISCORD_BOT_TOKEN=
|
|
734
775
|
`;
|
|
735
|
-
const envPath =
|
|
736
|
-
|
|
776
|
+
const envPath = path5.join(cwd, ".env");
|
|
777
|
+
fs7.writeFileSync(envPath, envContent, "utf-8");
|
|
737
778
|
p3.log.success(`Created ${pc3.bold(".env")} with API key`);
|
|
738
779
|
const pkgDir = findPackageDir();
|
|
739
780
|
copyDeployFile(pkgDir, cwd, "Dockerfile");
|
|
740
781
|
copyDeployFile(pkgDir, cwd, "docker-entrypoint.sh");
|
|
741
782
|
copyDeployFile(pkgDir, cwd, "docker-compose.yml");
|
|
742
783
|
try {
|
|
743
|
-
|
|
784
|
+
fs7.chmodSync(path5.join(cwd, "docker-entrypoint.sh"), 493);
|
|
744
785
|
} catch {
|
|
745
786
|
}
|
|
746
787
|
p3.log.success(`Created ${pc3.bold("Dockerfile")} + ${pc3.bold("docker-compose.yml")}`);
|
|
@@ -776,20 +817,20 @@ AMAN_MODEL=${model}
|
|
|
776
817
|
# TELEGRAM_BOT_TOKEN=
|
|
777
818
|
# DISCORD_BOT_TOKEN=
|
|
778
819
|
`;
|
|
779
|
-
const envPath =
|
|
780
|
-
|
|
820
|
+
const envPath = path5.join(cwd, ".env");
|
|
821
|
+
fs7.writeFileSync(envPath, envContent, "utf-8");
|
|
781
822
|
p3.log.success(`Created ${pc3.bold(".env")} with Ollama config`);
|
|
782
823
|
const pkgDir = findPackageDir();
|
|
783
824
|
copyDeployFile(pkgDir, cwd, "Dockerfile");
|
|
784
825
|
copyDeployFile(pkgDir, cwd, "docker-entrypoint.sh");
|
|
785
826
|
copyDeployFile(pkgDir, cwd, "docker-compose.ollama.yml");
|
|
786
|
-
const src =
|
|
787
|
-
const dest =
|
|
788
|
-
if (
|
|
789
|
-
|
|
827
|
+
const src = path5.join(cwd, "docker-compose.ollama.yml");
|
|
828
|
+
const dest = path5.join(cwd, "docker-compose.yml");
|
|
829
|
+
if (fs7.existsSync(src) && !fs7.existsSync(dest)) {
|
|
830
|
+
fs7.renameSync(src, dest);
|
|
790
831
|
}
|
|
791
832
|
try {
|
|
792
|
-
|
|
833
|
+
fs7.chmodSync(path5.join(cwd, "docker-entrypoint.sh"), 493);
|
|
793
834
|
} catch {
|
|
794
835
|
}
|
|
795
836
|
p3.log.success(`Created ${pc3.bold("Dockerfile")} + ${pc3.bold("docker-compose.yml")} (with Ollama)`);
|
|
@@ -866,18 +907,18 @@ ${pc3.bold("Raspberry Pi:")}
|
|
|
866
907
|
function findPackageDir() {
|
|
867
908
|
let dir = new URL(".", import.meta.url).pathname;
|
|
868
909
|
for (let i = 0; i < 5; i++) {
|
|
869
|
-
if (
|
|
870
|
-
dir =
|
|
910
|
+
if (fs7.existsSync(path5.join(dir, "Dockerfile"))) return dir;
|
|
911
|
+
dir = path5.dirname(dir);
|
|
871
912
|
}
|
|
872
|
-
const globalDir =
|
|
873
|
-
if (
|
|
913
|
+
const globalDir = path5.join(process.env.npm_config_prefix || "/usr/local", "lib/node_modules/@aman_asmuei/aman");
|
|
914
|
+
if (fs7.existsSync(path5.join(globalDir, "Dockerfile"))) return globalDir;
|
|
874
915
|
return process.cwd();
|
|
875
916
|
}
|
|
876
917
|
function copyDeployFile(pkgDir, destDir, filename) {
|
|
877
|
-
const src =
|
|
878
|
-
const dest =
|
|
879
|
-
if (
|
|
880
|
-
|
|
918
|
+
const src = path5.join(pkgDir, filename);
|
|
919
|
+
const dest = path5.join(destDir, filename);
|
|
920
|
+
if (fs7.existsSync(src)) {
|
|
921
|
+
fs7.copyFileSync(src, dest);
|
|
881
922
|
}
|
|
882
923
|
}
|
|
883
924
|
|
|
@@ -1007,14 +1048,14 @@ async function showcaseCommand(nameArg, opts = {}) {
|
|
|
1007
1048
|
// src/commands/here.ts
|
|
1008
1049
|
import * as p5 from "@clack/prompts";
|
|
1009
1050
|
import pc5 from "picocolors";
|
|
1010
|
-
import
|
|
1011
|
-
import
|
|
1051
|
+
import fs8 from "fs";
|
|
1052
|
+
import path6 from "path";
|
|
1012
1053
|
async function hereCommand(opts = {}) {
|
|
1013
1054
|
const cwd = process.cwd();
|
|
1014
|
-
const acoreDir =
|
|
1015
|
-
const contextPath =
|
|
1016
|
-
const configPath =
|
|
1017
|
-
if (
|
|
1055
|
+
const acoreDir = path6.join(cwd, ".acore");
|
|
1056
|
+
const contextPath = path6.join(acoreDir, "context.md");
|
|
1057
|
+
const configPath = path6.join(acoreDir, "config.json");
|
|
1058
|
+
if (fs8.existsSync(contextPath) && !opts.force) {
|
|
1018
1059
|
p5.intro(pc5.bold("aman here") + " \u2014 project context card");
|
|
1019
1060
|
const overwrite = await p5.confirm({
|
|
1020
1061
|
message: `${pc5.dim(".acore/context.md")} already exists. Overwrite?`,
|
|
@@ -1028,7 +1069,7 @@ async function hereCommand(opts = {}) {
|
|
|
1028
1069
|
const stack = detectStack() || "unknown";
|
|
1029
1070
|
const platform = detectPlatform();
|
|
1030
1071
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1031
|
-
|
|
1072
|
+
fs8.mkdirSync(acoreDir, { recursive: true });
|
|
1032
1073
|
const contextContent = `## Work
|
|
1033
1074
|
- Stack: ${stack}
|
|
1034
1075
|
- Domain:
|
|
@@ -1044,21 +1085,21 @@ async function hereCommand(opts = {}) {
|
|
|
1044
1085
|
## Project Patterns
|
|
1045
1086
|
- [observations specific to this project \u2014 built over time]
|
|
1046
1087
|
`;
|
|
1047
|
-
|
|
1048
|
-
if (
|
|
1088
|
+
fs8.writeFileSync(contextPath, contextContent, "utf-8");
|
|
1089
|
+
if (fs8.existsSync(configPath)) {
|
|
1049
1090
|
try {
|
|
1050
|
-
const existing = JSON.parse(
|
|
1091
|
+
const existing = JSON.parse(fs8.readFileSync(configPath, "utf-8"));
|
|
1051
1092
|
if (typeof existing.platform !== "string" || existing.platform === "") {
|
|
1052
1093
|
existing.platform = platform || "other";
|
|
1053
|
-
|
|
1094
|
+
fs8.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
1054
1095
|
}
|
|
1055
1096
|
} catch {
|
|
1056
1097
|
const fresh = { platform: platform || "other" };
|
|
1057
|
-
|
|
1098
|
+
fs8.writeFileSync(configPath, JSON.stringify(fresh, null, 2) + "\n", "utf-8");
|
|
1058
1099
|
}
|
|
1059
1100
|
} else {
|
|
1060
1101
|
const fresh = { platform: platform || "other" };
|
|
1061
|
-
|
|
1102
|
+
fs8.writeFileSync(configPath, JSON.stringify(fresh, null, 2) + "\n", "utf-8");
|
|
1062
1103
|
}
|
|
1063
1104
|
if (opts.force) {
|
|
1064
1105
|
return;
|
|
@@ -1071,8 +1112,12 @@ async function hereCommand(opts = {}) {
|
|
|
1071
1112
|
}
|
|
1072
1113
|
|
|
1073
1114
|
// src/index.ts
|
|
1115
|
+
import pc6 from "picocolors";
|
|
1074
1116
|
var program = new Command();
|
|
1075
|
-
program.name("aman").description("Your complete AI companion \u2014 identity, memory, and tools in one command").version("0.5.
|
|
1117
|
+
program.name("aman").description("Your complete AI companion \u2014 identity, memory, and tools in one command").version("0.5.4").action(() => {
|
|
1118
|
+
for (const msg of runAutoHeal()) {
|
|
1119
|
+
console.log(` ${pc6.green("\u2714")} ${msg}`);
|
|
1120
|
+
}
|
|
1076
1121
|
const ecosystem = detectEcosystem();
|
|
1077
1122
|
if (ecosystem.acore.installed) {
|
|
1078
1123
|
statusCommand();
|
|
@@ -1081,7 +1126,12 @@ program.name("aman").description("Your complete AI companion \u2014 identity, me
|
|
|
1081
1126
|
}
|
|
1082
1127
|
});
|
|
1083
1128
|
program.command("setup").description("Set up your AI companion (identity + memory + tools)").action(() => setupCommand());
|
|
1084
|
-
program.command("status").description("View your full ecosystem status").action(() =>
|
|
1129
|
+
program.command("status").description("View your full ecosystem status").action(() => {
|
|
1130
|
+
for (const msg of runAutoHeal()) {
|
|
1131
|
+
console.log(` ${pc6.green("\u2714")} ${msg}`);
|
|
1132
|
+
}
|
|
1133
|
+
statusCommand();
|
|
1134
|
+
});
|
|
1085
1135
|
program.command("deploy").description("Deploy your AI companion (Docker, systemd, or cloud)").action(() => deployCommand());
|
|
1086
1136
|
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(
|
|
1087
1137
|
(name, opts) => showcaseCommand(name, opts)
|