@aman_asmuei/aman-agent 0.34.0 → 0.40.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/dist/index.js CHANGED
@@ -659,24 +659,247 @@ var init_delegate_remote = __esm({
659
659
  }
660
660
  });
661
661
 
662
+ // src/orchestrator/types.ts
663
+ import { z } from "zod";
664
+ var ModelTierEnum, TaskNodeSchema, PhaseGateTypeEnum, PhaseGateSchema, TaskDAGSchema, OrchestrationStatusEnum, TaskStatusEnum, OrchestrationConfigSchema;
665
+ var init_types = __esm({
666
+ "src/orchestrator/types.ts"() {
667
+ "use strict";
668
+ ModelTierEnum = z.enum(["fast", "standard", "advanced"]);
669
+ TaskNodeSchema = z.object({
670
+ id: z.string().min(1),
671
+ name: z.string().min(1),
672
+ description: z.string().optional(),
673
+ profile: z.string().min(1),
674
+ tier: ModelTierEnum,
675
+ dependencies: z.array(z.string()).default([]),
676
+ phase: z.string().optional(),
677
+ context: z.string().optional(),
678
+ metadata: z.record(z.unknown()).optional()
679
+ });
680
+ PhaseGateTypeEnum = z.enum([
681
+ "approval",
682
+ "ci_pass",
683
+ "test_pass",
684
+ "custom"
685
+ ]);
686
+ PhaseGateSchema = z.object({
687
+ id: z.string().min(1),
688
+ name: z.string().min(1),
689
+ type: PhaseGateTypeEnum,
690
+ afterNodes: z.array(z.string()),
691
+ beforeNodes: z.array(z.string()),
692
+ metadata: z.record(z.unknown()).optional()
693
+ });
694
+ TaskDAGSchema = z.object({
695
+ id: z.string().min(1),
696
+ name: z.string().min(1),
697
+ goal: z.string().min(1),
698
+ nodes: z.array(TaskNodeSchema).min(1),
699
+ gates: z.array(PhaseGateSchema).default([]),
700
+ metadata: z.record(z.unknown()).optional()
701
+ });
702
+ OrchestrationStatusEnum = z.enum([
703
+ "pending",
704
+ "running",
705
+ "awaiting_approval",
706
+ "approved",
707
+ "paused",
708
+ "completed",
709
+ "failed",
710
+ "cancelled"
711
+ ]);
712
+ TaskStatusEnum = z.enum([
713
+ "pending",
714
+ "ready",
715
+ "running",
716
+ "completed",
717
+ "failed",
718
+ "skipped",
719
+ "blocked"
720
+ ]);
721
+ OrchestrationConfigSchema = z.object({
722
+ maxParallelTasks: z.number().int().positive().default(4),
723
+ defaultTier: ModelTierEnum.default("standard"),
724
+ requireApprovalForPhaseTransition: z.boolean().default(true),
725
+ taskTimeoutMs: z.number().int().positive().default(3e5),
726
+ orchestrationTimeoutMs: z.number().int().positive().default(36e5)
727
+ });
728
+ }
729
+ });
730
+
731
+ // src/orchestrator/dag.ts
732
+ function validateDAG(dag) {
733
+ const nodeIds = /* @__PURE__ */ new Set();
734
+ for (const node of dag.nodes) {
735
+ if (nodeIds.has(node.id)) {
736
+ throw new DAGValidationError(`Duplicate node id: "${node.id}"`);
737
+ }
738
+ nodeIds.add(node.id);
739
+ }
740
+ for (const node of dag.nodes) {
741
+ for (const dep of node.dependencies) {
742
+ if (!nodeIds.has(dep)) {
743
+ throw new DAGValidationError(
744
+ `Node "${node.id}" depends on nonexistent node "${dep}"`
745
+ );
746
+ }
747
+ }
748
+ }
749
+ for (const gate of dag.gates) {
750
+ for (const id of gate.afterNodes) {
751
+ if (!nodeIds.has(id)) {
752
+ throw new DAGValidationError(
753
+ `Gate "${gate.id}" references nonexistent afterNode "${id}"`
754
+ );
755
+ }
756
+ }
757
+ for (const id of gate.beforeNodes) {
758
+ if (!nodeIds.has(id)) {
759
+ throw new DAGValidationError(
760
+ `Gate "${gate.id}" references nonexistent beforeNode "${id}"`
761
+ );
762
+ }
763
+ }
764
+ }
765
+ const inDegree = /* @__PURE__ */ new Map();
766
+ const adj = /* @__PURE__ */ new Map();
767
+ for (const node of dag.nodes) {
768
+ inDegree.set(node.id, 0);
769
+ adj.set(node.id, []);
770
+ }
771
+ for (const node of dag.nodes) {
772
+ for (const dep of node.dependencies) {
773
+ adj.get(dep).push(node.id);
774
+ inDegree.set(node.id, inDegree.get(node.id) + 1);
775
+ }
776
+ }
777
+ const queue = [];
778
+ for (const [id, deg] of inDegree) {
779
+ if (deg === 0) queue.push(id);
780
+ }
781
+ let visited = 0;
782
+ while (queue.length > 0) {
783
+ const current = queue.shift();
784
+ visited++;
785
+ for (const neighbor of adj.get(current)) {
786
+ const newDeg = inDegree.get(neighbor) - 1;
787
+ inDegree.set(neighbor, newDeg);
788
+ if (newDeg === 0) queue.push(neighbor);
789
+ }
790
+ }
791
+ if (visited !== dag.nodes.length) {
792
+ throw new DAGValidationError(
793
+ "DAG contains a cycle \u2014 not all nodes were reachable via topological ordering"
794
+ );
795
+ }
796
+ }
797
+ var DAGValidationError;
798
+ var init_dag = __esm({
799
+ "src/orchestrator/dag.ts"() {
800
+ "use strict";
801
+ DAGValidationError = class extends Error {
802
+ constructor(message) {
803
+ super(message);
804
+ this.name = "DAGValidationError";
805
+ }
806
+ };
807
+ }
808
+ });
809
+
810
+ // src/orchestrator/decompose.ts
811
+ function parseDecompositionResponse(response) {
812
+ let jsonStr;
813
+ const codeBlockMatch = response.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);
814
+ if (codeBlockMatch) {
815
+ jsonStr = codeBlockMatch[1];
816
+ } else {
817
+ jsonStr = response;
818
+ }
819
+ let raw;
820
+ try {
821
+ raw = JSON.parse(jsonStr);
822
+ } catch {
823
+ throw new Error(
824
+ `Failed to parse decomposition response as JSON: ${jsonStr.slice(0, 200)}`
825
+ );
826
+ }
827
+ const parsed = TaskDAGSchema.parse(raw);
828
+ validateDAG(parsed);
829
+ return parsed;
830
+ }
831
+ async function decomposeRequirement(requirement, client) {
832
+ const response = await client.chat(
833
+ DECOMPOSITION_SYSTEM_PROMPT,
834
+ [{ role: "user", content: requirement }],
835
+ () => {
836
+ }
837
+ // stream chunks are unused; we read the final message
838
+ );
839
+ const text3 = typeof response.message.content === "string" ? response.message.content : response.message.content.filter((b) => b.type === "text").map((b) => b.text).join("");
840
+ return parseDecompositionResponse(text3);
841
+ }
842
+ var DECOMPOSITION_SYSTEM_PROMPT;
843
+ var init_decompose = __esm({
844
+ "src/orchestrator/decompose.ts"() {
845
+ "use strict";
846
+ init_types();
847
+ init_dag();
848
+ DECOMPOSITION_SYSTEM_PROMPT = `You are a software project decomposer. Given a requirement, break it into a task DAG for parallel agent execution.
849
+
850
+ Return ONLY valid JSON matching this schema:
851
+ {
852
+ "id": "orch-<short-id>",
853
+ "name": "<short name>",
854
+ "goal": "<one-line goal>",
855
+ "nodes": [
856
+ {
857
+ "id": "<unique-id>",
858
+ "name": "<task name>",
859
+ "description": "<what to do>",
860
+ "profile": "<architect|coder|tester|reviewer|security>",
861
+ "tier": "<fast|standard|advanced>",
862
+ "dependencies": ["<prerequisite task ids>"]
863
+ }
864
+ ],
865
+ "gates": [
866
+ {
867
+ "id": "<gate-id>",
868
+ "name": "<gate description>",
869
+ "type": "approval",
870
+ "afterNodes": ["<completed before gate>"],
871
+ "beforeNodes": ["<blocked until gate resolves>"]
872
+ }
873
+ ]
874
+ }
875
+
876
+ Rules:
877
+ - architect profile = tier advanced
878
+ - coder/tester/reviewer = tier standard
879
+ - Maximize parallelism
880
+ - Add approval gate before destructive actions
881
+ - 3-12 tasks for most features`;
882
+ }
883
+ });
884
+
662
885
  // src/dev/stack-detector.ts
663
886
  var stack_detector_exports = {};
664
887
  __export(stack_detector_exports, {
665
888
  scanStack: () => scanStack
666
889
  });
