@aman_asmuei/aman-agent 0.33.8 → 0.34.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/README.md CHANGED
@@ -121,11 +121,13 @@ $ aman-agent dev ~/projects/amantrade
121
121
 
122
122
  | Flag | What it does |
123
123
  |:---|:---|
124
- | `--smart` | Use your configured LLM to synthesize a smarter CLAUDE.md |
125
- | `--yolo` | Launch Claude Code with `--dangerously-skip-permissions` (full autonomous mode) |
126
- | `--no-launch` | Generate CLAUDE.md only, don't start Claude Code |
124
+ | `--smart` | Use your configured LLM to synthesize a smarter context file |
125
+ | `--yolo` | Launch with skip-permissions (Claude Code only) |
126
+ | `--copilot` | Target GitHub Copilot — writes `.github/copilot-instructions.md`, opens VS Code |
127
+ | `--cursor` | Target Cursor — writes `.cursorrules`, opens Cursor |
128
+ | `--no-launch` | Generate context file only, don't launch editor |
127
129
  | `--diff` | Preview what would change without writing |
128
- | `--force` | Regenerate even if CLAUDE.md is fresh |
130
+ | `--force` | Regenerate even if context file is fresh |
129
131
 
130
132
  Works with **multiple projects** simultaneously — each terminal gets its own `aman-agent dev`, all sharing the same memory database. Decisions from one project flow into the next.
131
133
 
@@ -407,14 +409,22 @@ aman-agent dev --smart
407
409
 
408
410
  The LLM merges related corrections into single convention statements and removes redundancy. Falls back to template mode automatically if the LLM call fails.
409
411
 
410
- **Yolo mode** — Full autonomous, no permission prompts:
412
+ **Multi-editor support** — Same memory, any editor:
411
413
 
412
414
  ```bash
413
- aman-agent dev --yolo # skip permissions
414
- aman-agent dev --yolo --smart # skip permissions + LLM-generated CLAUDE.md
415
+ aman-agent dev # Claude Code (default) → CLAUDE.md
416
+ aman-agent dev --copilot # VS Code + Copilot .github/copilot-instructions.md
417
+ aman-agent dev --cursor # Cursor → .cursorrules
415
418
  ```
416
419
 
417
- Launches Claude Code with `--dangerously-skip-permissions`. Use when you trust the project and want zero friction.
420
+ All three use the same pipeline: stack detection amem recall → context assembly. Only the output file and launcher differ.
421
+
422
+ **Yolo mode** — Full autonomous, no permission prompts (Claude Code only):
423
+
424
+ ```bash
425
+ aman-agent dev --yolo # skip permissions
426
+ aman-agent dev --yolo --smart # skip permissions + LLM-generated context
427
+ ```
418
428
 
419
429
  **Multi-project workflow** — Each terminal is independent:
420
430
 
@@ -1367,7 +1377,7 @@ sequenceDiagram
1367
1377
  | Command | Description |
1368
1378
  |:---|:---|
1369
1379
  | `aman-agent` | Start interactive chat session |
1370
- | `aman-agent dev [path]` | Scan project, generate CLAUDE.md, launch Claude Code `[--smart\|--yolo\|--no-launch\|--force\|--diff]` |
1380
+ | `aman-agent dev [path]` | Scan project, generate context, launch editor `[--smart\|--yolo\|--copilot\|--cursor\|--no-launch\|--force\|--diff]` |
1371
1381
  | `aman-agent init` | Set up your AI companion with a guided wizard |
1372
1382
  | `aman-agent serve` | Run as a local MCP server for agent delegation `[--name\|--profile]` |
1373
1383
  | `aman-agent setup` | Full reconfiguration wizard |
package/dist/index.js CHANGED
@@ -975,6 +975,15 @@ var init_context_builder = __esm({
975
975
  });
976
976
 
977
977
  // src/dev/claude-md-writer.ts
978
+ var claude_md_writer_exports = {};
979
+ __export(claude_md_writer_exports, {
980
+ EDITOR_TARGETS: () => EDITOR_TARGETS,
981
+ checkStaleness: () => checkStaleness,
982
+ parseMarker: () => parseMarker,
983
+ renderToString: () => renderToString,
984
+ writeClaudeMd: () => writeClaudeMd,
985
+ writeContextFile: () => writeContextFile
986
+ });
978
987
  import fs26 from "fs";
979
988
  import path26 from "path";
980
989
  function formatStack(stack) {
@@ -1058,36 +1067,71 @@ function parseMarker(content) {
1058
1067
  mode: match[3]
1059
1068
  };
1060
1069
  }
1061
- function checkStaleness(projectPath) {
1062
- const claudeMdPath = path26.join(projectPath, "CLAUDE.md");
1063
- if (!fs26.existsSync(claudeMdPath)) {
1070
+ function checkStaleness(projectPath, editor = "claude") {
1071
+ const target = EDITOR_TARGETS[editor];
1072
+ const filePath = path26.join(projectPath, target.contextFile);
1073
+ if (!fs26.existsSync(filePath)) {
1064
1074
  return { status: "missing" };
1065
1075
  }
1066
- const content = fs26.readFileSync(claudeMdPath, "utf-8");
1076
+ const content = fs26.readFileSync(filePath, "utf-8");
1067
1077
  const marker = parseMarker(content);
1068
1078
  if (!marker) {
1069
1079
  return { status: "no-marker" };
1070
1080
  }
1071
1081
  return { status: "fresh", generatedAt: marker.generatedAt };
1072
1082
  }
1073
- function writeClaudeMd(ctx, projectPath) {
1074
- const claudeMdPath = path26.join(projectPath, "CLAUDE.md");
1083
+ function writeContextFile(ctx, projectPath, editor = "claude") {
1084
+ const target = EDITOR_TARGETS[editor];
1085
+ const filePath = path26.join(projectPath, target.contextFile);
1075
1086
  let backedUp = false;
1076
- if (fs26.existsSync(claudeMdPath)) {
1077
- const content = fs26.readFileSync(claudeMdPath, "utf-8");
1087
+ const parentDir = path26.dirname(filePath);
1088
+ if (!fs26.existsSync(parentDir)) {
1089
+ fs26.mkdirSync(parentDir, { recursive: true });
1090
+ }
1091
+ if (fs26.existsSync(filePath)) {
1092
+ const content = fs26.readFileSync(filePath, "utf-8");
1078
1093
  const marker = parseMarker(content);
1079
1094
  if (!marker) {
1080
- fs26.copyFileSync(claudeMdPath, `${claudeMdPath}.bak`);
1095
+ fs26.copyFileSync(filePath, `${filePath}.bak`);
1081
1096
  backedUp = true;
1082
1097
  }
1083
1098
  }
1084
1099
  const md = renderToString(ctx);
1085
- fs26.writeFileSync(claudeMdPath, md, "utf-8");
1086
- return { written: true, backedUp, path: claudeMdPath };
1100
+ fs26.writeFileSync(filePath, md, "utf-8");
1101
+ return { written: true, backedUp, path: filePath };
1087
1102
  }
1103
+ var EDITOR_TARGETS, writeClaudeMd;
1088
1104
  var init_claude_md_writer = __esm({
1089
1105
  "src/dev/claude-md-writer.ts"() {
1090
1106
  "use strict";
1107
+ EDITOR_TARGETS = {
1108
+ claude: {
1109
+ name: "claude",
1110
+ contextFile: "CLAUDE.md",
1111
+ launchCmd: "claude",
1112
+ launchArgs: [],
1113
+ yoloArgs: ["--dangerously-skip-permissions"],
1114
+ gitignoreEntry: "CLAUDE.md",
1115
+ displayName: "Claude Code"
1116
+ },
1117
+ copilot: {
1118
+ name: "copilot",
1119
+ contextFile: ".github/copilot-instructions.md",
1120
+ launchCmd: "code",
1121
+ launchArgs: ["."],
1122
+ gitignoreEntry: ".github/copilot-instructions.md",
1123
+ displayName: "VS Code (Copilot)"
1124
+ },
1125
+ cursor: {
1126
+ name: "cursor",
1127
+ contextFile: ".cursorrules",
1128
+ launchCmd: "cursor",
1129
+ launchArgs: ["."],
1130
+ gitignoreEntry: ".cursorrules",
1131
+ displayName: "Cursor"
1132
+ }
1133
+ };
1134
+ writeClaudeMd = writeContextFile;
1091
1135
  }
1092
1136
  });
1093
1137
 
@@ -1098,15 +1142,20 @@ __export(dev_command_exports, {
1098
1142
  });
1099
1143
  import fs27 from "fs";
1100
1144
  import path27 from "path";
1101
- function ensureGitignore(projectPath) {
1145
+ function ensureGitignore(projectPath, editor) {
1102
1146
  const gitignorePath = path27.join(projectPath, ".gitignore");
1103
1147
  if (!fs27.existsSync(gitignorePath)) return;
1104
1148
  const content = fs27.readFileSync(gitignorePath, "utf-8");
1105
- if (content.includes("CLAUDE.md")) return;
1106
- fs27.appendFileSync(gitignorePath, "\n# Generated by aman-agent dev\nCLAUDE.md\n");
1149
+ const target = EDITOR_TARGETS[editor];
1150
+ if (content.includes(target.gitignoreEntry)) return;
1151
+ fs27.appendFileSync(gitignorePath, `
1152
+ # Generated by aman-agent dev
1153
+ ${target.gitignoreEntry}
1154
+ `);
1107
1155
  }
1108
1156
  async function runDev(projectPath, flags = {}, precomputedStack) {
1109
1157
  const resolved = path27.resolve(projectPath);
1158
+ const editor = flags.editor ?? "claude";
1110
1159
  if (!fs27.existsSync(resolved)) {
1111
1160
  return { success: false, generated: false, error: `Directory not found: ${resolved}` };
1112
1161
  }
@@ -1114,7 +1163,8 @@ async function runDev(projectPath, flags = {}, precomputedStack) {
1114
1163
  if (flags.diff) {
1115
1164
  const ctx2 = await buildContext2(stack, { smart: flags.smart });
1116
1165
  const newContent = renderToString(ctx2);
1117
- const existingPath = path27.join(resolved, "CLAUDE.md");
1166
+ const target = EDITOR_TARGETS[editor];
1167
+ const existingPath = path27.join(resolved, target.contextFile);
1118
1168
  const existing = fs27.existsSync(existingPath) ? fs27.readFileSync(existingPath, "utf-8") : "";
1119
1169
  return {
1120
1170
  success: true,
@@ -1123,18 +1173,26 @@ async function runDev(projectPath, flags = {}, precomputedStack) {
1123
1173
  context: ctx2
1124
1174
  };
1125
1175
  }
1126
- if (!flags.force) {
1127
- const staleness = checkStaleness(resolved);
1176
+ if (!flags.force && !flags.smart) {
1177
+ const staleness = checkStaleness(resolved, editor);
1128
1178
  if (staleness.status === "fresh") {
1129
- return { success: true, generated: false, skippedReason: "fresh" };
1179
+ if (staleness.generatedAt) {
1180
+ const ageMs = Date.now() - staleness.generatedAt.getTime();
1181
+ const ONE_HOUR = 60 * 60 * 1e3;
1182
+ if (ageMs < ONE_HOUR) {
1183
+ return { success: true, generated: false, skippedReason: "fresh" };
1184
+ }
1185
+ } else {
1186
+ return { success: true, generated: false, skippedReason: "fresh" };
1187
+ }
1130
1188
  }
1131
1189
  }
1132
1190
  const ctx = await buildContext2(stack, { smart: flags.smart });
1133
- const writeResult = writeClaudeMd(ctx, resolved);
1134
- ensureGitignore(resolved);
1191
+ writeContextFile(ctx, resolved, editor);
1192
+ ensureGitignore(resolved, editor);
1135
1193
  return {
1136
1194
  success: true,
1137
- generated: writeResult.written,
1195
+ generated: true,
1138
1196
  context: ctx
1139
1197
  };
1140
1198
  }
@@ -7099,7 +7157,7 @@ function handleReset(action) {
7099
7157
  function handleUpdate() {
7100
7158
  try {
7101
7159
  const current = execFileSync3("npm", ["view", "@aman_asmuei/aman-agent", "version"], { encoding: "utf-8" }).trim();
7102
- const local = true ? "0.33.8" : "unknown";
7160
+ const local = true ? "0.34.0" : "unknown";
7103
7161
  if (current === local) {
7104
7162
  return { handled: true, output: `${pc6.green("Up to date")} \u2014 v${local}` };
7105
7163
  }
@@ -10083,7 +10141,7 @@ var Inbox = class {
10083
10141
  // package.json
10084
10142
  var package_default = {
10085
10143
  name: "@aman_asmuei/aman-agent",
10086
- version: "0.33.8",
10144
+ version: "0.34.0",
10087
10145
  description: "Your AI companion, running locally \u2014 powered by the aman ecosystem",
10088
10146
  type: "module",
10089
10147
  engines: {
@@ -10450,7 +10508,7 @@ function bootstrapEcosystem() {
10450
10508
  return true;
10451
10509
  }
10452
10510
  var program = new Command();
10453
- program.name("aman-agent").description("Your AI companion, running locally").version("0.33.8").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) => {
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) => {
10454
10512
  p4.intro(pc9.bold("aman agent") + pc9.dim(" \u2014 your AI companion"));
10455
10513
  let config = loadConfig();
10456
10514
  if (!config) {
@@ -10845,9 +10903,12 @@ program.command("serve").description("Run aman-agent as a local MCP server other
10845
10903
  process.exit(1);
10846
10904
  }
10847
10905
  });
10848
- program.command("dev [path]").description("Set up project context and start Claude Code").option("--smart", "Use LLM to generate CLAUDE.md").option("--no-launch", "Generate CLAUDE.md only, don't start claude").option("--force", "Regenerate even if CLAUDE.md is fresh").option("--diff", "Show what would change without writing").option("--yolo", "Launch Claude Code with --dangerously-skip-permissions").action(async (projectPath, opts) => {
10906
+ program.command("dev [path]").description("Set up project context and launch your editor (Claude Code, Copilot, or Cursor)").option("--smart", "Use LLM to synthesize context file").option("--no-launch", "Generate context file only, don't launch editor").option("--force", "Regenerate even if context file is fresh").option("--diff", "Show what would change without writing").option("--yolo", "Launch with skip-permissions (Claude Code only)").option("--copilot", "Target GitHub Copilot (writes .github/copilot-instructions.md, opens VS Code)").option("--cursor", "Target Cursor editor (writes .cursorrules, opens Cursor)").action(async (projectPath, opts) => {
10849
10907
  const { runDev: runDev2 } = await Promise.resolve().then(() => (init_dev_command(), dev_command_exports));
10850
10908
  const { scanStack: scanStack2 } = await Promise.resolve().then(() => (init_stack_detector(), stack_detector_exports));
10909
+ const { EDITOR_TARGETS: EDITOR_TARGETS2 } = await Promise.resolve().then(() => (init_claude_md_writer(), claude_md_writer_exports));
10910
+ const editorName = opts.copilot ? "copilot" : opts.cursor ? "cursor" : "claude";
10911
+ const target = EDITOR_TARGETS2[editorName];
10851
10912
  const targetPath = projectPath ?? process.cwd();
10852
10913
  const stack = scanStack2(targetPath);
10853
10914
  const stackParts = stack.languages.map((l) => l.charAt(0).toUpperCase() + l.slice(1));
@@ -10865,13 +10926,14 @@ program.command("dev [path]").description("Set up project context and start Clau
10865
10926
  ${pc9.cyan("Detected:")} ${stackParts.join(" + ")}`);
10866
10927
  } else {
10867
10928
  console.log(`
10868
- ${pc9.dim("No stack detected \u2014 generating minimal CLAUDE.md")}`);
10929
+ ${pc9.dim("No stack detected \u2014 generating minimal context")}`);
10869
10930
  }
10870
10931
  const result = await runDev2(targetPath, {
10871
10932
  smart: opts.smart,
10872
10933
  noLaunch: opts.launch === false,
10873
10934
  force: opts.force,
10874
- diff: opts.diff
10935
+ diff: opts.diff,
10936
+ editor: editorName
10875
10937
  }, stack);
10876
10938
  if (!result.success) {
10877
10939
  console.error(` ${pc9.red("Error:")} ${result.error}`);
@@ -10886,30 +10948,30 @@ ${result.diff}`);
10886
10948
  const mode = opts.smart ? "smart" : "template";
10887
10949
  const memCount = result.context?.metadata.memoriesUsed ?? 0;
10888
10950
  console.log(` ${pc9.cyan("Recalled:")} ${memCount} memories`);
10889
- console.log(` ${pc9.green("\u2713")} CLAUDE.md written (${mode} mode)
10951
+ console.log(` ${pc9.green("\u2713")} ${target.contextFile} written (${mode} mode)
10890
10952
  `);
10891
10953
  } else if (result.skippedReason === "fresh") {
10892
- console.log(` ${pc9.green("\u2713")} CLAUDE.md is up to date
10954
+ console.log(` ${pc9.green("\u2713")} ${target.contextFile} is up to date
10893
10955
  `);
10894
10956
  }
10895
10957
  if (opts.launch !== false && !opts.diff) {
10896
10958
  const { execFileSync: execFileSync4 } = await import("child_process");
10897
10959
  try {
10898
- execFileSync4("which", ["claude"], { stdio: "ignore" });
10960
+ execFileSync4("which", [target.launchCmd], { stdio: "ignore" });
10899
10961
  } catch {
10900
- console.log(` ${pc9.yellow("Claude Code not found.")} Install: npm install -g @anthropic-ai/claude-code`);
10962
+ console.log(` ${pc9.yellow(`${target.displayName} not found.`)} Ensure '${target.launchCmd}' is in your PATH.`);
10901
10963
  process.exit(1);
10902
10964
  }
10903
- const claudeArgs = [];
10904
- if (opts.yolo) {
10905
- claudeArgs.push("--dangerously-skip-permissions");
10906
- console.log(` ${pc9.cyan("Launching Claude Code")} ${pc9.yellow("(--dangerously-skip-permissions)")}...
10965
+ const launchArgs = [...target.launchArgs];
10966
+ if (opts.yolo && target.yoloArgs) {
10967
+ launchArgs.push(...target.yoloArgs);
10968
+ console.log(` ${pc9.cyan(`Launching ${target.displayName}`)} ${pc9.yellow("(skip-permissions)")}...
10907
10969
  `);
10908
10970
  } else {
10909
- console.log(` ${pc9.cyan("Launching Claude Code...")}
10971
+ console.log(` ${pc9.cyan(`Launching ${target.displayName}...`)}
10910
10972
  `);
10911
10973
  }
10912
- execFileSync4("claude", claudeArgs, { cwd: targetPath, stdio: "inherit" });
10974
+ execFileSync4(target.launchCmd, launchArgs, { cwd: targetPath, stdio: "inherit" });
10913
10975
  }
10914
10976
  });
10915
10977
  program.command("setup").description("Run the full configuration wizard (provider, identity, presets)").action(async () => {