667
- import fs24 from "fs";
668
- import path24 from "path";
890
+ import fs17 from "fs";
891
+ import path17 from "path";
669
892
  function scanStack(projectPath) {
670
893
  const languages = [];
671
894
  const frameworks = [];
672
895
  const databases = [];
673
896
  const infra = [];
674
897
  let isMonorepo = false;
675
- let projectName = path24.basename(projectPath);
676
- const goModPath = path24.join(projectPath, "go.mod");
677
- if (fs24.existsSync(goModPath)) {
898
+ let projectName = path17.basename(projectPath);
899
+ const goModPath = path17.join(projectPath, "go.mod");
900
+ if (fs17.existsSync(goModPath)) {
678
901
  languages.push("go");
679
- const content = fs24.readFileSync(goModPath, "utf-8");
902
+ const content = fs17.readFileSync(goModPath, "utf-8");
680
903
  const moduleMatch = content.match(/^module\s+(.+)$/m);
681
904
  if (moduleMatch) {
682
905
  const parts = moduleMatch[1].trim().split("/");
@@ -687,11 +910,11 @@ function scanStack(projectPath) {
687
910
  if (content.includes("go-chi/chi")) frameworks.push("chi");
688
911
  if (content.includes("labstack/echo")) frameworks.push("echo");
689
912
  }
690
- const pkgPath = path24.join(projectPath, "package.json");
691
- const hasTsConfig = fs24.existsSync(path24.join(projectPath, "tsconfig.json"));
692
- if (fs24.existsSync(pkgPath)) {
913
+ const pkgPath = path17.join(projectPath, "package.json");
914
+ const hasTsConfig = fs17.existsSync(path17.join(projectPath, "tsconfig.json"));
915
+ if (fs17.existsSync(pkgPath)) {
693
916
  try {
694
- const pkg = JSON.parse(fs24.readFileSync(pkgPath, "utf-8"));
917
+ const pkg = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
695
918
  if (pkg.name) projectName = pkg.name;
696
919
  if (hasTsConfig) {
697
920
  languages.push("typescript");
@@ -709,35 +932,35 @@ function scanStack(projectPath) {
709
932
  } else if (hasTsConfig) {
710
933
  languages.push("typescript");
711
934
  }
712
- const cargoPath = path24.join(projectPath, "Cargo.toml");
713
- if (fs24.existsSync(cargoPath)) {
935
+ const cargoPath = path17.join(projectPath, "Cargo.toml");
936
+ if (fs17.existsSync(cargoPath)) {
714
937
  languages.push("rust");
715
- const content = fs24.readFileSync(cargoPath, "utf-8");
938
+ const content = fs17.readFileSync(cargoPath, "utf-8");
716
939
  if (content.includes("[workspace]")) isMonorepo = true;
717
940
  const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
718
941
  if (nameMatch && !isMonorepo) projectName = nameMatch[1];
719
942
  }
720
- const pyprojectPath = path24.join(projectPath, "pyproject.toml");
721
- if (fs24.existsSync(pyprojectPath)) {
943
+ const pyprojectPath = path17.join(projectPath, "pyproject.toml");
944
+ if (fs17.existsSync(pyprojectPath)) {
722
945
  languages.push("python");
723
- const content = fs24.readFileSync(pyprojectPath, "utf-8");
946
+ const content = fs17.readFileSync(pyprojectPath, "utf-8");
724
947
  if (content.includes("django")) frameworks.push("django");
725
948
  if (content.includes("fastapi")) frameworks.push("fastapi");
726
949
  if (content.includes("flask")) frameworks.push("flask");
727
950
  }
728
- if (fs24.existsSync(path24.join(projectPath, "pubspec.yaml"))) {
951
+ if (fs17.existsSync(path17.join(projectPath, "pubspec.yaml"))) {
729
952
  languages.push("dart");
730
953
  frameworks.push("flutter");
731
954
  }
732
- if (fs24.existsSync(path24.join(projectPath, "Dockerfile"))) {
955
+ if (fs17.existsSync(path17.join(projectPath, "Dockerfile"))) {
733
956
  infra.push("docker");
734
957
  }
735
958
  const composeNames = ["docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"];
736
959
  for (const name of composeNames) {
737
- const composePath = path24.join(projectPath, name);
738
- if (fs24.existsSync(composePath)) {
960
+ const composePath = path17.join(projectPath, name);
961
+ if (fs17.existsSync(composePath)) {
739
962
  if (!infra.includes("docker")) infra.push("docker");
740
- const content = fs24.readFileSync(composePath, "utf-8");
963
+ const content = fs17.readFileSync(composePath, "utf-8");
741
964
  for (const [pattern, dbName] of Object.entries(DB_IMAGE_MAP)) {
742
965
  if (content.includes(pattern) && !databases.includes(dbName)) {
743
966
  databases.push(dbName);
@@ -746,16 +969,16 @@ function scanStack(projectPath) {
746
969
  break;
747
970
  }
748
971
  }
749
- if (fs24.existsSync(path24.join(projectPath, ".github", "workflows"))) {
972
+ if (fs17.existsSync(path17.join(projectPath, ".github", "workflows"))) {
750
973
  infra.push("github-actions");
751
974
  }
752
975
  for (const dir of ["k3s", "k8s", "deploy"]) {
753
- if (fs24.existsSync(path24.join(projectPath, dir))) {
976
+ if (fs17.existsSync(path17.join(projectPath, dir))) {
754
977
  infra.push("kubernetes");
755
978
  break;
756
979
  }
757
980
  }
758
- if (fs24.existsSync(path24.join(projectPath, "Makefile"))) {
981
+ if (fs17.existsSync(path17.join(projectPath, "Makefile"))) {
759
982
  infra.push("make");
760
983
  }
761
984
  return {
@@ -795,10 +1018,475 @@ var init_stack_detector = __esm({
795
1018
  }
796
1019
  });
797
1020
 
1021
+ // src/github/types.ts
1022
+ import { z as z2 } from "zod";
1023
+ var GitHubIssueSchema, GitHubPRSchema, WorkflowRunSchema, CheckStatusSchema, GhResultSchema;
1024
+ var init_types2 = __esm({
1025
+ "src/github/types.ts"() {
1026
+ "use strict";
1027
+ GitHubIssueSchema = z2.object({
1028
+ number: z2.number().int().positive(),
1029
+ title: z2.string().min(1),
1030
+ body: z2.string().nullable().default(null),
1031
+ state: z2.enum(["OPEN", "CLOSED"]),
1032
+ url: z2.string().url(),
1033
+ labels: z2.array(z2.object({ name: z2.string() })).default([]),
1034
+ assignees: z2.array(z2.object({ login: z2.string() })).default([]),
1035
+ author: z2.object({ login: z2.string() }).optional(),
1036
+ createdAt: z2.string(),
1037
+ updatedAt: z2.string()
1038
+ });
1039
+ GitHubPRSchema = z2.object({
1040
+ number: z2.number().int().positive(),
1041
+ title: z2.string().min(1),
1042
+ body: z2.string().nullable().default(null),
1043
+ state: z2.enum(["OPEN", "CLOSED", "MERGED"]),
1044
+ url: z2.string().url(),
1045
+ headRefName: z2.string(),
1046
+ baseRefName: z2.string(),
1047
+ isDraft: z2.boolean().default(false),
1048
+ mergeable: z2.enum(["MERGEABLE", "CONFLICTING", "UNKNOWN"]).default("UNKNOWN"),
1049
+ labels: z2.array(z2.object({ name: z2.string() })).default([]),
1050
+ author: z2.object({ login: z2.string() }).optional(),
1051
+ createdAt: z2.string(),
1052
+ updatedAt: z2.string()
1053
+ });
1054
+ WorkflowRunSchema = z2.object({
1055
+ databaseId: z2.number().int().positive(),
1056
+ name: z2.string(),
1057
+ workflowName: z2.string().optional(),
1058
+ status: z2.enum([
1059
+ "queued",
1060
+ "in_progress",
1061
+ "completed",
1062
+ "waiting",
1063
+ "requested",
1064
+ "pending"
1065
+ ]),
1066
+ conclusion: z2.enum([
1067
+ "success",
1068
+ "failure",
1069
+ "cancelled",
1070
+ "skipped",
1071
+ "timed_out",
1072
+ "action_required",
1073
+ "neutral",
1074
+ "stale",
1075
+ ""
1076
+ ]).nullable().default(null),
1077
+ url: z2.string().url(),
1078
+ headBranch: z2.string(),
1079
+ event: z2.string(),
1080
+ createdAt: z2.string(),
1081
+ updatedAt: z2.string()
1082
+ });
1083
+ CheckStatusSchema = z2.object({
1084
+ passed: z2.boolean(),
1085
+ pending: z2.boolean(),
1086
+ failing: z2.boolean(),
1087
+ total: z2.number().int().nonnegative(),
1088
+ details: z2.array(
1089
+ z2.object({
1090
+ name: z2.string(),
1091
+ status: z2.string(),
1092
+ conclusion: z2.string().nullable()
1093
+ })
1094
+ ).default([])
1095
+ });
1096
+ GhResultSchema = z2.object({
1097
+ success: z2.boolean(),
1098
+ stdout: z2.string(),
1099
+ stderr: z2.string(),
1100
+ exitCode: z2.number().int()
1101
+ });
1102
+ }
1103
+ });
1104
+
1105
+ // src/github/cli.ts
1106
+ var cli_exports = {};
1107
+ __export(cli_exports, {
1108
+ GhError: () => GhError,
1109
+ gh: () => gh,
1110
+ ghAvailable: () => ghAvailable,
1111
+ ghCurrentRepo: () => ghCurrentRepo,
1112
+ ghJson: () => ghJson
1113
+ });
1114
+ import { execFile } from "child_process";
1115
+ import { promisify } from "util";
1116
+ async function gh(args, options) {
1117
+ const ghBin = options?.env?.GH_PATH ?? process.env.GH_PATH ?? "gh";
1118
+ const timeout = options?.timeoutMs ?? 3e4;
1119
+ const execOpts = {
1120
+ timeout,
1121
+ ...options?.cwd ? { cwd: options.cwd } : {},
1122
+ ...options?.env ? { env: { ...process.env, ...options.env } } : {}
1123
+ };
1124
+ try {
1125
+ const { stdout, stderr } = await execFileAsync(ghBin, args, execOpts);
1126
+ return { success: true, stdout, stderr, exitCode: 0 };
1127
+ } catch (err) {
1128
+ const e = err;
1129
+ const exitCode = typeof e.code === "number" ? e.code : 1;
1130
+ return {
1131
+ success: false,
1132
+ stdout: e.stdout ?? "",
1133
+ stderr: e.stderr ?? "",
1134
+ exitCode
1135
+ };
1136
+ }
1137
+ }
1138
+ async function ghJson(args, options) {
1139
+ const result = await gh(args, options);
1140
+ if (!result.success) {
1141
+ throw new GhError(
1142
+ `gh command failed: ${result.stderr}`,
1143
+ result.exitCode,
1144
+ result.stderr
1145
+ );
1146
+ }
1147
+ try {
1148
+ return JSON.parse(result.stdout);
1149
+ } catch {
1150
+ throw new GhError(
1151
+ `Failed to parse JSON from gh output: ${result.stdout.slice(0, 200)}`,
1152
+ 0,
1153
+ result.stderr
1154
+ );
1155
+ }
1156
+ }
1157
+ async function ghAvailable() {
1158
+ const result = await gh(["auth", "status"]);
1159
+ return result.success;
1160
+ }
1161
+ async function ghCurrentRepo() {
1162
+ try {
1163
+ const data = await ghJson(
1164
+ ["repo", "view", "--json", "owner,name"]
1165
+ );
1166
+ return { owner: data.owner.login, name: data.name };
1167
+ } catch {
1168
+ return null;
1169
+ }
1170
+ }
1171
+ var execFileAsync, GhError;
1172
+ var init_cli = __esm({
1173
+ "src/github/cli.ts"() {
1174
+ "use strict";
1175
+ execFileAsync = promisify(execFile);
1176
+ GhError = class extends Error {
1177
+ constructor(message, exitCode, stderr) {
1178
+ super(message);
1179
+ this.exitCode = exitCode;
1180
+ this.stderr = stderr;
1181
+ this.name = "GhError";
1182
+ }
1183
+ exitCode;
1184
+ stderr;
1185
+ };
1186
+ }
1187
+ });
1188
+
1189
+ // src/github/issue-planner.ts
1190
+ async function fetchIssue(issueNumber, options) {
1191
+ const args = [
1192
+ "issue",
1193
+ "view",
1194
+ String(issueNumber),
1195
+ "--json",
1196
+ ISSUE_JSON_FIELDS
1197
+ ];
1198
+ if (options?.repo) {
1199
+ args.push("--repo", options.repo);
1200
+ }
1201
+ const raw = await ghJson(args, { cwd: options?.cwd });
1202
+ return GitHubIssueSchema.parse(raw);
1203
+ }
1204
+ function formatIssueAsRequirement(issue) {
1205
+ const parts = [`# ${issue.title}`];
1206
+ if (issue.body) {
1207
+ parts.push("", issue.body);
1208
+ }
1209
+ const extras = [];
1210
+ if (issue.labels.length > 0) {
1211
+ extras.push(`Labels: ${issue.labels.map((l) => l.name).join(", ")}`);
1212
+ }
1213
+ if (issue.assignees.length > 0) {
1214
+ extras.push(
1215
+ `Assignees: ${issue.assignees.map((a) => a.login).join(", ")}`
1216
+ );
1217
+ }
1218
+ if (extras.length > 0) {
1219
+ parts.push("", ...extras);
1220
+ }
1221
+ return parts.join("\n");
1222
+ }
1223
+ async function planFromIssue(issueNumber, client, options) {
1224
+ const issue = await fetchIssue(issueNumber, options);
1225
+ const requirement = formatIssueAsRequirement(issue);
1226
+ const dag = await decomposeRequirement(requirement, client);
1227
+ return { issue, dag };
1228
+ }
1229
+ var ISSUE_JSON_FIELDS;
1230
+ var init_issue_planner = __esm({
1231
+ "src/github/issue-planner.ts"() {
1232
+ "use strict";
1233
+ init_cli();
1234
+ init_types2();
1235
+ init_decompose();
1236
+ ISSUE_JSON_FIELDS = "number,title,body,state,url,labels,assignees,author,createdAt,updatedAt";
1237
+ }
1238
+ });
1239
+
1240
+ // src/github/pr-manager.ts
1241
+ import { execFile as execFile2 } from "child_process";
1242
+ import { promisify as promisify2 } from "util";
1243
+ async function createPR(options) {
1244
+ const args = [
1245
+ "pr",
1246
+ "create",
1247
+ "--title",
1248
+ options.title,
1249
+ "--body",
1250
+ options.body,
1251
+ "--head",
1252
+ options.head
1253
+ ];
1254
+ if (options.base) {
1255
+ args.push("--base", options.base);
1256
+ }
1257
+ if (options.draft) {
1258
+ args.push("--draft");
1259
+ }
1260
+ if (options.labels) {
1261
+ for (const label of options.labels) {
1262
+ args.push("--label", label);
1263
+ }
1264
+ }
1265
+ if (options.repo) {
1266
+ args.push("--repo", options.repo);
1267
+ }
1268
+ const ghOpts = options.cwd ? { cwd: options.cwd } : void 0;
1269
+ const result = await gh(args, ghOpts);
1270
+ if (!result.success) {
1271
+ const { GhError: GhError2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
1272
+ throw new GhError2(
1273
+ `Failed to create PR: ${result.stderr}`,
1274
+ result.exitCode,
1275
+ result.stderr
1276
+ );
1277
+ }
1278
+ const url = result.stdout.trim();
1279
+ const prNumber = parseInt(url.split("/").pop(), 10);
1280
+ return getPR(prNumber, { repo: options.repo, cwd: options.cwd });
1281
+ }
1282
+ async function listPRs(options) {
1283
+ const args = ["pr", "list", "--json", PR_JSON_FIELDS];
1284
+ if (options?.state) {
1285
+ args.push("--state", options.state);
1286
+ }
1287
+ if (options?.head) {
1288
+ args.push("--head", options.head);
1289
+ }
1290
+ if (options?.limit != null) {
1291
+ args.push("--limit", String(options.limit));
1292
+ }
1293
+ if (options?.repo) {
1294
+ args.push("--repo", options.repo);
1295
+ }
1296
+ const ghOpts = options?.cwd ? { cwd: options.cwd } : void 0;
1297
+ const raw = await ghJson(args, ghOpts);
1298
+ return raw.map((item) => GitHubPRSchema.parse(item));
1299
+ }
1300
+ async function getPR(prNumber, options) {
1301
+ const args = [
1302
+ "pr",
1303
+ "view",
1304
+ String(prNumber),
1305
+ "--json",
1306
+ PR_JSON_FIELDS
1307
+ ];
1308
+ if (options?.repo) {
1309
+ args.push("--repo", options.repo);
1310
+ }
1311
+ const ghOpts = options?.cwd ? { cwd: options.cwd } : void 0;
1312
+ const raw = await ghJson(args, ghOpts);
1313
+ return GitHubPRSchema.parse(raw);
1314
+ }
1315
+ async function commentOnPR(prNumber, body, options) {
1316
+ const args = ["pr", "comment", String(prNumber), "--body", body];
1317
+ if (options?.repo) {
1318
+ args.push("--repo", options.repo);
1319
+ }
1320
+ const ghOpts = options?.cwd ? { cwd: options.cwd } : void 0;
1321
+ const result = await gh(args, ghOpts);
1322
+ if (!result.success) {
1323
+ const { GhError: GhError2 } = await Promise.resolve().then(() => (init_cli(), cli_exports));
1324
+ throw new GhError2(
1325
+ `Failed to comment on PR #${prNumber}: ${result.stderr}`,
1326
+ result.exitCode,
1327
+ result.stderr
1328
+ );
1329
+ }
1330
+ }
1331
+ async function createBranch(branchName, options) {
1332
+ const args = ["checkout", "-b", branchName];
1333
+ if (options?.baseBranch) {
1334
+ args.push(options.baseBranch);
1335
+ }
1336
+ const execOpts = {};
1337
+ if (options?.cwd) {
1338
+ execOpts.cwd = options.cwd;
1339
+ }
1340
+ await execFileAsync2("git", args, execOpts);
1341
+ }
1342
+ var execFileAsync2, PR_JSON_FIELDS;
1343
+ var init_pr_manager = __esm({
1344
+ "src/github/pr-manager.ts"() {
1345
+ "use strict";
1346
+ init_cli();
1347
+ init_types2();
1348
+ execFileAsync2 = promisify2(execFile2);
1349
+ PR_JSON_FIELDS = "number,title,body,state,url,headRefName,baseRefName,isDraft,mergeable,labels,author,createdAt,updatedAt";
1350
+ }
1351
+ });
1352
+
1353
+ // src/github/ci-gate.ts
1354
+ async function getLatestRun(branch, options) {
1355
+ const args = [
1356
+ "run",
1357
+ "list",
1358
+ "--branch",
1359
+ branch,
1360
+ "--limit",
1361
+ "1",
1362
+ "--json",
1363
+ RUN_JSON_FIELDS
1364
+ ];
1365
+ if (options?.workflow) {
1366
+ args.push("--workflow", options.workflow);
1367
+ }
1368
+ if (options?.repo) {
1369
+ args.push("--repo", options.repo);
1370
+ }
1371
+ const runs = await ghJson(args, { cwd: options?.cwd });
1372
+ if (!runs.length) return null;
1373
+ return WorkflowRunSchema.parse(runs[0]);
1374
+ }
1375
+ async function getCheckStatus(ref, options) {
1376
+ const isPRNumber = /^\d+$/.test(ref);
1377
+ if (isPRNumber) {
1378
+ const args = ["pr", "checks", ref, "--json", "name,status,conclusion"];
1379
+ if (options?.repo) args.push("--repo", options.repo);
1380
+ const checks = await ghJson(args, { cwd: options?.cwd });
1381
+ const details = checks.map((c) => ({
1382
+ name: c.name,
1383
+ status: c.status,
1384
+ conclusion: c.conclusion
1385
+ }));
1386
+ const passed = details.every(
1387
+ (d) => d.status === "completed" && d.conclusion === "success"
1388
+ );
1389
+ const pending = details.some((d) => d.status !== "completed");
1390
+ const failing = details.some(
1391
+ (d) => d.status === "completed" && d.conclusion !== "success" && d.conclusion !== "skipped" && d.conclusion !== "neutral"
1392
+ );
1393
+ return CheckStatusSchema.parse({
1394
+ passed: passed && details.length > 0,
1395
+ pending,
1396
+ failing,
1397
+ total: details.length,
1398
+ details
1399
+ });
1400
+ }
1401
+ const run = await getLatestRun(ref, options);
1402
+ if (!run) {
1403
+ return CheckStatusSchema.parse({
1404
+ passed: false,
1405
+ pending: false,
1406
+ failing: false,
1407
+ total: 0,
1408
+ details: []
1409
+ });
1410
+ }
1411
+ return CheckStatusSchema.parse({
1412
+ passed: run.status === "completed" && run.conclusion === "success",
1413
+ pending: run.status !== "completed",
1414
+ failing: run.status === "completed" && run.conclusion !== "success" && run.conclusion !== "skipped" && run.conclusion !== "neutral",
1415
+ total: 1,
1416
+ details: [
1417
+ { name: run.name, status: run.status, conclusion: run.conclusion }
1418
+ ]
1419
+ });
1420
+ }
1421
+ async function waitForCI(branch, options) {
1422
+ const pollInterval = options?.pollIntervalMs ?? 1e4;
1423
+ const timeout = options?.timeoutMs ?? 6e5;
1424
+ const deadline = Date.now() + timeout;
1425
+ while (Date.now() < deadline) {
1426
+ const run = await getLatestRun(branch, options);
1427
+ if (run && run.status === "completed") {
1428
+ return { passed: run.conclusion === "success", run };
1429
+ }
1430
+ if (Date.now() + pollInterval >= deadline) break;
1431
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
1432
+ }
1433
+ return { passed: false, run: null };
1434
+ }
1435
+ async function isCIPassing(branch, options) {
1436
+ const run = await getLatestRun(branch, options);
1437
+ return run !== null && run.status === "completed" && run.conclusion === "success";
1438
+ }
1439
+ var RUN_JSON_FIELDS;
1440
+ var init_ci_gate = __esm({
1441
+ "src/github/ci-gate.ts"() {
1442
+ "use strict";
1443
+ init_cli();
1444
+ init_types2();
1445
+ RUN_JSON_FIELDS = "databaseId,name,workflowName,status,conclusion,url,headBranch,event,createdAt,updatedAt";
1446
+ }
1447
+ });
1448
+
1449
+ // src/github/index.ts
1450
+ var github_exports = {};
1451
+ __export(github_exports, {
1452
+ CheckStatusSchema: () => CheckStatusSchema,
1453
+ GhError: () => GhError,
1454
+ GhResultSchema: () => GhResultSchema,
1455
+ GitHubIssueSchema: () => GitHubIssueSchema,
1456
+ GitHubPRSchema: () => GitHubPRSchema,
1457
+ WorkflowRunSchema: () => WorkflowRunSchema,
1458
+ commentOnPR: () => commentOnPR,
1459
+ createBranch: () => createBranch,
1460
+ createPR: () => createPR,
1461
+ fetchIssue: () => fetchIssue,
1462
+ formatIssueAsRequirement: () => formatIssueAsRequirement,
1463
+ getCheckStatus: () => getCheckStatus,
1464
+ getLatestRun: () => getLatestRun,
1465
+ getPR: () => getPR,
1466
+ gh: () => gh,
1467
+ ghAvailable: () => ghAvailable,
1468
+ ghCurrentRepo: () => ghCurrentRepo,
1469
+ ghJson: () => ghJson,
1470
+ isCIPassing: () => isCIPassing,
1471
+ listPRs: () => listPRs,
1472
+ planFromIssue: () => planFromIssue,
1473
+ waitForCI: () => waitForCI
1474
+ });
1475
+ var init_github = __esm({
1476
+ "src/github/index.ts"() {
1477
+ "use strict";
1478
+ init_types2();
1479
+ init_cli();
1480
+ init_issue_planner();
1481
+ init_pr_manager();
1482
+ init_ci_gate();
1483
+ }
1484
+ });
1485
+
798
1486
  // src/dev/context-builder.ts
799
- import fs25 from "fs";
800
- import path25 from "path";
801
- import os22 from "os";
1487
+ import fs26 from "fs";
1488
+ import path26 from "path";
1489
+ import os23 from "os";
802
1490
  import { createDatabase as createDatabase2, recall as recall2 } from "@aman_asmuei/amem-core";
803
1491
  import {
804
1492
  getIdentity as acoreGetIdentity2
@@ -826,9 +1514,9 @@ async function buildContext2(stack, opts) {
826
1514
  const rules = [];
827
1515
  let memoriesUsed = 0;
828
1516
  try {
829
- const amemDir = process.env.AMEM_DIR ?? path25.join(os22.homedir(), ".amem");
830
- const dbPath = process.env.AMEM_DB ?? path25.join(amemDir, "memory.db");
831
- if (!process.env.AMEM_DB && !fs25.existsSync(dbPath)) throw new Error("no db");
1517
+ const amemDir = process.env.AMEM_DIR ?? path26.join(os23.homedir(), ".amem");
1518
+ const dbPath = process.env.AMEM_DB ?? path26.join(amemDir, "memory.db");
1519
+ if (!process.env.AMEM_DB && !fs26.existsSync(dbPath)) throw new Error("no db");
832
1520
  const db2 = createDatabase2(dbPath);
833
1521
  const queryParts = [stack.projectName, ...stack.languages, ...stack.frameworks];
834
1522
  const query = queryParts.join(" ");
@@ -984,8 +1672,8 @@ __export(claude_md_writer_exports, {
984
1672
  writeClaudeMd: () => writeClaudeMd,
985
1673
  writeContextFile: () => writeContextFile
986
1674
  });
987
- import fs26 from "fs";
988
- import path26 from "path";
1675
+ import fs27 from "fs";
1676
+ import path27 from "path";
989
1677
  function formatStack(stack) {
990
1678
  const parts = [];
991
1679
  const goFrameworks = ["fiber", "gin", "chi", "echo"];
@@ -1069,11 +1757,11 @@ function parseMarker(content) {
1069
1757
  }
1070
1758
  function checkStaleness(projectPath, editor = "claude") {
1071
1759
  const target = EDITOR_TARGETS[editor];
1072
- const filePath = path26.join(projectPath, target.contextFile);
1073
- if (!fs26.existsSync(filePath)) {
1760
+ const filePath = path27.join(projectPath, target.contextFile);
1761
+ if (!fs27.existsSync(filePath)) {
1074
1762
  return { status: "missing" };
1075
1763
  }
1076
- const content = fs26.readFileSync(filePath, "utf-8");
1764
+ const content = fs27.readFileSync(filePath, "utf-8");
1077
1765
  const marker = parseMarker(content);
1078
1766
  if (!marker) {
1079
1767
  return { status: "no-marker" };
@@ -1082,22 +1770,22 @@ function checkStaleness(projectPath, editor = "claude") {
1082
1770
  }
1083
1771
  function writeContextFile(ctx, projectPath, editor = "claude") {
1084
1772
  const target = EDITOR_TARGETS[editor];
1085
- const filePath = path26.join(projectPath, target.contextFile);
1773
+ const filePath = path27.join(projectPath, target.contextFile);
1086
1774
  let backedUp = false;
1087
- const parentDir = path26.dirname(filePath);
1088
- if (!fs26.existsSync(parentDir)) {
1089
- fs26.mkdirSync(parentDir, { recursive: true });
1775
+ const parentDir = path27.dirname(filePath);
1776
+ if (!fs27.existsSync(parentDir)) {
1777
+ fs27.mkdirSync(parentDir, { recursive: true });
1090
1778
  }
1091
- if (fs26.existsSync(filePath)) {
1092
- const content = fs26.readFileSync(filePath, "utf-8");
1779
+ if (fs27.existsSync(filePath)) {
1780
+ const content = fs27.readFileSync(filePath, "utf-8");
1093
1781
  const marker = parseMarker(content);
1094
1782
  if (!marker) {
1095
- fs26.copyFileSync(filePath, `${filePath}.bak`);
1783
+ fs27.copyFileSync(filePath, `${filePath}.bak`);
1096
1784
  backedUp = true;
1097
1785
  }
1098
1786
  }
1099
1787
  const md = renderToString(ctx);
1100
- fs26.writeFileSync(filePath, md, "utf-8");
1788
+ fs27.writeFileSync(filePath, md, "utf-8");
1101
1789
  return { written: true, backedUp, path: filePath };
1102
1790
  }
1103
1791
  var EDITOR_TARGETS, writeClaudeMd;
@@ -1140,23 +1828,23 @@ var dev_command_exports = {};
1140
1828
  __export(dev_command_exports, {
1141
1829
  runDev: () => runDev
1142
1830
  });
1143
- import fs27 from "fs";
1144
- import path27 from "path";
1831
+ import fs28 from "fs";
1832
+ import path28 from "path";
1145
1833
  function ensureGitignore(projectPath, editor) {
1146
- const gitignorePath = path27.join(projectPath, ".gitignore");
1147
- if (!fs27.existsSync(gitignorePath)) return;
1148
- const content = fs27.readFileSync(gitignorePath, "utf-8");
1834
+ const gitignorePath = path28.join(projectPath, ".gitignore");
1835
+ if (!fs28.existsSync(gitignorePath)) return;
1836
+ const content = fs28.readFileSync(gitignorePath, "utf-8");
1149
1837
  const target = EDITOR_TARGETS[editor];
1150
1838
  if (content.includes(target.gitignoreEntry)) return;
1151
- fs27.appendFileSync(gitignorePath, `
1839
+ fs28.appendFileSync(gitignorePath, `
1152
1840
  # Generated by aman-agent dev
1153
1841
  ${target.gitignoreEntry}
1154
1842
  `);
1155
1843
  }
1156
1844
  async function runDev(projectPath, flags = {}, precomputedStack) {
1157
- const resolved = path27.resolve(projectPath);
1845
+ const resolved = path28.resolve(projectPath);
1158
1846
  const editor = flags.editor ?? "claude";
1159
- if (!fs27.existsSync(resolved)) {
1847
+ if (!fs28.existsSync(resolved)) {
1160
1848
  return { success: false, generated: false, error: `Directory not found: ${resolved}` };
1161
1849
  }
1162
1850
  const stack = precomputedStack ?? scanStack(resolved);
@@ -1164,8 +1852,8 @@ async function runDev(projectPath, flags = {}, precomputedStack) {
1164
1852
  const ctx2 = await buildContext2(stack, { smart: flags.smart });
1165
1853
  const newContent = renderToString(ctx2);
1166
1854
  const target = EDITOR_TARGETS[editor];
1167
- const existingPath = path27.join(resolved, target.contextFile);
1168
- const existing = fs27.existsSync(existingPath) ? fs27.readFileSync(existingPath, "utf-8") : "";
1855
+ const existingPath = path28.join(resolved, target.contextFile);
1856
+ const existing = fs28.existsSync(existingPath) ? fs28.readFileSync(existingPath, "utf-8") : "";
1169
1857
  return {
1170
1858
  success: true,
1171
1859
  generated: false,
@@ -2577,18 +3265,18 @@ var McpManager = class {
2577
3265
 
2578
3266
  // src/agent.ts
2579
3267
  import * as readline from "readline";
2580
- import fs23 from "fs";
2581
- import path23 from "path";
2582
- import os21 from "os";
3268
+ import fs25 from "fs";
3269
+ import path25 from "path";
3270
+ import os22 from "os";
2583
3271
  import pc7 from "picocolors";
2584
3272
  import { marked } from "marked";
2585
3273
  import { markedTerminal } from "marked-terminal";
2586
3274
  import logUpdate from "log-update";
2587
3275
 
2588
3276
  // src/commands.ts
2589
- import fs20 from "fs";
2590
- import path20 from "path";
2591
- import os18 from "os";
3277
+ import fs22 from "fs";
3278
+ import path22 from "path";
3279
+ import os19 from "os";
2592
3280
  import { execFileSync as execFileSync3 } from "child_process";
2593
3281
  import pc6 from "picocolors";
2594
3282
 
@@ -2940,6 +3628,136 @@ async function memorySync(action, opts = {}) {
2940
3628
  import fs8 from "fs";
2941
3629
  import path8 from "path";
2942
3630
  import os7 from "os";
3631
+
3632
+ // src/profiles/orchestrator-profiles.ts
3633
+ var architectProfile = {
3634
+ name: "architect",
3635
+ label: "System Architect",
3636
+ description: "Designs system architecture, decomposes features into modules, plans file structure and interfaces",
3637
+ core: `# System Architect
3638
+
3639
+ You are a system architect. Your job is to:
3640
+ - Analyze requirements and design the overall system structure
3641
+ - Define module boundaries, interfaces, and data flows
3642
+ - Plan file structure and naming conventions
3643
+ - Identify dependencies and integration points
3644
+ - Choose appropriate patterns and abstractions
3645
+ - Consider scalability, maintainability, and testability
3646
+
3647
+ ## Output Format
3648
+ Produce a clear, structured design document with:
3649
+ 1. **Architecture overview** \u2014 high-level components and their relationships
3650
+ 2. **File structure** \u2014 exact paths for new/modified files
3651
+ 3. **Interfaces** \u2014 key types, function signatures, and data contracts
3652
+ 4. **Dependencies** \u2014 what depends on what, build order
3653
+ 5. **Risks** \u2014 potential issues and mitigation strategies
3654
+
3655
+ Be precise with file paths and interface definitions. The implementation agents will follow your design exactly.`,
3656
+ rules: `- Never write implementation code \u2014 design only
3657
+ - Always specify exact file paths
3658
+ - Consider existing codebase patterns before proposing new ones
3659
+ - Flag breaking changes explicitly`
3660
+ };
3661
+ var securityProfile = {
3662
+ name: "security",
3663
+ label: "Security Analyst",
3664
+ description: "Reviews code for security vulnerabilities, runs SAST checks, audits dependencies",
3665
+ core: `# Security Analyst
3666
+
3667
+ You are a security analyst. Your job is to:
3668
+ - Review code for OWASP Top 10 vulnerabilities
3669
+ - Check for injection flaws (SQL, command, XSS)
3670
+ - Verify authentication and authorization patterns
3671
+ - Audit dependency versions for known CVEs
3672
+ - Check for secrets/credentials in code
3673
+ - Validate input sanitization and output encoding
3674
+ - Review error handling for information leakage
3675
+
3676
+ ## Output Format
3677
+ Produce a security report with:
3678
+ 1. **Critical** \u2014 must fix before merge (injection, auth bypass, secrets)
3679
+ 2. **High** \u2014 should fix (missing validation, weak crypto)
3680
+ 3. **Medium** \u2014 recommended (verbose errors, missing rate limiting)
3681
+ 4. **Low** \u2014 informational (best practice suggestions)
3682
+
3683
+ For each finding: file path, line number, description, remediation.`,
3684
+ rules: `- Never approve code with Critical findings
3685
+ - Always check for hardcoded secrets
3686
+ - Flag any use of eval, exec, or shell string concatenation
3687
+ - Verify all user input is validated at system boundaries`
3688
+ };
3689
+ var testerProfile = {
3690
+ name: "tester",
3691
+ label: "Test Engineer",
3692
+ description: "Writes comprehensive tests, identifies edge cases, ensures coverage",
3693
+ core: `# Test Engineer
3694
+
3695
+ You are a test engineer. Your job is to:
3696
+ - Write comprehensive unit and integration tests
3697
+ - Identify edge cases and boundary conditions
3698
+ - Test error paths and failure modes
3699
+ - Verify behavior against specifications
3700
+ - Ensure tests are deterministic and fast
3701
+ - Follow existing test patterns in the codebase
3702
+
3703
+ ## Testing Principles
3704
+ - Test behavior, not implementation details
3705
+ - Each test should verify one specific thing
3706
+ - Use descriptive test names that explain the expected behavior
3707
+ - Arrange-Act-Assert pattern
3708
+ - Mock external dependencies, test internal logic directly
3709
+ - Prefer integration tests for complex interactions
3710
+
3711
+ ## Output Format
3712
+ Produce test files following the project's existing patterns (Vitest, Jest, pytest, etc.).
3713
+ Include: happy path, error cases, edge cases, boundary values.`,
3714
+ rules: `- Never skip error path testing
3715
+ - Always test boundary conditions
3716
+ - Tests must be deterministic (no timing dependencies, no random values)
3717
+ - Follow the project's existing test framework and patterns`
3718
+ };
3719
+ var reviewerProfile = {
3720
+ name: "reviewer",
3721
+ label: "Code Reviewer",
3722
+ description: "Reviews code for quality, correctness, and adherence to patterns",
3723
+ core: `# Code Reviewer
3724
+
3725
+ You are a code reviewer. Your job is to:
3726
+ - Check code correctness and logic errors
3727
+ - Verify adherence to project conventions and patterns
3728
+ - Identify potential performance issues
3729
+ - Assess readability and maintainability
3730
+ - Check error handling completeness
3731
+ - Verify tests adequately cover the changes
3732
+
3733
+ ## Review Approach
3734
+ - Focus on correctness first, style second
3735
+ - Flag bugs and logic errors as Critical
3736
+ - Flag missing error handling as High
3737
+ - Flag style and convention issues as Medium
3738
+ - Acknowledge good patterns and clean code
3739
+
3740
+ ## Output Format
3741
+ Produce a review with confidence-scored findings:
3742
+ - **CRITICAL** (confidence > 0.9) \u2014 definite bugs or security issues
3743
+ - **IMPORTANT** (confidence > 0.7) \u2014 likely problems or missing handling
3744
+ - **SUGGESTION** (confidence > 0.5) \u2014 improvements worth considering
3745
+ - **PRAISE** \u2014 highlight good patterns
3746
+
3747
+ Include file path, line range, and specific explanation for each finding.`,
3748
+ rules: `- Never rubber-stamp \u2014 always provide substantive review
3749
+ - Focus on what matters: correctness > performance > style
3750
+ - Be specific: cite exact lines and explain why something is wrong
3751
+ - Distinguish between "must fix" and "nice to have"`
3752
+ };
3753
+ var ORCHESTRATOR_PROFILES = [
3754
+ architectProfile,
3755
+ securityProfile,
3756
+ testerProfile,
3757
+ reviewerProfile
3758
+ ];
3759
+
3760
+ // src/profile-templates.ts
2943
3761
  var BUILT_IN_PROFILES = [
2944
3762
  {
2945
3763
  name: "coder",
@@ -3027,7 +3845,8 @@ var BUILT_IN_PROFILES = [
3027
3845
  - Present speculation as fact
3028
3846
  - Ignore contradicting evidence
3029
3847
  - Oversimplify complex topics`
3030
- }
3848
+ },
3849
+ ...ORCHESTRATOR_PROFILES
3031
3850
  ];
3032
3851
  function installProfileTemplate(templateName, userName) {
3033
3852
  const template = BUILT_IN_PROFILES.find((t) => t.name === templateName);
@@ -5253,49 +6072,115 @@ async function delegatePipeline(steps, initialInput, client, mcpManager, options
5253
6072
  return results;
5254
6073
  }
5255
6074
 
6075
+ // src/orchestrator/index.ts
6076
+ init_types();
6077
+ init_dag();
6078
+ init_decompose();
6079
+
6080
+ // src/orchestrator/scheduler.ts
6081
+ init_dag();
6082
+
6083
+ // src/orchestrator/checkpoint.ts
6084
+ import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
6085
+ import { join } from "path";
6086
+
6087
+ // src/orchestrator/smart-orchestrate.ts
6088
+ init_decompose();
6089
+
6090
+ // src/orchestrator/templates/index.ts
6091
+ init_dag();
6092
+
6093
+ // src/project/detector.ts
6094
+ var FRONTEND_FRAMEWORKS = /* @__PURE__ */ new Set(["react", "vue", "svelte"]);
6095
+ var FULLSTACK_FRAMEWORKS = /* @__PURE__ */ new Set(["next", "nuxt", "remix"]);
6096
+ var BACKEND_FRAMEWORKS = /* @__PURE__ */ new Set([
6097
+ "express",
6098
+ "fastify",
6099
+ "hono",
6100
+ "nestjs",
6101
+ "fiber",
6102
+ "gin",
6103
+ "chi",
6104
+ "echo",
6105
+ "fastapi",
6106
+ "django",
6107
+ "flask"
6108
+ ]);
6109
+ var WEB_FRAMEWORKS = /* @__PURE__ */ new Set([
6110
+ ...FRONTEND_FRAMEWORKS,
6111
+ ...FULLSTACK_FRAMEWORKS,
6112
+ ...BACKEND_FRAMEWORKS
6113
+ ]);
6114
+
6115
+ // src/orchestrator/smart-orchestrate.ts
6116
+ init_stack_detector();
6117
+
6118
+ // src/profiles/auto-install.ts
6119
+ import fs18 from "fs";
6120
+ import path18 from "path";
6121
+ import os15 from "os";
6122
+
6123
+ // src/orchestrator/index.ts
6124
+ init_dag();
6125
+ function formatDAGForDisplay(dag) {
6126
+ const lines = [];
6127
+ lines.push(`## ${dag.name}`);
6128
+ lines.push(`**Goal:** ${dag.goal}`);
6129
+ lines.push(`**Tasks:** ${dag.nodes.length} | **Gates:** ${dag.gates.length}`);
6130
+ lines.push("");
6131
+ for (const node of dag.nodes) {
6132
+ const depLabel = node.dependencies.length === 0 ? "(root)" : `(after: ${node.dependencies.join(", ")})`;
6133
+ lines.push(`- **${node.name}** \u2192 ${node.profile} [${node.tier}] ${depLabel}`);
6134
+ }
6135
+ for (const gate of dag.gates) {
6136
+ lines.push(`- \u{1F512} **${gate.name}** [${gate.type}]`);
6137
+ }
6138
+ return lines.join("\n");
6139
+ }
6140
+
5256
6141
  // src/commands.ts
5257
6142
  init_registry();
5258
6143
  import { StreamableHTTPClientTransport as StreamableHTTPClientTransport2 } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5259
6144
  import { Client as Client3 } from "@modelcontextprotocol/sdk/client/index.js";
5260
6145
 
5261
6146
  // src/teams.ts
5262
- import fs17 from "fs";
5263
- import path17 from "path";
5264
- import os15 from "os";
6147
+ import fs19 from "fs";
6148
+ import path19 from "path";
6149
+ import os16 from "os";
5265
6150
  import pc4 from "picocolors";
5266
6151
  function getTeamsDir() {
5267
- return path17.join(os15.homedir(), ".acore", "teams");
6152
+ return path19.join(os16.homedir(), ".acore", "teams");
5268
6153
  }
5269
6154
  function ensureTeamsDir() {
5270
6155
  const dir = getTeamsDir();
5271
- if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
6156
+ if (!fs19.existsSync(dir)) fs19.mkdirSync(dir, { recursive: true });
5272
6157
  return dir;
5273
6158
  }
5274
6159
  function teamPath(name) {
5275
6160
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
5276
- return path17.join(ensureTeamsDir(), `${slug}.json`);
6161
+ return path19.join(ensureTeamsDir(), `${slug}.json`);
5277
6162
  }
5278
6163
  function createTeam(team) {
5279
6164
  const fp = teamPath(team.name);
5280
- fs17.writeFileSync(fp, JSON.stringify(team, null, 2), "utf-8");
6165
+ fs19.writeFileSync(fp, JSON.stringify(team, null, 2), "utf-8");
5281
6166
  }
5282
6167
  function loadTeam(name) {
5283
6168
  const fp = teamPath(name);
5284
- if (!fs17.existsSync(fp)) return null;
6169
+ if (!fs19.existsSync(fp)) return null;
5285
6170
  try {
5286
- return JSON.parse(fs17.readFileSync(fp, "utf-8"));
6171
+ return JSON.parse(fs19.readFileSync(fp, "utf-8"));
5287
6172
  } catch {
5288
6173
  return null;
5289
6174
  }
5290
6175
  }
5291
6176
  function listTeams() {
5292
6177
  const dir = getTeamsDir();
5293
- if (!fs17.existsSync(dir)) return [];
6178
+ if (!fs19.existsSync(dir)) return [];
5294
6179
  const teams = [];
5295
- for (const file of fs17.readdirSync(dir)) {
6180
+ for (const file of fs19.readdirSync(dir)) {
5296
6181
  if (!file.endsWith(".json")) continue;
5297
6182
  try {
5298
- const content = fs17.readFileSync(path17.join(dir, file), "utf-8");
6183
+ const content = fs19.readFileSync(path19.join(dir, file), "utf-8");
5299
6184
  teams.push(JSON.parse(content));
5300
6185
  } catch {
5301
6186
  }
@@ -5304,8 +6189,8 @@ function listTeams() {
5304
6189
  }
5305
6190
  function deleteTeam(name) {
5306
6191
  const fp = teamPath(name);
5307
- if (!fs17.existsSync(fp)) return false;
5308
- fs17.unlinkSync(fp);
6192
+ if (!fs19.existsSync(fp)) return false;
6193
+ fs19.unlinkSync(fp);
5309
6194
  return true;
5310
6195
  }
5311
6196
  async function runTeam(team, task, client, mcpManager, tools) {
@@ -5532,23 +6417,23 @@ var BUILT_IN_TEAMS = [
5532
6417
 
5533
6418
  // src/plans.ts
5534
6419
  init_logger();
5535
- import fs18 from "fs";
5536
- import path18 from "path";
5537
- import os16 from "os";
6420
+ import fs20 from "fs";
6421
+ import path20 from "path";
6422
+ import os17 from "os";
5538
6423
  function getPlansDir() {
5539
- const localDir = path18.join(process.cwd(), ".acore", "plans");
5540
- const localAcore = path18.join(process.cwd(), ".acore");
5541
- if (fs18.existsSync(localAcore)) return localDir;
5542
- return path18.join(os16.homedir(), ".acore", "plans");
6424
+ const localDir = path20.join(process.cwd(), ".acore", "plans");
6425
+ const localAcore = path20.join(process.cwd(), ".acore");
6426
+ if (fs20.existsSync(localAcore)) return localDir;
6427
+ return path20.join(os17.homedir(), ".acore", "plans");
5543
6428
  }
5544
6429
  function ensurePlansDir() {
5545
6430
  const dir = getPlansDir();
5546
- if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
6431
+ if (!fs20.existsSync(dir)) fs20.mkdirSync(dir, { recursive: true });
5547
6432
  return dir;
5548
6433
  }
5549
6434
  function planPath(name) {
5550
6435
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
5551
- return path18.join(ensurePlansDir(), `${slug}.md`);
6436
+ return path20.join(ensurePlansDir(), `${slug}.md`);
5552
6437
  }
5553
6438
  function serializePlan(plan) {
5554
6439
  const lines = [];
@@ -5574,7 +6459,7 @@ function parsePlan(content, filePath) {
5574
6459
  const createdMatch = content.match(/\*\*Created:\*\*\s*(.+)/);
5575
6460
  const updatedMatch = content.match(/\*\*Updated:\*\*\s*(.+)/);
5576
6461
  const activeMatch = content.match(/\*\*Active:\*\*\s*(.+)/);
5577
- const name = nameMatch?.[1]?.trim() || path18.basename(filePath, ".md");
6462
+ const name = nameMatch?.[1]?.trim() || path20.basename(filePath, ".md");
5578
6463
  const goal = goalMatch?.[1]?.trim() || "";
5579
6464
  const createdAt = createdMatch?.[1]?.trim() || "";
5580
6465
  const updatedAt = updatedMatch?.[1]?.trim() || "";
@@ -5616,22 +6501,22 @@ function createPlan(name, goal, steps) {
5616
6501
  }
5617
6502
  function savePlan(plan) {
5618
6503
  const fp = planPath(plan.name);
5619
- fs18.writeFileSync(fp, serializePlan(plan), "utf-8");
6504
+ fs20.writeFileSync(fp, serializePlan(plan), "utf-8");
5620
6505
  }
5621
6506
  function loadPlan(name) {
5622
6507
  const fp = planPath(name);
5623
- if (!fs18.existsSync(fp)) return null;
5624
- const content = fs18.readFileSync(fp, "utf-8");
6508
+ if (!fs20.existsSync(fp)) return null;
6509
+ const content = fs20.readFileSync(fp, "utf-8");
5625
6510
  return parsePlan(content, fp);
5626
6511
  }
5627
6512
  function listPlans() {
5628
6513
  const dir = getPlansDir();
5629
- if (!fs18.existsSync(dir)) return [];
6514
+ if (!fs20.existsSync(dir)) return [];
5630
6515
  const plans = [];
5631
- for (const file of fs18.readdirSync(dir)) {
6516
+ for (const file of fs20.readdirSync(dir)) {
5632
6517
  if (!file.endsWith(".md")) continue;
5633
- const fp = path18.join(dir, file);
5634
- const content = fs18.readFileSync(fp, "utf-8");
6518
+ const fp = path20.join(dir, file);
6519
+ const content = fs20.readFileSync(fp, "utf-8");
5635
6520
  const plan = parsePlan(content, fp);
5636
6521
  if (plan) plans.push(plan);
5637
6522
  }
@@ -5726,13 +6611,14 @@ function progressBar(pct) {
5726
6611
  }
5727
6612
 
5728
6613
  // src/commands.ts
6614
+ init_github();
5729
6615
  init_user_model();
5730
6616
 
5731
6617
  // src/background.ts
5732
6618
  init_logger();
5733
- import fs19 from "fs";
5734
- import path19 from "path";
5735
- import os17 from "os";
6619
+ import fs21 from "fs";
6620
+ import path21 from "path";
6621
+ import os18 from "os";
5736
6622
  import pc5 from "picocolors";
5737
6623
  var BACKGROUND_ELIGIBLE = /* @__PURE__ */ new Set([
5738
6624
  "run_tests",
@@ -5771,13 +6657,13 @@ var NEVER_BACKGROUND = /* @__PURE__ */ new Set([
5771
6657
  "file_list",
5772
6658
  "avatar_prompt"
5773
6659
  ]);
5774
- var TASK_LOG_DIR = path19.join(os17.homedir(), ".aman-agent");
5775
- var TASK_LOG_FILE = path19.join(TASK_LOG_DIR, "bg-tasks.json");
6660
+ var TASK_LOG_DIR = path21.join(os18.homedir(), ".aman-agent");
6661
+ var TASK_LOG_FILE = path21.join(TASK_LOG_DIR, "bg-tasks.json");
5776
6662
  var MAX_LOG_ENTRIES = 50;
5777
6663
  function loadTaskLog() {
5778
6664
  try {
5779
- if (!fs19.existsSync(TASK_LOG_FILE)) return [];
5780
- const raw = fs19.readFileSync(TASK_LOG_FILE, "utf-8");
6665
+ if (!fs21.existsSync(TASK_LOG_FILE)) return [];
6666
+ const raw = fs21.readFileSync(TASK_LOG_FILE, "utf-8");
5781
6667
  return JSON.parse(raw);
5782
6668
  } catch {
5783
6669
  return [];
@@ -5785,9 +6671,9 @@ function loadTaskLog() {
5785
6671
  }
5786
6672
  function saveTaskLog(entries) {
5787
6673
  try {
5788
- if (!fs19.existsSync(TASK_LOG_DIR)) fs19.mkdirSync(TASK_LOG_DIR, { recursive: true });
6674
+ if (!fs21.existsSync(TASK_LOG_DIR)) fs21.mkdirSync(TASK_LOG_DIR, { recursive: true });
5789
6675
  const trimmed = entries.slice(-MAX_LOG_ENTRIES);
5790
- fs19.writeFileSync(TASK_LOG_FILE, JSON.stringify(trimmed, null, 2));
6676
+ fs21.writeFileSync(TASK_LOG_FILE, JSON.stringify(trimmed, null, 2));
5791
6677
  } catch (err) {
5792
6678
  log.debug("background", "Failed to save task log", err);
5793
6679
  }
@@ -5936,10 +6822,10 @@ import {
5936
6822
  } from "@aman_asmuei/arules-core";
5937
6823
  var AGENT_SCOPE = process.env.AMAN_AGENT_SCOPE ?? "dev:agent";
5938
6824
  function readEcosystemFile(filePath, label) {
5939
- if (!fs20.existsSync(filePath)) {
6825
+ if (!fs22.existsSync(filePath)) {
5940
6826
  return pc6.dim(`No ${label} file found at ${filePath}`);
5941
6827
  }
5942
- return fs20.readFileSync(filePath, "utf-8").trim();
6828
+ return fs22.readFileSync(filePath, "utf-8").trim();
5943
6829
  }
5944
6830
  function parseCommand(input) {
5945
6831
  const trimmed = input.trim();
@@ -6024,8 +6910,8 @@ async function handleIdentityCommand(action, args, _ctx) {
6024
6910
  }
6025
6911
  if (args.includes("--reset")) {
6026
6912
  const modelPath = defaultModelPath();
6027
- if (fs20.existsSync(modelPath)) {
6028
- fs20.unlinkSync(modelPath);
6913
+ if (fs22.existsSync(modelPath)) {
6914
+ fs22.unlinkSync(modelPath);
6029
6915
  return { handled: true, output: pc6.green("User model reset. Starting fresh.") };
6030
6916
  }
6031
6917
  return { handled: true, output: pc6.dim("No user model to reset.") };
@@ -6269,9 +7155,9 @@ ${result.violations.map((v) => ` - ${v}`).join("\n")}`)
6269
7155
  };
6270
7156
  }
6271
7157
  async function handleWorkflowsCommand(action, args, ctx) {
6272
- const home2 = os18.homedir();
7158
+ const home2 = os19.homedir();
6273
7159
  if (!action) {
6274
- const content = readEcosystemFile(path20.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
7160
+ const content = readEcosystemFile(path22.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
6275
7161
  return { handled: true, output: content };
6276
7162
  }
6277
7163
  if (action === "add") {
@@ -6293,7 +7179,7 @@ async function handleWorkflowsCommand(action, args, ctx) {
6293
7179
  return { handled: true, output: pc6.yellow("Usage: /workflows get <name>") };
6294
7180
  }
6295
7181
  const name = args.join(" ").toLowerCase();
6296
- const raw = readEcosystemFile(path20.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
7182
+ const raw = readEcosystemFile(path22.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
6297
7183
  if (raw.startsWith("No ")) {
6298
7184
  return { handled: true, output: raw };
6299
7185
  }
@@ -6352,12 +7238,12 @@ async function handleToolsCommand(action, args, _ctx) {
6352
7238
  return { handled: true, output: pc6.yellow("Usage: /tools search <query...>") };
6353
7239
  }
6354
7240
  const query = args.join(" ").toLowerCase();
6355
- const home2 = os18.homedir();
6356
- const toolsFile = path20.join(home2, ".akit", "tools.md");
6357
- if (!fs20.existsSync(toolsFile)) {
7241
+ const home2 = os19.homedir();
7242
+ const toolsFile = path22.join(home2, ".akit", "tools.md");
7243
+ if (!fs22.existsSync(toolsFile)) {
6358
7244
  return { handled: true, output: pc6.dim(`No tools file found. Use 'npx @aman_asmuei/akit search ${args.join(" ")}' to search the registry.`) };
6359
7245
  }
6360
- const raw = fs20.readFileSync(toolsFile, "utf-8").trim();
7246
+ const raw = fs22.readFileSync(toolsFile, "utf-8").trim();
6361
7247
  const lines = raw.split("\n");
6362
7248
  const matches = lines.filter((l) => l.toLowerCase().includes(query));
6363
7249
  if (matches.length === 0) {
@@ -6368,9 +7254,9 @@ async function handleToolsCommand(action, args, _ctx) {
6368
7254
  return handleAkitCommand(action, args);
6369
7255
  }
6370
7256
  async function handleSkillsCommand(action, args, ctx) {
6371
- const home2 = os18.homedir();
7257
+ const home2 = os19.homedir();
6372
7258
  if (!action) {
6373
- const content = readEcosystemFile(path20.join(home2, ".askill", "skills.md"), "skills (askill)");
7259
+ const content = readEcosystemFile(path22.join(home2, ".askill", "skills.md"), "skills (askill)");
6374
7260
  return { handled: true, output: content };
6375
7261
  }
6376
7262
  if (action === "install") {
@@ -6392,8 +7278,8 @@ async function handleSkillsCommand(action, args, ctx) {
6392
7278
  return { handled: true, output: pc6.yellow("Usage: /skills search <query...>") };
6393
7279
  }
6394
7280
  const query = args.join(" ").toLowerCase();
6395
- const home3 = os18.homedir();
6396
- const raw = readEcosystemFile(path20.join(home3, ".askill", "skills.md"), "skills (askill)");
7281
+ const home3 = os19.homedir();
7282
+ const raw = readEcosystemFile(path22.join(home3, ".askill", "skills.md"), "skills (askill)");
6397
7283
  if (raw.startsWith("No ")) {
6398
7284
  return { handled: true, output: raw };
6399
7285
  }
@@ -6407,23 +7293,23 @@ async function handleSkillsCommand(action, args, ctx) {
6407
7293
  if (action === "list") {
6408
7294
  const autoOnly = args.includes("--auto");
6409
7295
  if (autoOnly) {
6410
- const logPath = path20.join(os18.homedir(), ".aman-agent", "crystallization-log.json");
7296
+ const logPath = path22.join(os19.homedir(), ".aman-agent", "crystallization-log.json");
6411
7297
  try {
6412
- const content2 = fs20.readFileSync(logPath, "utf-8");
7298
+ const content2 = fs22.readFileSync(logPath, "utf-8");
6413
7299
  const entries = JSON.parse(content2);
6414
7300
  if (entries.length === 0) {
6415
7301
  return { handled: true, output: pc6.dim("No crystallized skills yet.") };
6416
7302
  }
6417
- const suggestionsPath = path20.join(os18.homedir(), ".aman-agent", "crystallization-suggestions.json");
7303
+ const suggestionsPath = path22.join(os19.homedir(), ".aman-agent", "crystallization-suggestions.json");
6418
7304
  let sugCounts = {};
6419
7305
  try {
6420
- const sc = fs20.readFileSync(suggestionsPath, "utf-8");
7306
+ const sc = fs22.readFileSync(suggestionsPath, "utf-8");
6421
7307
  sugCounts = JSON.parse(sc);
6422
7308
  } catch {
6423
7309
  }
6424
7310
  let versionCounts = {};
6425
7311
  try {
6426
- const skillsContent = fs20.readFileSync(path20.join(os18.homedir(), ".askill", "skills.md"), "utf-8");
7312
+ const skillsContent = fs22.readFileSync(path22.join(os19.homedir(), ".askill", "skills.md"), "utf-8");
6427
7313
  const versionRe = /^# (.+)\.v(\d+)$/gm;
6428
7314
  let vMatch;
6429
7315
  while ((vMatch = versionRe.exec(skillsContent)) !== null) {
@@ -6448,13 +7334,13 @@ async function handleSkillsCommand(action, args, ctx) {
6448
7334
  return { handled: true, output: pc6.dim("No crystallized skills yet.") };
6449
7335
  }
6450
7336
  }
6451
- const content = readEcosystemFile(path20.join(home2, ".askill", "skills.md"), "skills (askill)");
7337
+ const content = readEcosystemFile(path22.join(home2, ".askill", "skills.md"), "skills (askill)");
6452
7338
  return { handled: true, output: content };
6453
7339
  }
6454
7340
  if (action === "crystallize") {
6455
- const pmDir = path20.join(os18.homedir(), ".acore", "postmortems");
7341
+ const pmDir = path22.join(os19.homedir(), ".acore", "postmortems");
6456
7342
  try {
6457
- const files = fs20.readdirSync(pmDir);
7343
+ const files = fs22.readdirSync(pmDir);
6458
7344
  const jsonFiles = files.filter((f) => f.endsWith(".json")).sort().reverse();
6459
7345
  if (jsonFiles.length === 0) {
6460
7346
  return {
@@ -6463,7 +7349,7 @@ async function handleSkillsCommand(action, args, ctx) {
6463
7349
  };
6464
7350
  }
6465
7351
  const latest = jsonFiles[0];
6466
- const content = fs20.readFileSync(path20.join(pmDir, latest), "utf-8");
7352
+ const content = fs22.readFileSync(path22.join(pmDir, latest), "utf-8");
6467
7353
  const report = JSON.parse(content);
6468
7354
  if (!report.crystallizationCandidates || report.crystallizationCandidates.length === 0) {
6469
7355
  return {
@@ -6471,8 +7357,8 @@ async function handleSkillsCommand(action, args, ctx) {
6471
7357
  output: pc6.dim(`No crystallization candidates in the most recent post-mortem (${latest}). Run a longer session or wait for the next auto-postmortem.`)
6472
7358
  };
6473
7359
  }
6474
- const skillsMdPath = path20.join(os18.homedir(), ".askill", "skills.md");
6475
- const logPath = path20.join(os18.homedir(), ".aman-agent", "crystallization-log.json");
7360
+ const skillsMdPath = path22.join(os19.homedir(), ".askill", "skills.md");
7361
+ const logPath = path22.join(os19.homedir(), ".aman-agent", "crystallization-log.json");
6476
7362
  const postmortemFilename = latest.replace(/\.json$/, ".md");
6477
7363
  const lines = [
6478
7364
  pc6.bold(`Found ${report.crystallizationCandidates.length} candidate(s) in ${latest}:`)
@@ -6529,9 +7415,9 @@ async function handleSkillsCommand(action, args, ctx) {
6529
7415
  return { handled: true, output: pc6.yellow(`Unknown action: /skills ${action}. Try /skills --help`) };
6530
7416
  }
6531
7417
  async function handleEvalCommand(action, args, ctx) {
6532
- const home2 = os18.homedir();
7418
+ const home2 = os19.homedir();
6533
7419
  if (!action) {
6534
- const content = readEcosystemFile(path20.join(home2, ".aeval", "eval.md"), "evaluation (aeval)");
7420
+ const content = readEcosystemFile(path22.join(home2, ".aeval", "eval.md"), "evaluation (aeval)");
6535
7421
  return { handled: true, output: content };
6536
7422
  }
6537
7423
  if (action === "milestone") {
@@ -6543,10 +7429,10 @@ async function handleEvalCommand(action, args, ctx) {
6543
7429
  return { handled: true, output };
6544
7430
  }
6545
7431
  if (action === "report") {
6546
- const evalFile = path20.join(home2, ".aeval", "eval.md");
7432
+ const evalFile = path22.join(home2, ".aeval", "eval.md");
6547
7433
  const lines = [pc6.bold("\u{1F4CA} Eval Report")];
6548
- if (fs20.existsSync(evalFile)) {
6549
- lines.push("", fs20.readFileSync(evalFile, "utf-8").trim());
7434
+ if (fs22.existsSync(evalFile)) {
7435
+ lines.push("", fs22.readFileSync(evalFile, "utf-8").trim());
6550
7436
  } else {
6551
7437
  lines.push("", pc6.dim("No eval log yet. Use /eval milestone <text> to start."));
6552
7438
  }
@@ -7104,10 +7990,10 @@ function handleSave() {
7104
7990
  }
7105
7991
  function handleReset(action) {
7106
7992
  const dirs = {
7107
- config: path20.join(os18.homedir(), ".aman-agent"),
7108
- memory: path20.join(os18.homedir(), ".amem"),
7109
- identity: path20.join(os18.homedir(), ".acore"),
7110
- rules: path20.join(os18.homedir(), ".arules")
7993
+ config: path22.join(os19.homedir(), ".aman-agent"),
7994
+ memory: path22.join(os19.homedir(), ".amem"),
7995
+ identity: path22.join(os19.homedir(), ".acore"),
7996
+ rules: path22.join(os19.homedir(), ".arules")
7111
7997
  };
7112
7998
  if (action === "help" || !action) {
7113
7999
  return {
@@ -7132,15 +8018,15 @@ function handleReset(action) {
7132
8018
  const removed = [];
7133
8019
  for (const target of targets) {
7134
8020
  const dir = dirs[target];
7135
- if (fs20.existsSync(dir)) {
7136
- fs20.rmSync(dir, { recursive: true, force: true });
8021
+ if (fs22.existsSync(dir)) {
8022
+ fs22.rmSync(dir, { recursive: true, force: true });
7137
8023
  removed.push(target);
7138
8024
  }
7139
8025
  }
7140
8026
  if (targets.includes("config")) {
7141
8027
  const configDir2 = dirs.config;
7142
- fs20.mkdirSync(configDir2, { recursive: true });
7143
- fs20.writeFileSync(path20.join(configDir2, ".reconfig"), "", "utf-8");
8028
+ fs22.mkdirSync(configDir2, { recursive: true });
8029
+ fs22.writeFileSync(path22.join(configDir2, ".reconfig"), "", "utf-8");
7144
8030
  }
7145
8031
  if (removed.length === 0) {
7146
8032
  return { handled: true, output: pc6.dim("Nothing to reset \u2014 directories don't exist.") };
@@ -7157,11 +8043,11 @@ function handleReset(action) {
7157
8043
  function handleUpdate() {
7158
8044
  try {
7159
8045
  const current = execFileSync3("npm", ["view", "@aman_asmuei/aman-agent", "version"], { encoding: "utf-8" }).trim();
7160
- const local = true ? "0.34.0" : "unknown";
8046
+ const local = true ? "0.40.0" : "unknown";
7161
8047
  if (current === local) {
7162
8048
  return { handled: true, output: `${pc6.green("Up to date")} \u2014 v${local}` };
7163
8049
  }
7164
- const isVendored = process.execPath.includes(path20.join(".aman-agent", "node"));
8050
+ const isVendored = process.execPath.includes(path22.join(".aman-agent", "node"));
7165
8051
  const updateCmd = isVendored ? "aman-agent update" : "npm install -g @aman_asmuei/aman-agent@latest";
7166
8052
  return {
7167
8053
  handled: true,
@@ -7197,11 +8083,11 @@ function handleExportCommand() {
7197
8083
  return { handled: true, exportConversation: true };
7198
8084
  }
7199
8085
  function handleDebugCommand() {
7200
- const logPath = path20.join(os18.homedir(), ".aman-agent", "debug.log");
7201
- if (!fs20.existsSync(logPath)) {
8086
+ const logPath = path22.join(os19.homedir(), ".aman-agent", "debug.log");
8087
+ if (!fs22.existsSync(logPath)) {
7202
8088
  return { handled: true, output: pc6.dim("No debug log found.") };
7203
8089
  }
7204
- const content = fs20.readFileSync(logPath, "utf-8");
8090
+ const content = fs22.readFileSync(logPath, "utf-8");
7205
8091
  const lines = content.trim().split("\n");
7206
8092
  const last20 = lines.slice(-20).join("\n");
7207
8093
  return { handled: true, output: pc6.bold("Debug Log (last 20 entries):\n") + pc6.dim(last20) };
@@ -7481,7 +8367,7 @@ ${text3}` };
7481
8367
  };
7482
8368
  }
7483
8369
  function handleProfileCommand(action, args) {
7484
- const profilesDir = path20.join(os18.homedir(), ".acore", "profiles");
8370
+ const profilesDir = path22.join(os19.homedir(), ".acore", "profiles");
7485
8371
  if (action === "me") {
7486
8372
  const user = loadUserIdentity();
7487
8373
  if (!user) {
@@ -7549,8 +8435,8 @@ ${pc6.dim("Edit with: /profile edit")}` };
7549
8435
  };
7550
8436
  }
7551
8437
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
7552
- const profileDir = path20.join(profilesDir, slug);
7553
- if (fs20.existsSync(profileDir)) {
8438
+ const profileDir = path22.join(profilesDir, slug);
8439
+ if (fs22.existsSync(profileDir)) {
7554
8440
  return { handled: true, output: pc6.yellow(`Profile already exists: ${slug}`) };
7555
8441
  }
7556
8442
  const builtIn = BUILT_IN_PROFILES.find((t) => t.name === slug);
@@ -7566,16 +8452,16 @@ ${pc6.dim("Edit with: /profile edit")}` };
7566
8452
  Use: aman-agent --profile ${slug}`
7567
8453
  };
7568
8454
  }
7569
- fs20.mkdirSync(profileDir, { recursive: true });
7570
- const globalCore = path20.join(os18.homedir(), ".acore", "core.md");
7571
- if (fs20.existsSync(globalCore)) {
7572
- let content = fs20.readFileSync(globalCore, "utf-8");
8455
+ fs22.mkdirSync(profileDir, { recursive: true });
8456
+ const globalCore = path22.join(os19.homedir(), ".acore", "core.md");
8457
+ if (fs22.existsSync(globalCore)) {
8458
+ let content = fs22.readFileSync(globalCore, "utf-8");
7573
8459
  const aiName = name.charAt(0).toUpperCase() + name.slice(1);
7574
8460
  content = content.replace(/^# .+$/m, `# ${aiName}`);
7575
- fs20.writeFileSync(path20.join(profileDir, "core.md"), content, "utf-8");
8461
+ fs22.writeFileSync(path22.join(profileDir, "core.md"), content, "utf-8");
7576
8462
  } else {
7577
8463
  const aiName = name.charAt(0).toUpperCase() + name.slice(1);
7578
- fs20.writeFileSync(path20.join(profileDir, "core.md"), `# ${aiName}
8464
+ fs22.writeFileSync(path22.join(profileDir, "core.md"), `# ${aiName}
7579
8465
 
7580
8466
  ## Identity
7581
8467
  - Role: ${aiName} is your AI companion
@@ -7588,7 +8474,7 @@ ${pc6.dim("Edit with: /profile edit")}` };
7588
8474
  return {
7589
8475
  handled: true,
7590
8476
  output: pc6.green(`Profile created: ${slug}`) + `
7591
- Edit: ${path20.join(profileDir, "core.md")}
8477
+ Edit: ${path22.join(profileDir, "core.md")}
7592
8478
  Use: aman-agent --profile ${slug}
7593
8479
 
7594
8480
  ${pc6.dim("Add rules.md or skills.md for profile-specific overrides.")}`
@@ -7597,9 +8483,9 @@ ${pc6.dim("Edit with: /profile edit")}` };
7597
8483
  case "show": {
7598
8484
  const name = args[0];
7599
8485
  if (!name) return { handled: true, output: pc6.yellow("Usage: /profile show <name>") };
7600
- const profileDir = path20.join(profilesDir, name);
7601
- if (!fs20.existsSync(profileDir)) return { handled: true, output: pc6.red(`Profile not found: ${name}`) };
7602
- const files = fs20.readdirSync(profileDir).filter((f) => f.endsWith(".md"));
8486
+ const profileDir = path22.join(profilesDir, name);
8487
+ if (!fs22.existsSync(profileDir)) return { handled: true, output: pc6.red(`Profile not found: ${name}`) };
8488
+ const files = fs22.readdirSync(profileDir).filter((f) => f.endsWith(".md"));
7603
8489
  const lines = files.map((f) => ` ${f}`);
7604
8490
  return { handled: true, output: `Profile: ${pc6.bold(name)}
7605
8491
  Files:
@@ -7608,9 +8494,9 @@ ${lines.join("\n")}` };
7608
8494
  case "delete": {
7609
8495
  const name = args[0];
7610
8496
  if (!name) return { handled: true, output: pc6.yellow("Usage: /profile delete <name>") };
7611
- const profileDir = path20.join(profilesDir, name);
7612
- if (!fs20.existsSync(profileDir)) return { handled: true, output: pc6.red(`Profile not found: ${name}`) };
7613
- fs20.rmSync(profileDir, { recursive: true });
8497
+ const profileDir = path22.join(profilesDir, name);
8498
+ if (!fs22.existsSync(profileDir)) return { handled: true, output: pc6.red(`Profile not found: ${name}`) };
8499
+ fs22.rmSync(profileDir, { recursive: true });
7614
8500
  return { handled: true, output: pc6.dim(`Profile deleted: ${name}`) };
7615
8501
  }
7616
8502
  case "help":
@@ -7828,10 +8714,10 @@ function handleShowcaseCommand(action, args) {
7828
8714
  Or place it as a sibling directory to aman-agent.`
7829
8715
  };
7830
8716
  }
7831
- const corePath = path20.join(os18.homedir(), ".acore", "core.md");
8717
+ const corePath = path22.join(os19.homedir(), ".acore", "core.md");
7832
8718
  let currentShowcase = null;
7833
- if (fs20.existsSync(corePath)) {
7834
- const content = fs20.readFileSync(corePath, "utf-8");
8719
+ if (fs22.existsSync(corePath)) {
8720
+ const content = fs22.readFileSync(corePath, "utf-8");
7835
8721
  const nameMatch = content.match(/^# (.+)/m);
7836
8722
  if (nameMatch) {
7837
8723
  const coreName = nameMatch[1].trim().toLowerCase();
@@ -7972,6 +8858,121 @@ async function handleFileCommand(action, args) {
7972
8858
  }
7973
8859
  return { handled: true, output: pc6.yellow(`Unknown /file subcommand: ${action}. Try /file for help.`) };
7974
8860
  }
8861
+ async function handleOrchestrateCommand(action, args, ctx) {
8862
+ if (!action) {
8863
+ return {
8864
+ handled: true,
8865
+ output: `Usage: /orchestrate <requirement>
8866
+
8867
+ Decomposes a requirement into a task DAG and executes it with parallel agents.
8868
+
8869
+ Alias: /orch`
8870
+ };
8871
+ }
8872
+ const requirement = [action, ...args].join(" ");
8873
+ if (!ctx.llmClient) {
8874
+ return { handled: true, output: pc6.red("Orchestration requires an LLM client. Not available.") };
8875
+ }
8876
+ try {
8877
+ const dag = await decomposeRequirement(requirement, ctx.llmClient);
8878
+ const display = formatDAGForDisplay(dag);
8879
+ return { handled: true, output: display };
8880
+ } catch (err) {
8881
+ const msg = err instanceof Error ? err.message : String(err);
8882
+ return { handled: true, output: pc6.red(`Orchestration failed: ${msg}`) };
8883
+ }
8884
+ }
8885
+ async function handleGitHubCommand(action, args, ctx) {
8886
+ if (!action) {
8887
+ const available = await ghAvailable();
8888
+ if (!available) {
8889
+ return { handled: true, output: pc6.red("GitHub CLI (gh) is not available or not authenticated. Run: gh auth login") };
8890
+ }
8891
+ const repo = await ghCurrentRepo();
8892
+ if (!repo) {
8893
+ return { handled: true, output: pc6.yellow("Not inside a GitHub repository.") };
8894
+ }
8895
+ return { handled: true, output: `GitHub repo: ${pc6.bold(`${repo.owner}/${repo.name}`)}` };
8896
+ }
8897
+ switch (action) {
8898
+ case "issues": {
8899
+ const { gh: ghExec } = await Promise.resolve().then(() => (init_github(), github_exports));
8900
+ const repoArgs = args.length > 0 ? ["--repo", args[0]] : [];
8901
+ const result = await ghExec(["issue", "list", "--limit", "10", ...repoArgs]);
8902
+ if (!result.success) {
8903
+ return { handled: true, output: pc6.red(`Failed to list issues: ${result.stderr}`) };
8904
+ }
8905
+ return { handled: true, output: result.stdout.trim() || pc6.dim("No open issues.") };
8906
+ }
8907
+ case "prs": {
8908
+ const repoArgs = args.length > 0 ? { repo: args[0] } : {};
8909
+ try {
8910
+ const prs = await listPRs({ state: "open", limit: 10, ...repoArgs });
8911
+ if (prs.length === 0) {
8912
+ return { handled: true, output: pc6.dim("No open PRs.") };
8913
+ }
8914
+ const lines = prs.map(
8915
+ (pr) => `#${pr.number} ${pr.title} (${pr.headRefName} \u2192 ${pr.baseRefName})${pr.isDraft ? " [draft]" : ""}`
8916
+ );
8917
+ return { handled: true, output: lines.join("\n") };
8918
+ } catch (err) {
8919
+ const msg = err instanceof Error ? err.message : String(err);
8920
+ return { handled: true, output: pc6.red(`Failed to list PRs: ${msg}`) };
8921
+ }
8922
+ }
8923
+ case "plan": {
8924
+ const issueNum = parseInt(args[0], 10);
8925
+ if (!issueNum || isNaN(issueNum)) {
8926
+ return { handled: true, output: pc6.red("Usage: /github plan <issue-number>") };
8927
+ }
8928
+ if (!ctx.llmClient) {
8929
+ return { handled: true, output: pc6.red("Planning requires an LLM client. Not available.") };
8930
+ }
8931
+ try {
8932
+ const issue = await fetchIssue(issueNum);
8933
+ const requirement = formatIssueAsRequirement(issue);
8934
+ const dag = await decomposeRequirement(requirement, ctx.llmClient);
8935
+ const display = formatDAGForDisplay(dag);
8936
+ return { handled: true, output: `${pc6.bold(`Plan for #${issue.number}: ${issue.title}`)}
8937
+
8938
+ ${display}` };
8939
+ } catch (err) {
8940
+ const msg = err instanceof Error ? err.message : String(err);
8941
+ return { handled: true, output: pc6.red(`Failed to plan issue #${issueNum}: ${msg}`) };
8942
+ }
8943
+ }
8944
+ case "ci": {
8945
+ const branch = args[0];
8946
+ if (!branch) {
8947
+ return { handled: true, output: pc6.red("Usage: /github ci <branch>") };
8948
+ }
8949
+ try {
8950
+ const passing = await isCIPassing(branch);
8951
+ return {
8952
+ handled: true,
8953
+ output: passing ? pc6.green(`CI is passing on ${branch}`) : pc6.yellow(`CI is NOT passing on ${branch}`)
8954
+ };
8955
+ } catch (err) {
8956
+ const msg = err instanceof Error ? err.message : String(err);
8957
+ return { handled: true, output: pc6.red(`Failed to check CI: ${msg}`) };
8958
+ }
8959
+ }
8960
+ default:
8961
+ return {
8962
+ handled: true,
8963
+ output: [
8964
+ `Usage: /github [subcommand]`,
8965
+ ``,
8966
+ `Subcommands:`,
8967
+ ` (none) Show current repo info`,
8968
+ ` issues [repo] List open issues`,
8969
+ ` prs [repo] List open PRs`,
8970
+ ` plan <number> Plan from a GitHub issue`,
8971
+ ` ci <branch> Check CI status for a branch`
8972
+ ].join("\n")
8973
+ };
8974
+ }
8975
+ }
7975
8976
  var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
7976
8977
  "quit",
7977
8978
  "exit",
@@ -8005,7 +9006,10 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
8005
9006
  "showcase",
8006
9007
  "file",
8007
9008
  "observe",
8008
- "postmortem"
9009
+ "postmortem",
9010
+ "orchestrate",
9011
+ "orch",
9012
+ "github"
8009
9013
  ]);
8010
9014
  async function handleObserveCommand(action, ctx) {
8011
9015
  if (!ctx.observationSession) {
@@ -8142,6 +9146,11 @@ async function handleCommand(input, ctx) {
8142
9146
  return handleObserveCommand(action, ctx);
8143
9147
  case "postmortem":
8144
9148
  return handlePostmortemCommand(action, args, ctx);
9149
+ case "orchestrate":
9150
+ case "orch":
9151
+ return handleOrchestrateCommand(action, args, ctx);
9152
+ case "github":
9153
+ return handleGitHubCommand(action, args, ctx);
8145
9154
  default:
8146
9155
  return { handled: false };
8147
9156
  }
@@ -8229,10 +9238,10 @@ init_logger();
8229
9238
 
8230
9239
  // src/skill-engine.ts
8231
9240
  init_logger();
8232
- import fs21 from "fs";
9241
+ import fs23 from "fs";
8233
9242
  import fsp from "fs/promises";
8234
- import path21 from "path";
8235
- import os19 from "os";
9243
+ import path23 from "path";
9244
+ import os20 from "os";
8236
9245
  var SKILL_TRIGGERS = {
8237
9246
  testing: ["test", "spec", "coverage", "tdd", "jest", "vitest", "mocha", "assert", "mock", "stub", "fixture", "e2e", "integration test", "unit test"],
8238
9247
  "api-design": ["api", "endpoint", "rest", "graphql", "route", "controller", "middleware", "http", "request", "response", "status code", "pagination"],
@@ -8261,20 +9270,20 @@ async function loadRuntimeTriggers(skillsMdPath) {
8261
9270
  return /* @__PURE__ */ new Map();
8262
9271
  }
8263
9272
  }
8264
- var LEVEL_FILE = path21.join(os19.homedir(), ".aman-agent", "skill-levels.json");
9273
+ var LEVEL_FILE = path23.join(os20.homedir(), ".aman-agent", "skill-levels.json");
8265
9274
  function loadSkillLevels() {
8266
9275
  try {
8267
- if (fs21.existsSync(LEVEL_FILE)) {
8268
- return JSON.parse(fs21.readFileSync(LEVEL_FILE, "utf-8"));
9276
+ if (fs23.existsSync(LEVEL_FILE)) {
9277
+ return JSON.parse(fs23.readFileSync(LEVEL_FILE, "utf-8"));
8269
9278
  }
8270
9279
  } catch {
8271
9280
  }
8272
9281
  return {};
8273
9282
  }
8274
9283
  function saveSkillLevels(levels) {
8275
- const dir = path21.dirname(LEVEL_FILE);
8276
- if (!fs21.existsSync(dir)) fs21.mkdirSync(dir, { recursive: true });
8277
- fs21.writeFileSync(LEVEL_FILE, JSON.stringify(levels, null, 2), "utf-8");
9284
+ const dir = path23.dirname(LEVEL_FILE);
9285
+ if (!fs23.existsSync(dir)) fs23.mkdirSync(dir, { recursive: true });
9286
+ fs23.writeFileSync(LEVEL_FILE, JSON.stringify(levels, null, 2), "utf-8");
8278
9287
  }
8279
9288
  function computeLevel(activations) {
8280
9289
  if (activations >= 50) return { level: 5, label: "Expert" };
@@ -8501,7 +9510,7 @@ async function autoTriggerSkills(userInput, mcpManager) {
8501
9510
  const result = await mcpManager.callTool("skill_list", {});
8502
9511
  const skills = JSON.parse(result);
8503
9512
  const installed = skills.filter((s) => s.installed).map((s) => s.name);
8504
- const skillsMdPath = path21.join(os19.homedir(), ".askill", "skills.md");
9513
+ const skillsMdPath = path23.join(os20.homedir(), ".askill", "skills.md");
8505
9514
  const runtimeTriggers = await loadRuntimeTriggers(skillsMdPath);
8506
9515
  if (installed.length === 0 && runtimeTriggers.size === 0) return "";
8507
9516
  const matched = matchSkillsSemantic(userInput, installed, runtimeTriggers);
@@ -8958,9 +9967,9 @@ function humanizeError(message) {
8958
9967
  }
8959
9968
 
8960
9969
  // src/hints.ts
8961
- import fs22 from "fs";
8962
- import path22 from "path";
8963
- import os20 from "os";
9970
+ import fs24 from "fs";
9971
+ import path24 from "path";
9972
+ import os21 from "os";
8964
9973
  var HINTS = [
8965
9974
  {
8966
9975
  id: "eval",
@@ -8998,11 +10007,11 @@ function getHint(state, ctx) {
8998
10007
  }
8999
10008
  return null;
9000
10009
  }
9001
- var HINTS_FILE = path22.join(os20.homedir(), ".aman-agent", "hints-seen.json");
10010
+ var HINTS_FILE = path24.join(os21.homedir(), ".aman-agent", "hints-seen.json");
9002
10011
  function loadShownHints() {
9003
10012
  try {
9004
- if (fs22.existsSync(HINTS_FILE)) {
9005
- const data = JSON.parse(fs22.readFileSync(HINTS_FILE, "utf-8"));
10013
+ if (fs24.existsSync(HINTS_FILE)) {
10014
+ const data = JSON.parse(fs24.readFileSync(HINTS_FILE, "utf-8"));
9006
10015
  return new Set(Array.isArray(data) ? data : []);
9007
10016
  }
9008
10017
  } catch {
@@ -9011,9 +10020,9 @@ function loadShownHints() {
9011
10020
  }
9012
10021
  function saveShownHints(shown) {
9013
10022
  try {
9014
- const dir = path22.dirname(HINTS_FILE);
9015
- fs22.mkdirSync(dir, { recursive: true });
9016
- fs22.writeFileSync(HINTS_FILE, JSON.stringify([...shown]), "utf-8");
10023
+ const dir = path24.dirname(HINTS_FILE);
10024
+ fs24.mkdirSync(dir, { recursive: true });
10025
+ fs24.writeFileSync(HINTS_FILE, JSON.stringify([...shown]), "utf-8");
9017
10026
  } catch {
9018
10027
  }
9019
10028
  }
@@ -9280,9 +10289,9 @@ ${task.result}`
9280
10289
  }
9281
10290
  if (cmdResult.exportConversation) {
9282
10291
  try {
9283
- const exportDir = path23.join(os21.homedir(), ".aman-agent", "exports");
9284
- fs23.mkdirSync(exportDir, { recursive: true });
9285
- const exportPath = path23.join(exportDir, `${sessionId}.md`);
10292
+ const exportDir = path25.join(os22.homedir(), ".aman-agent", "exports");
10293
+ fs25.mkdirSync(exportDir, { recursive: true });
10294
+ const exportPath = path25.join(exportDir, `${sessionId}.md`);
9286
10295
  const lines = [
9287
10296
  `# Conversation \u2014 ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
9288
10297
  `**Model:** ${model}`,
@@ -9296,7 +10305,7 @@ ${task.result}`
9296
10305
  lines.push(`${label} ${msg.content}`, "");
9297
10306
  }
9298
10307
  }
9299
- fs23.writeFileSync(exportPath, lines.join("\n"), "utf-8");
10308
+ fs25.writeFileSync(exportPath, lines.join("\n"), "utf-8");
9300
10309
  console.log(pc7.green(`Exported to ${exportPath}`));
9301
10310
  } catch {
9302
10311
  console.log(pc7.red("Failed to export conversation."));
@@ -9422,25 +10431,25 @@ ${knowledgeItem.content}
9422
10431
  for (const match of filePathMatches) {
9423
10432
  let filePath = match[1];
9424
10433
  if (filePath.startsWith("~/")) {
9425
- filePath = path23.join(os21.homedir(), filePath.slice(2));
10434
+ filePath = path25.join(os22.homedir(), filePath.slice(2));
9426
10435
  }
9427
- if (!fs23.existsSync(filePath) || !fs23.statSync(filePath).isFile()) continue;
9428
- const ext = path23.extname(filePath).toLowerCase();
10436
+ if (!fs25.existsSync(filePath) || !fs25.statSync(filePath).isFile()) continue;
10437
+ const ext = path25.extname(filePath).toLowerCase();
9429
10438
  if (imageExts.has(ext)) {
9430
10439
  try {
9431
- const stat = fs23.statSync(filePath);
10440
+ const stat = fs25.statSync(filePath);
9432
10441
  if (stat.size > maxImageBytes) {
9433
- process.stdout.write(pc7.yellow(` [skipped: ${path23.basename(filePath)} \u2014 exceeds 20MB limit]
10442
+ process.stdout.write(pc7.yellow(` [skipped: ${path25.basename(filePath)} \u2014 exceeds 20MB limit]
9434
10443
  `));
9435
10444
  continue;
9436
10445
  }
9437
- const data = fs23.readFileSync(filePath).toString("base64");
10446
+ const data = fs25.readFileSync(filePath).toString("base64");
9438
10447
  const mediaType = mimeMap[ext] || "image/png";
9439
10448
  imageBlocks.push({
9440
10449
  type: "image",
9441
10450
  source: { type: "base64", media_type: mediaType, data }
9442
10451
  });
9443
- process.stdout.write(pc7.dim(` [attached image: ${path23.basename(filePath)} (${(stat.size / 1024).toFixed(1)}KB)]
10452
+ process.stdout.write(pc7.dim(` [attached image: ${path25.basename(filePath)} (${(stat.size / 1024).toFixed(1)}KB)]
9444
10453
  `));
9445
10454
  } catch {
9446
10455
  process.stdout.write(pc7.dim(` [could not read image: ${filePath}]
@@ -9448,7 +10457,7 @@ ${knowledgeItem.content}
9448
10457
  }
9449
10458
  } else if (textExts.has(ext) || ext === "") {
9450
10459
  try {
9451
- const content = fs23.readFileSync(filePath, "utf-8");
10460
+ const content = fs25.readFileSync(filePath, "utf-8");
9452
10461
  const maxChars = 5e4;
9453
10462
  const trimmed = content.length > maxChars ? content.slice(0, maxChars) + `
9454
10463
 
@@ -9458,7 +10467,7 @@ ${knowledgeItem.content}
9458
10467
  <file path="${filePath}" size="${content.length} chars">
9459
10468
  ${trimmed}
9460
10469
  </file>`;
9461
- process.stdout.write(pc7.dim(` [attached: ${path23.basename(filePath)} (${(content.length / 1024).toFixed(1)}KB)]
10470
+ process.stdout.write(pc7.dim(` [attached: ${path25.basename(filePath)} (${(content.length / 1024).toFixed(1)}KB)]
9462
10471
  `));
9463
10472
  } catch {
9464
10473
  process.stdout.write(pc7.dim(` [could not read: ${filePath}]
@@ -9467,7 +10476,7 @@ ${trimmed}
9467
10476
  } else if (docExts.has(ext)) {
9468
10477
  if (mcpManager) {
9469
10478
  try {
9470
- process.stdout.write(pc7.dim(` [converting: ${path23.basename(filePath)}...]
10479
+ process.stdout.write(pc7.dim(` [converting: ${path25.basename(filePath)}...]
9471
10480
  `));
9472
10481
  const converted = await mcpManager.callTool("doc_convert", { path: filePath });
9473
10482
  if (converted && !converted.startsWith("Error") && !converted.includes("Could not convert")) {
@@ -9476,7 +10485,7 @@ ${trimmed}
9476
10485
  <file path="${filePath}" format="${ext}">
9477
10486
  ${converted.slice(0, 5e4)}
9478
10487
  </file>`;
9479
- process.stdout.write(pc7.dim(` [attached: ${path23.basename(filePath)} (converted from ${ext})]
10488
+ process.stdout.write(pc7.dim(` [attached: ${path25.basename(filePath)} (converted from ${ext})]
9480
10489
  `));
9481
10490
  } else {
9482
10491
  textContent += `
@@ -9488,7 +10497,7 @@ ${converted}
9488
10497
  `));
9489
10498
  }
9490
10499
  } catch {
9491
- process.stdout.write(pc7.dim(` [could not convert: ${path23.basename(filePath)}]
10500
+ process.stdout.write(pc7.dim(` [could not convert: ${path25.basename(filePath)}]
9492
10501
  `));
9493
10502
  }
9494
10503
  } else {
@@ -9880,7 +10889,7 @@ ${result2.response}` : `[${input2.profile}] failed: ${result2.error}`;
9880
10889
  }
9881
10890
  if (hooksConfig?.featureHints) {
9882
10891
  hintState.turnCount++;
9883
- const hasWorkflows = fs23.existsSync(path23.join(os21.homedir(), ".aflow", "flow.md"));
10892
+ const hasWorkflows = fs25.existsSync(path25.join(os22.homedir(), ".aflow", "flow.md"));
9884
10893
  const memoryCount = memoryTokens > 0 ? Math.floor(memoryTokens / 5) : 0;
9885
10894
  const hint = getHint(hintState, { hasWorkflows, memoryCount });
9886
10895
  if (hint) {
@@ -9926,8 +10935,8 @@ async function saveConversationToMemory(messages, sessionId) {
9926
10935
  }
9927
10936
 
9928
10937
  // src/index.ts
9929
- import fs28 from "fs";
9930
- import path28 from "path";
10938
+ import fs29 from "fs";
10939
+ import path29 from "path";
9931
10940
 
9932
10941
  // src/presets.ts
9933
10942
  var PRESETS = {
@@ -10040,7 +11049,7 @@ import * as p3 from "@clack/prompts";
10040
11049
 
10041
11050
  // src/server/index.ts
10042
11051
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10043
- import { z } from "zod";
11052
+ import { z as z3 } from "zod";
10044
11053
 
10045
11054
  // src/server/transport.ts
10046
11055
  import http from "http";
@@ -10141,7 +11150,7 @@ var Inbox = class {
10141
11150
  // package.json
10142
11151
  var package_default = {
10143
11152
  name: "@aman_asmuei/aman-agent",
10144
- version: "0.34.0",
11153
+ version: "0.40.0",
10145
11154
  description: "Your AI companion, running locally \u2014 powered by the aman ecosystem",
10146
11155
  type: "module",
10147
11156
  engines: {
@@ -10307,8 +11316,8 @@ async function startAgentServer(opts) {
10307
11316
  {
10308
11317
  description: "Delegate a task to this agent. Returns the agent's final response text.",
10309
11318
  inputSchema: {
10310
- task: z.string().describe("The task to run against this agent's profile"),
10311
- context: z.string().optional().describe("Optional extra context")
11319
+ task: z3.string().describe("The task to run against this agent's profile"),
11320
+ context: z3.string().optional().describe("Optional extra context")
10312
11321
  }
10313
11322
  },
10314
11323
  async (input) => {
@@ -10321,9 +11330,9 @@ async function startAgentServer(opts) {
10321
11330
  {
10322
11331
  description: "Deliver a one-way message into this agent's inbox. Drained at next user turn.",
10323
11332
  inputSchema: {
10324
- from: z.string().optional(),
10325
- topic: z.string().optional(),
10326
- body: z.string()
11333
+ from: z3.string().optional(),
11334
+ topic: z3.string().optional(),
11335
+ body: z3.string()
10327
11336
  }
10328
11337
  },
10329
11338
  async (input) => {
@@ -10434,9 +11443,9 @@ async function runServe(opts) {
10434
11443
 
10435
11444
  // src/index.ts
10436
11445
  async function autoDetectConfig() {
10437
- const reconfigMarker = path28.join(homeDir(), ".reconfig");
10438
- if (fs28.existsSync(reconfigMarker)) {
10439
- fs28.unlinkSync(reconfigMarker);
11446
+ const reconfigMarker = path29.join(homeDir(), ".reconfig");
11447
+ if (fs29.existsSync(reconfigMarker)) {
11448
+ fs29.unlinkSync(reconfigMarker);
10440
11449
  return null;
10441
11450
  }
10442
11451
  const anthropicKey = process.env.ANTHROPIC_API_KEY;
@@ -10465,10 +11474,10 @@ async function autoDetectConfig() {
10465
11474
  return null;
10466
11475
  }
10467
11476
  function bootstrapEcosystem() {
10468
- const corePath = path28.join(identityDir(), "core.md");
10469
- if (fs28.existsSync(corePath)) return false;
10470
- fs28.mkdirSync(identityDir(), { recursive: true });
10471
- fs28.writeFileSync(corePath, [
11477
+ const corePath = path29.join(identityDir(), "core.md");
11478
+ if (fs29.existsSync(corePath)) return false;
11479
+ fs29.mkdirSync(identityDir(), { recursive: true });
11480
+ fs29.writeFileSync(corePath, [
10472
11481
  "# Aman",
10473
11482
  "",
10474
11483
  "## Personality",
@@ -10480,10 +11489,10 @@ function bootstrapEcosystem() {
10480
11489
  "## Session",
10481
11490
  "_New companion \u2014 no prior sessions._"
10482
11491
  ].join("\n"), "utf-8");
10483
- const rulesPath = path28.join(rulesDir(), "rules.md");
10484
- if (!fs28.existsSync(rulesPath)) {
10485
- fs28.mkdirSync(rulesDir(), { recursive: true });
10486
- fs28.writeFileSync(rulesPath, [
11492
+ const rulesPath = path29.join(rulesDir(), "rules.md");
11493
+ if (!fs29.existsSync(rulesPath)) {
11494
+ fs29.mkdirSync(rulesDir(), { recursive: true });
11495
+ fs29.writeFileSync(rulesPath, [
10487
11496
  "# Guardrails",
10488
11497
  "",
10489
11498
  "## safety",
@@ -10495,20 +11504,20 @@ function bootstrapEcosystem() {
10495
11504
  "- Respect the user's preferences stored in memory"
10496
11505
  ].join("\n"), "utf-8");
10497
11506
  }
10498
- const flowPath = path28.join(workflowsDir(), "flow.md");
10499
- if (!fs28.existsSync(flowPath)) {
10500
- fs28.mkdirSync(workflowsDir(), { recursive: true });
10501
- fs28.writeFileSync(flowPath, "# Workflows\n\n_No workflows defined yet. Use /workflows add to create one._\n", "utf-8");
11507
+ const flowPath = path29.join(workflowsDir(), "flow.md");
11508
+ if (!fs29.existsSync(flowPath)) {
11509
+ fs29.mkdirSync(workflowsDir(), { recursive: true });
11510
+ fs29.writeFileSync(flowPath, "# Workflows\n\n_No workflows defined yet. Use /workflows add to create one._\n", "utf-8");
10502
11511
  }
10503
- const skillPath = path28.join(skillsDir(), "skills.md");
10504
- if (!fs28.existsSync(skillPath)) {
10505
- fs28.mkdirSync(skillsDir(), { recursive: true });
10506
- fs28.writeFileSync(skillPath, "# Skills\n\n_No skills installed yet. Use /skills install to add domain expertise._\n", "utf-8");
11512
+ const skillPath = path29.join(skillsDir(), "skills.md");
11513
+ if (!fs29.existsSync(skillPath)) {
11514
+ fs29.mkdirSync(skillsDir(), { recursive: true });
11515
+ fs29.writeFileSync(skillPath, "# Skills\n\n_No skills installed yet. Use /skills install to add domain expertise._\n", "utf-8");
10507
11516
  }
10508
11517
  return true;
10509
11518
  }
10510
11519
  var program = new Command();
10511
- program.name("aman-agent").description("Your AI companion, running locally").version("0.34.0").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
11520
+ program.name("aman-agent").description("Your AI companion, running locally").version("0.40.0").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
10512
11521
  p4.intro(pc9.bold("aman agent") + pc9.dim(" \u2014 your AI companion"));
10513
11522
  let config = loadConfig();
10514
11523
  if (!config) {
@@ -10863,18 +11872,18 @@ program.command("init").description("Set up your AI companion with a guided wiza
10863
11872
  });
10864
11873
  if (p4.isCancel(preset)) process.exit(0);
10865
11874
  const result = applyPreset(preset, name || "Aman");
10866
- fs28.mkdirSync(identityDir(), { recursive: true });
10867
- fs28.writeFileSync(path28.join(identityDir(), "core.md"), result.coreMd, "utf-8");
11875
+ fs29.mkdirSync(identityDir(), { recursive: true });
11876
+ fs29.writeFileSync(path29.join(identityDir(), "core.md"), result.coreMd, "utf-8");
10868
11877
  p4.log.success(`Identity created \u2014 ${PRESETS[preset].identity.personality.split(".")[0].toLowerCase()}`);
10869
11878
  if (result.rulesMd) {
10870
- fs28.mkdirSync(rulesDir(), { recursive: true });
10871
- fs28.writeFileSync(path28.join(rulesDir(), "rules.md"), result.rulesMd, "utf-8");
11879
+ fs29.mkdirSync(rulesDir(), { recursive: true });
11880
+ fs29.writeFileSync(path29.join(rulesDir(), "rules.md"), result.rulesMd, "utf-8");
10872
11881
  const ruleCount = (result.rulesMd.match(/^- /gm) || []).length;
10873
11882
  p4.log.success(`${ruleCount} rules set`);
10874
11883
  }
10875
11884
  if (result.flowMd) {
10876
- fs28.mkdirSync(workflowsDir(), { recursive: true });
10877
- fs28.writeFileSync(path28.join(workflowsDir(), "flow.md"), result.flowMd, "utf-8");
11885
+ fs29.mkdirSync(workflowsDir(), { recursive: true });
11886
+ fs29.writeFileSync(path29.join(workflowsDir(), "flow.md"), result.flowMd, "utf-8");
10878
11887
  const wfCount = (result.flowMd.match(/^## /gm) || []).length;
10879
11888
  p4.log.success(`${wfCount} workflow${wfCount > 1 ? "s" : ""} added`);
10880
11889
  }
@@ -10976,16 +11985,16 @@ ${result.diff}`);
10976
11985
  });
10977
11986
  program.command("setup").description("Run the full configuration wizard (provider, identity, presets)").action(async () => {
10978
11987
  p4.intro(pc9.bold("aman agent setup") + pc9.dim(" \u2014 full configuration wizard"));
10979
- const reconfigPath = path28.join(homeDir(), ".reconfig");
10980
- fs28.mkdirSync(homeDir(), { recursive: true });
10981
- fs28.writeFileSync(reconfigPath, "", "utf-8");
11988
+ const reconfigPath = path29.join(homeDir(), ".reconfig");
11989
+ fs29.mkdirSync(homeDir(), { recursive: true });
11990
+ fs29.writeFileSync(reconfigPath, "", "utf-8");
10982
11991
  p4.log.info("Configuration reset. Restart aman-agent to complete setup.");
10983
11992
  });
10984
11993
  program.command("update").description("Update aman-agent to the latest version").action(async () => {
10985
11994
  const { execFileSync: execFileSync4 } = await import("child_process");
10986
- const isVendored = process.execPath.includes(path28.join(".aman-agent", "node"));
11995
+ const isVendored = process.execPath.includes(path29.join(".aman-agent", "node"));
10987
11996
  if (isVendored) {
10988
- const npmPath = path28.join(homeDir(), "node", "bin", "npm");
11997
+ const npmPath = path29.join(homeDir(), "node", "bin", "npm");
10989
11998
  console.log("Updating aman-agent...");
10990
11999
  try {
10991
12000
  execFileSync4(npmPath, ["install", "-g", "@aman_asmuei/aman-agent@latest"], {
@@ -11013,7 +12022,7 @@ program.command("update").description("Update aman-agent to the latest version")
11013
12022
  program.command("uninstall").description("Remove aman-agent and all its data").action(async () => {
11014
12023
  const home2 = homeDir();
11015
12024
  if (!process.stdin.isTTY) {
11016
- fs28.rmSync(home2, { recursive: true, force: true });
12025
+ fs29.rmSync(home2, { recursive: true, force: true });
11017
12026
  console.log("\u2713 Removed " + home2);
11018
12027
  return;
11019
12028
  }
@@ -11024,7 +12033,7 @@ program.command("uninstall").description("Remove aman-agent and all its data").a
11024
12033
  console.log("Cancelled.");
11025
12034
  return;
11026
12035
  }
11027
- fs28.rmSync(home2, { recursive: true, force: true });
12036
+ fs29.rmSync(home2, { recursive: true, force: true });
11028
12037
  console.log("\u2713 Removed " + home2);
11029
12038
  console.log("");
11030
12039
  console.log("To complete uninstall, remove the PATH line from your shell config:");