@arrislink/axon 1.0.6 → 1.0.8

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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +249 -95
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -129,6 +129,7 @@ graph LR
129
129
  |---------|-------------|
130
130
  | `ax init [name]` | Initialize a new Axon project |
131
131
  | `ax spec init` | Create project specification interactively |
132
+ | `ax spec edit` | Edit the existing specification |
132
133
  | `ax spec show` | Display current specification |
133
134
  | `ax plan` | Generate task graph from specification |
134
135
  | `ax work` | Execute the next task |
package/dist/index.js CHANGED
@@ -16209,7 +16209,34 @@ var require_prompts3 = __commonJS((exports, module) => {
16209
16209
  module.exports = isNodeLT("8.6.0") ? require_dist() : require_lib();
16210
16210
  });
16211
16211
 
16212
+ // src/utils/i18n.ts
16213
+ function detectLocale() {
16214
+ const lang = process.env["LANG"] || process.env["LANGUAGE"] || process.env["LC_ALL"] || "en";
16215
+ if (lang.toLowerCase().includes("zh")) {
16216
+ currentLocale = "zh";
16217
+ } else {
16218
+ currentLocale = "en";
16219
+ }
16220
+ return currentLocale;
16221
+ }
16222
+ function t(en, zh) {
16223
+ return currentLocale === "zh" ? zh : en;
16224
+ }
16225
+ var currentLocale = "en";
16226
+ var init_i18n = __esm(() => {
16227
+ detectLocale();
16228
+ });
16229
+
16212
16230
  // src/utils/prompt.ts
16231
+ var exports_prompt = {};
16232
+ __export(exports_prompt, {
16233
+ select: () => select,
16234
+ password: () => password,
16235
+ multiSelect: () => multiSelect,
16236
+ input: () => input,
16237
+ editor: () => editor,
16238
+ confirm: () => confirm
16239
+ });
16213
16240
  async function confirm(options) {
16214
16241
  const response = await import_prompts2.default({
16215
16242
  type: "confirm",
@@ -16255,6 +16282,23 @@ async function input(options) {
16255
16282
  });
16256
16283
  return response.value || "";
16257
16284
  }
16285
+ async function password(message) {
16286
+ const response = await import_prompts2.default({
16287
+ type: "password",
16288
+ name: "value",
16289
+ message
16290
+ });
16291
+ return response.value || "";
16292
+ }
16293
+ async function editor(message, defaultValue) {
16294
+ const response = await import_prompts2.default({
16295
+ type: "text",
16296
+ name: "value",
16297
+ message: `${message} (Editor not supported, please enter text)`,
16298
+ initial: defaultValue
16299
+ });
16300
+ return response.value || "";
16301
+ }
16258
16302
  var import_prompts2;
16259
16303
  var init_prompt = __esm(() => {
16260
16304
  import_prompts2 = __toESM(require_prompts3(), 1);
@@ -16264,36 +16308,37 @@ var init_prompt = __esm(() => {
16264
16308
  class SpecCollector {
16265
16309
  constructor() {}
16266
16310
  async collect() {
16267
- logger.title("Axon \u9700\u6C42\u6536\u96C6");
16268
- console.log(`\u8BA9\u6211\u4EEC\u5F00\u59CB\u5B9A\u4E49\u4F60\u7684\u9879\u76EE\uFF01
16269
- `);
16311
+ logger.title(t("Axon Requirements Collection", "Axon \u9700\u6C42\u6536\u96C6"));
16312
+ console.log(t(`Let's start defining your project!
16313
+ `, `\u8BA9\u6211\u4EEC\u5F00\u59CB\u5B9A\u4E49\u4F60\u7684\u9879\u76EE\uFF01
16314
+ `));
16270
16315
  const description = await input({
16271
- message: "\uD83C\uDF40 \u4F60\u60F3\u6784\u5EFA\u4EC0\u4E48\u9879\u76EE\uFF1F",
16272
- validate: (val) => val.length > 5 || "\u8BF7\u63D0\u4F9B\u66F4\u8BE6\u7EC6\u7684\u63CF\u8FF0"
16316
+ message: t("\uD83C\uDF40 What project do you want to build?", "\uD83C\uDF40 \u4F60\u60F3\u6784\u5EFA\u4EC0\u4E48\u9879\u76EE\uFF1F"),
16317
+ validate: (val) => val.length > 5 || t("Please provide a more detailed description", "\u8BF7\u63D0\u4F9B\u66F4\u8BE6\u7EC6\u7684\u63CF\u8FF0")
16273
16318
  });
16274
- const projectType = await select("\uD83D\uDCE6 \u9879\u76EE\u7C7B\u578B\uFF1F", [
16275
- { name: "Web API", value: "api", description: "RESTful \u6216 GraphQL \u540E\u7AEF\u670D\u52A1" },
16276
- { name: "Web \u5E94\u7528", value: "webapp", description: "\u524D\u7AEF + \u540E\u7AEF\u5B8C\u6574\u5E94\u7528" },
16277
- { name: "Axon Skill", value: "skill", description: "\u53EF\u590D\u7528\u7684 AI \u6280\u80FD/\u63D2\u4EF6" },
16278
- { name: "CLI \u5DE5\u5177", value: "cli", description: "\u547D\u4EE4\u884C\u5DE5\u5177" },
16279
- { name: "\u5E93/SDK", value: "library", description: "\u53EF\u590D\u7528\u7684\u4EE3\u7801\u5E93" },
16280
- { name: "\u5176\u4ED6", value: "other", description: "\u5176\u4ED6\u7C7B\u578B\u9879\u76EE" }
16319
+ const projectType = await select(t("\uD83D\uDCE6 Project type?", "\uD83D\uDCE6 \u9879\u76EE\u7C7B\u578B\uFF1F"), [
16320
+ { name: "Web API", value: "api", description: t("RESTful or GraphQL backend service", "RESTful \u6216 GraphQL \u540E\u7AEF\u670D\u52A1") },
16321
+ { name: "Web App", value: "webapp", description: t("Frontend + Backend full application", "\u524D\u7AEF + \u540E\u7AEF\u5B8C\u6574\u5E94\u7528") },
16322
+ { name: "Axon Skill", value: "skill", description: t("Reusable AI skill/plugin", "\u53EF\u590D\u7528\u7684 AI \u6280\u80FD/\u63D2\u4EF6") },
16323
+ { name: "CLI Tool", value: "cli", description: t("Command line tool", "\u547D\u4EE4\u884C\u5DE5\u5177") },
16324
+ { name: "Library/SDK", value: "library", description: t("Reusable code library", "\u53EF\u590D\u7528\u7684\u4EE3\u7801\u5E93") },
16325
+ { name: "Other", value: "other", description: t("Other types of projects", "\u5176\u4ED6\u7C7B\u578B\u9879\u76EE") }
16281
16326
  ]);
16282
16327
  const featureOptions = this.getFeatureOptions(projectType);
16283
- const features = await multiSelect("\u2728 \u9700\u8981\u54EA\u4E9B\u529F\u80FD\uFF1F", featureOptions);
16284
- const techStack = await select("\uD83D\uDEE0\uFE0F \u6280\u672F\u6808\u504F\u597D\uFF1F", [
16285
- { name: "TypeScript + Bun", value: "typescript-bun", description: "\u5FEB\u901F\u3001\u73B0\u4EE3\u7684 JS \u8FD0\u884C\u65F6" },
16286
- { name: "TypeScript + Node.js", value: "typescript-node", description: "\u6210\u719F\u7A33\u5B9A\u7684 JS \u8FD0\u884C\u65F6" },
16287
- { name: "Go", value: "go", description: "\u9AD8\u6027\u80FD\u3001\u7B80\u6D01\u7684\u8BED\u8A00" },
16288
- { name: "Python + FastAPI", value: "python-fastapi", description: "\u5FEB\u901F API \u5F00\u53D1" },
16289
- { name: "Rust", value: "rust", description: "\u5185\u5B58\u5B89\u5168\u3001\u9AD8\u6027\u80FD" },
16290
- { name: "\u8BA9 AI \u63A8\u8350", value: "auto", description: "\u6839\u636E\u9879\u76EE\u9700\u6C42\u81EA\u52A8\u9009\u62E9" }
16328
+ const features = await multiSelect(t("\u2728 Which features do you need?", "\u2728 \u9700\u8981\u54EA\u4E9B\u529F\u80FD\uFF1F"), featureOptions);
16329
+ const techStack = await select(t("\uD83D\uDEE0\uFE0F Tech stack preference?", "\uD83D\uDEE0\uFE0F \u6280\u672F\u6808\u504F\u597D\uFF1F"), [
16330
+ { name: "TypeScript + Bun", value: "typescript-bun", description: t("Fast, modern JS runtime", "\u5FEB\u901F\u3001\u73B0\u4EE3\u7684 JS \u8FD0\u884C\u65F6") },
16331
+ { name: "TypeScript + Node.js", value: "typescript-node", description: t("Mature and stable JS runtime", "\u6210\u719F\u7A33\u5B9A\u7684 JS \u8FD0\u884C\u65F6") },
16332
+ { name: "Go", value: "go", description: t("High performance, concise language", "\u9AD8\u6027\u80FD\u3001\u7B80\u6D01\u7684\u8BED\u8A00") },
16333
+ { name: "Python + FastAPI", value: "python-fastapi", description: t("Fast API development", "\u5FEB\u901F API \u5F00\u53D1") },
16334
+ { name: "Rust", value: "rust", description: t("Memory safe, high performance", "\u5185\u5B58\u5B89\u5168\u3001\u9AD8\u6027\u80FD") },
16335
+ { name: "Let AI Recommend", value: "auto", description: t("Automatically choose based on requirements", "\u6839\u636E\u9879\u76EE\u9700\u6C42\u81EA\u52A8\u9009\u62E9") }
16291
16336
  ]);
16292
16337
  let additionalRequirements = "";
16293
- const hasMore = await confirm({ message: "\uD83D\uDCDD \u8FD8\u6709\u5176\u4ED6\u9700\u6C42\u8981\u8865\u5145\u5417\uFF1F", default: false });
16338
+ const hasMore = await confirm({ message: t("\uD83D\uDCDD Any other requirements to add?", "\uD83D\uDCDD \u8FD8\u6709\u5176\u4ED6\u9700\u6C42\u8981\u8865\u5145\u5417\uFF1F"), default: false });
16294
16339
  if (hasMore) {
16295
16340
  additionalRequirements = await input({
16296
- message: "\u8BF7\u63CF\u8FF0\u5176\u4ED6\u9700\u6C42:"
16341
+ message: t("Please describe other requirements:", "\u8BF7\u63CF\u8FF0\u5176\u4ED6\u9700\u6C42:")
16297
16342
  });
16298
16343
  }
16299
16344
  return {
@@ -16306,46 +16351,46 @@ class SpecCollector {
16306
16351
  }
16307
16352
  getFeatureOptions(projectType) {
16308
16353
  const common = [
16309
- { name: "\u65E5\u5FD7\u8BB0\u5F55", value: "logging" },
16310
- { name: "\u9519\u8BEF\u5904\u7406", value: "error-handling" },
16311
- { name: "\u914D\u7F6E\u7BA1\u7406", value: "config" },
16312
- { name: "\u5355\u5143\u6D4B\u8BD5", value: "testing" }
16354
+ { name: t("Logging", "\u65E5\u5FD7\u8BB0\u5F55"), value: "logging" },
16355
+ { name: t("Error Handling", "\u9519\u8BEF\u5904\u7406"), value: "error-handling" },
16356
+ { name: t("Config Management", "\u914D\u7F6E\u7BA1\u7406"), value: "config" },
16357
+ { name: t("Unit Testing", "\u5355\u5143\u6D4B\u8BD5"), value: "testing" }
16313
16358
  ];
16314
16359
  switch (projectType) {
16315
16360
  case "api":
16316
16361
  return [
16317
- { name: "\u7528\u6237\u8BA4\u8BC1 (JWT)", value: "auth-jwt" },
16362
+ { name: t("Authentication (JWT)", "\u7528\u6237\u8BA4\u8BC1 (JWT)"), value: "auth-jwt" },
16318
16363
  { name: "OAuth 2.0", value: "oauth" },
16319
- { name: "CRUD \u57FA\u7840\u63A5\u53E3", value: "crud" },
16320
- { name: "\u6570\u636E\u9A8C\u8BC1", value: "validation" },
16321
- { name: "API \u6587\u6863 (OpenAPI)", value: "openapi" },
16322
- { name: "\u901F\u7387\u9650\u5236", value: "rate-limit" },
16364
+ { name: t("CRUD Basic API", "CRUD \u57FA\u7840\u63A5\u53E3"), value: "crud" },
16365
+ { name: t("Data Validation", "\u6570\u636E\u9A8C\u8BC1"), value: "validation" },
16366
+ { name: t("API Docs (OpenAPI)", "API \u6587\u6863 (OpenAPI)"), value: "openapi" },
16367
+ { name: t("Rate Limit", "\u901F\u7387\u9650\u5236"), value: "rate-limit" },
16323
16368
  ...common
16324
16369
  ];
16325
16370
  case "webapp":
16326
16371
  return [
16327
- { name: "\u7528\u6237\u8BA4\u8BC1", value: "auth" },
16328
- { name: "\u54CD\u5E94\u5F0F UI", value: "responsive" },
16329
- { name: "\u72B6\u6001\u7BA1\u7406", value: "state" },
16330
- { name: "\u8DEF\u7531", value: "routing" },
16331
- { name: "API \u96C6\u6210", value: "api-integration" },
16372
+ { name: t("Authentication", "\u7528\u6237\u8BA4\u8BC1"), value: "auth" },
16373
+ { name: t("Responsive UI", "\u54CD\u5E94\u5F0F UI"), value: "responsive" },
16374
+ { name: t("State Management", "\u72B6\u6001\u7BA1\u7406"), value: "state" },
16375
+ { name: t("Routing", "\u8DEF\u7531"), value: "routing" },
16376
+ { name: t("API Integration", "API \u96C6\u6210"), value: "api-integration" },
16332
16377
  ...common
16333
16378
  ];
16334
16379
  case "cli":
16335
16380
  return [
16336
- { name: "\u4EA4\u4E92\u5F0F\u63D0\u793A", value: "interactive" },
16337
- { name: "\u914D\u7F6E\u6587\u4EF6\u652F\u6301", value: "config-file" },
16338
- { name: "\u5E2E\u52A9\u6587\u6863", value: "help" },
16339
- { name: "\u8FDB\u5EA6\u663E\u793A", value: "progress" },
16340
- { name: "\u989C\u8272\u8F93\u51FA", value: "colors" },
16381
+ { name: t("Interactive Prompts", "\u4EA4\u4E92\u5F0F\u63D0\u793A"), value: "interactive" },
16382
+ { name: t("Config File Support", "\u914D\u7F6E\u6587\u4EF6\u652F\u6301"), value: "config-file" },
16383
+ { name: t("Help Docs", "\u5E2E\u52A9\u6587\u6863"), value: "help" },
16384
+ { name: t("Progress Indicators", "\u8FDB\u5EA6\u663E\u793A"), value: "progress" },
16385
+ { name: t("Colorized Output", "\u989C\u8272\u8F93\u51FA"), value: "colors" },
16341
16386
  ...common
16342
16387
  ];
16343
16388
  case "skill":
16344
16389
  return [
16345
- { name: "\u529F\u80FD\u63CF\u8FF0 (Skill Spec)", value: "skill-spec" },
16346
- { name: "\u4F7F\u7528\u793A\u4F8B (Examples)", value: "skill-examples" },
16347
- { name: "\u6838\u5FC3\u903B\u8F91 (Beads)", value: "skill-logic" },
16348
- { name: "\u4F9D\u8D56\u7BA1\u7406", value: "skill-deps" },
16390
+ { name: t("Skill Spec", "\u529F\u80FD\u63CF\u8FF0 (Skill Spec)"), value: "skill-spec" },
16391
+ { name: t("Skill Examples", "\u4F7F\u7528\u793A\u4F8B (Examples)"), value: "skill-examples" },
16392
+ { name: t("Core Logic (Beads)", "\u6838\u5FC3\u903B\u8F91 (Beads)"), value: "skill-logic" },
16393
+ { name: t("Dependency Management", "\u4F9D\u8D56\u7BA1\u7406"), value: "skill-deps" },
16349
16394
  ...common
16350
16395
  ];
16351
16396
  default:
@@ -16356,6 +16401,7 @@ class SpecCollector {
16356
16401
  var init_collector = __esm(() => {
16357
16402
  init_prompt();
16358
16403
  init_logger();
16404
+ init_i18n();
16359
16405
  });
16360
16406
 
16361
16407
  // src/core/integrations/anthropic.ts
@@ -17628,7 +17674,7 @@ class SkillsLibrary {
17628
17674
  }
17629
17675
  let result = [...this.skills];
17630
17676
  if (filter?.tags?.length) {
17631
- result = result.filter((s) => s.metadata.tags.some((t) => filter.tags?.includes(t)));
17677
+ result = result.filter((s) => s.metadata.tags.some((t2) => filter.tags?.includes(t2)));
17632
17678
  }
17633
17679
  if (filter?.difficulty) {
17634
17680
  result = result.filter((s) => s.metadata.difficulty === filter.difficulty);
@@ -19723,6 +19769,9 @@ var {
19723
19769
 
19724
19770
  // src/index.ts
19725
19771
  init_source();
19772
+ import { readFileSync as readFileSync7 } from "fs";
19773
+ import { join as join12, dirname as dirname5 } from "path";
19774
+ import { fileURLToPath } from "url";
19726
19775
 
19727
19776
  // src/commands/init.ts
19728
19777
  init_source();
@@ -24767,11 +24816,12 @@ function progressBar(current, total, width = 20) {
24767
24816
 
24768
24817
  // src/commands/init.ts
24769
24818
  init_errors();
24819
+ init_i18n();
24770
24820
  var import_prompts = __toESM(require_prompts3(), 1);
24771
- var initCommand = new Command("init").description("\u521D\u59CB\u5316\u65B0\u7684 Axon \u9879\u76EE").argument("[project-name]", "\u9879\u76EE\u540D\u79F0", ".").option("-t, --template <name>", "\u4F7F\u7528\u6A21\u677F (web, api, cli)", "default").option("--skip-install", "\u8DF3\u8FC7\u4F9D\u8D56\u5B89\u88C5").option("--skip-git", "\u8DF3\u8FC7 Git \u521D\u59CB\u5316").action(async (projectName, options) => {
24821
+ var initCommand = new Command("init").description(t("Initialize a new Axon project", "\u521D\u59CB\u5316\u65B0\u7684 Axon \u9879\u76EE")).argument("[project-name]", t("Project name", "\u9879\u76EE\u540D\u79F0"), ".").option("-t, --template <name>", t("Use template (web, api, cli)", "\u4F7F\u7528\u6A21\u677F (web, api, cli)"), "default").option("--skip-install", t("Skip dependency installation", "\u8DF3\u8FC7\u4F9D\u8D56\u5B89\u88C5")).option("--skip-git", t("Skip Git initialization", "\u8DF3\u8FC7 Git \u521D\u59CB\u5316")).action(async (projectName, options) => {
24772
24822
  const projectPath = projectName === "." ? process.cwd() : join4(process.cwd(), projectName);
24773
24823
  const name = projectName === "." ? basename(process.cwd()) : projectName;
24774
- logger.title("Axon \u9879\u76EE\u521D\u59CB\u5316");
24824
+ logger.title(t("Axon Project Initialization", "Axon \u9879\u76EE\u521D\u59CB\u5316"));
24775
24825
  if (ConfigManager.isAxonProject(projectPath)) {
24776
24826
  throw new AxonError("\u9879\u76EE\u5DF2\u521D\u59CB\u5316", "INIT_ERROR", [
24777
24827
  `\u76EE\u5F55 ${projectPath} \u5DF2\u5B58\u5728 .axon \u914D\u7F6E`,
@@ -24780,7 +24830,7 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u65B0\u768
24780
24830
  }
24781
24831
  const existingConfigs = detectExistingConfig(projectPath);
24782
24832
  if (existingConfigs.hasOpenCode || existingConfigs.hasBeads) {
24783
- logger.warn("\u26A0\uFE0F \u68C0\u6D4B\u5230\u73B0\u6709\u914D\u7F6E");
24833
+ logger.warn(t("\u26A0\uFE0F Existing configuration detected", "\u26A0\uFE0F \u68C0\u6D4B\u5230\u73B0\u6709\u914D\u7F6E"));
24784
24834
  if (existingConfigs.hasOpenCode)
24785
24835
  console.log(source_default.dim(" - .opencode/ (OpenCode)"));
24786
24836
  if (existingConfigs.hasBeads)
@@ -24789,16 +24839,16 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u65B0\u768
24789
24839
  const response = await import_prompts.default({
24790
24840
  type: "select",
24791
24841
  name: "action",
24792
- message: "\u5982\u4F55\u5904\u7406\u73B0\u6709\u914D\u7F6E\uFF1F",
24842
+ message: t("How to handle existing configuration?", "\u5982\u4F55\u5904\u7406\u73B0\u6709\u914D\u7F6E\uFF1F"),
24793
24843
  choices: [
24794
- { title: "\u4FDD\u7559\u73B0\u6709\u914D\u7F6E (Merge)", value: "merge", description: "\u4FDD\u7559\u73B0\u6709\u6587\u4EF6\uFF0C\u4EC5\u6DFB\u52A0 Axon \u914D\u7F6E" },
24795
- { title: "\u5907\u4EFD\u5E76\u521B\u5EFA\u65B0\u914D\u7F6E (Backup)", value: "backup", description: "\u5907\u4EFD\u73B0\u6709\u76EE\u5F55\u4E3A .backup \u540E\u91CD\u5EFA" },
24796
- { title: "\u53D6\u6D88\u521D\u59CB\u5316 (Cancel)", value: "cancel" }
24844
+ { title: t("Keep it (Merge)", "\u4FDD\u7559\u73B0\u6709\u914D\u7F6E (Merge)"), value: "merge", description: t("Keep existing files, only add Axon config", "\u4FDD\u7559\u73B0\u6709\u6587\u4EF6\uFF0C\u4EC5\u6DFB\u52A0 Axon \u914D\u7F6E") },
24845
+ { title: t("Backup and recreate (Backup)", "\u5907\u4EFD\u5E76\u521B\u5EFA\u65B0\u914D\u7F6E (Backup)"), value: "backup", description: t("Backup existing directories to .backup then recreate", "\u5907\u4EFD\u73B0\u6709\u76EE\u5F55\u4E3A .backup \u540E\u91CD\u5EFA") },
24846
+ { title: t("Cancel", "\u53D6\u6D88\u521D\u59CB\u5316 (Cancel)"), value: "cancel" }
24797
24847
  ],
24798
24848
  initial: 0
24799
24849
  });
24800
24850
  if (!response.action || response.action === "cancel") {
24801
- logger.info("\u5DF2\u53D6\u6D88\u521D\u59CB\u5316");
24851
+ logger.info(t("Initialization cancelled", "\u5DF2\u53D6\u6D88\u521D\u59CB\u5316"));
24802
24852
  return;
24803
24853
  }
24804
24854
  if (response.action === "backup") {
@@ -24809,15 +24859,15 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u65B0\u768
24809
24859
  if (existingConfigs.hasBeads) {
24810
24860
  await Bun.$`mv ${join4(projectPath, ".beads")} ${join4(projectPath, `.beads.backup.${timestamp}`)}`;
24811
24861
  }
24812
- logger.success(`\u2705 \u5DF2\u5907\u4EFD\u73B0\u6709\u914D\u7F6E`);
24862
+ logger.success(t("\u2705 Existing configuration backed up", "\u2705 \u5DF2\u5907\u4EFD\u73B0\u6709\u914D\u7F6E"));
24813
24863
  }
24814
24864
  }
24815
24865
  if (!existsSync3(projectPath)) {
24816
- spinner.start(`\u521B\u5EFA\u9879\u76EE\u76EE\u5F55 ${source_default.cyan(name)}`);
24866
+ spinner.start(t(`Creating project directory ${source_default.cyan(name)}`, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55 ${source_default.cyan(name)}`));
24817
24867
  mkdirSync2(projectPath, { recursive: true });
24818
24868
  spinner.succeed();
24819
24869
  }
24820
- spinner.start("\u521B\u5EFA Axon \u76EE\u5F55\u7ED3\u6784");
24870
+ spinner.start(t("Creating Axon directory structure", "\u521B\u5EFA Axon \u76EE\u5F55\u7ED3\u6784"));
24821
24871
  for (const dir of DEFAULT_DIRECTORIES) {
24822
24872
  const fullPath = join4(projectPath, dir);
24823
24873
  if (!existsSync3(fullPath)) {
@@ -24825,30 +24875,33 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u65B0\u768
24825
24875
  }
24826
24876
  }
24827
24877
  spinner.succeed();
24828
- spinner.start("\u751F\u6210\u914D\u7F6E\u6587\u4EF6");
24878
+ spinner.start(t("Generating configuration file", "\u751F\u6210\u914D\u7F6E\u6587\u4EF6"));
24829
24879
  ConfigManager.initialize(projectPath, name);
24830
24880
  spinner.succeed();
24831
24881
  if (!options.skipReadme && !existsSync3(join4(projectPath, "README.md"))) {
24832
- spinner.start("\u751F\u6210 README.md");
24882
+ spinner.start(t("Generating README.md", "\u751F\u6210 README.md"));
24833
24883
  const readme = generateReadme(name);
24834
24884
  await Bun.write(join4(projectPath, "README.md"), readme);
24835
24885
  spinner.succeed();
24836
24886
  }
24837
- spinner.start("\u751F\u6210\u5165\u95E8\u6307\u5357");
24887
+ spinner.start(t("Generating Quick Start guide", "\u751F\u6210\u5165\u95E8\u6307\u5357"));
24838
24888
  const gettingStarted = generateGettingStarted(name);
24839
24889
  await Bun.write(join4(projectPath, "GETTING_STARTED.md"), gettingStarted);
24840
24890
  spinner.succeed();
24841
24891
  if (!existsSync3(join4(projectPath, ".openspec", "spec.md"))) {
24842
- spinner.start("\u521B\u5EFA\u89C4\u683C\u6A21\u677F");
24843
- const specContent = `# ${name} \u89C4\u683C\u6587\u6863
24892
+ spinner.start(t("Creating specification template", "\u521B\u5EFA\u89C4\u683C\u6A21\u677F"));
24893
+ const specContent = t(`# ${name} Specification
24894
+
24895
+ (To be filled)
24896
+ `, `# ${name} \u89C4\u683C\u6587\u6863
24844
24897
 
24845
24898
  (\u5F85\u586B\u5199)
24846
- `;
24899
+ `);
24847
24900
  await Bun.write(join4(projectPath, ".openspec", "spec.md"), specContent);
24848
24901
  spinner.succeed();
24849
24902
  }
24850
24903
  if (!options.skipGit) {
24851
- spinner.start("\u521D\u59CB\u5316 Git \u4ED3\u5E93");
24904
+ spinner.start(t("Initializing Git repository", "\u521D\u59CB\u5316 Git \u4ED3\u5E93"));
24852
24905
  const git = new GitOperations(projectPath);
24853
24906
  if (!git.isGitRepo()) {
24854
24907
  await git.init();
@@ -24859,31 +24912,57 @@ var initCommand = new Command("init").description("\u521D\u59CB\u5316\u65B0\u768
24859
24912
  }
24860
24913
  logger.blank();
24861
24914
  logger.divider();
24862
- logger.success(`\u9879\u76EE ${source_default.bold(name)} \u521D\u59CB\u5316\u5B8C\u6210\uFF01`);
24915
+ logger.success(t(`Project ${source_default.bold(name)} initialization complete!`, `\u9879\u76EE ${source_default.bold(name)} \u521D\u59CB\u5316\u5B8C\u6210\uFF01`));
24863
24916
  logger.blank();
24864
- console.log(source_default.dim("\u5DF2\u521B\u5EFA\u4EE5\u4E0B\u7ED3\u6784:"));
24865
- console.log(` ${source_default.cyan(".axon/")} - \u914D\u7F6E\u548C\u5143\u6570\u636E`);
24866
- console.log(` ${source_default.cyan(".openspec/")} - \u89C4\u683C\u6587\u6863`);
24867
- console.log(` ${source_default.cyan(".beads/")} - \u4EFB\u52A1\u56FE`);
24868
- console.log(` ${source_default.cyan(".skills/")} - \u672C\u5730\u6280\u80FD\u5E93`);
24869
- console.log(` ${source_default.cyan("GETTING_STARTED.md")} - \u5165\u95E8\u6307\u5357`);
24870
- console.log(` ${source_default.cyan("README.md")} - \u9879\u76EE\u8BF4\u660E`);
24917
+ console.log(source_default.dim(t("Created structure:", "\u5DF2\u521B\u5EFA\u4EE5\u4E0B\u7ED3\u6784:")));
24918
+ console.log(` ${source_default.cyan(".axon/")} - ${t("Config and metadata", "\u914D\u7F6E\u548C\u5143\u6570\u636E")}`);
24919
+ console.log(` ${source_default.cyan(".openspec/")} - ${t("Specification document", "\u89C4\u683C\u6587\u6863")}`);
24920
+ console.log(` ${source_default.cyan(".beads/")} - ${t("Task graph", "\u4EFB\u52A1\u56FE")}`);
24921
+ console.log(` ${source_default.cyan(".skills/")} - ${t("Local skill library", "\u672C\u5730\u6280\u80FD\u5E93")}`);
24922
+ console.log(` ${source_default.cyan("GETTING_STARTED.md")} - ${t("Quick Start guide", "\u5165\u95E8\u6307\u5357")}`);
24923
+ console.log(` ${source_default.cyan("README.md")} - ${t("Project description", "\u9879\u76EE\u8BF4\u660E")}`);
24871
24924
  logger.blank();
24872
- console.log(source_default.bold("\u4E0B\u4E00\u6B65:"));
24925
+ console.log(source_default.bold(t("Next steps:", "\u4E0B\u4E00\u6B65:")));
24873
24926
  console.log(` 1. ${source_default.cyan("cd " + (projectName === "." ? "" : projectName))}`);
24874
- console.log(` 2. ${source_default.cyan("cat GETTING_STARTED.md")} - \u9605\u8BFB\u5165\u95E8\u6307\u5357`);
24875
- console.log(` 3. ${source_default.cyan("ax spec init")} - \u5B9A\u4E49\u9879\u76EE\u89C4\u683C`);
24876
- console.log(` 4. ${source_default.cyan("ax plan")} - \u751F\u6210\u4EFB\u52A1\u56FE`);
24927
+ console.log(` 2. ${source_default.cyan("cat GETTING_STARTED.md")} - ${t("Read Quick Start guide", "\u9605\u8BFB\u5165\u95E8\u6307\u5357")}`);
24928
+ console.log(` 3. ${source_default.cyan("ax spec init")} - ${t("Define project specification", "\u5B9A\u4E49\u9879\u76EE\u89C4\u683C")}`);
24929
+ console.log(` 4. ${source_default.cyan("ax plan")} - ${t("Generate task graph", "\u751F\u6210\u4EFB\u52A1\u56FE")}`);
24877
24930
  logger.blank();
24878
24931
  });
24879
- function detectExistingConfig(projectPath) {
24880
- return {
24881
- hasOpenCode: existsSync3(join4(projectPath, ".opencode")),
24882
- hasBeads: existsSync3(join4(projectPath, ".beads"))
24883
- };
24884
- }
24885
24932
  function generateGettingStarted(name) {
24886
- return `# ${name} - Axon \u5FEB\u901F\u5165\u95E8
24933
+ return t(`# ${name} - Axon Quick Start
24934
+
24935
+ ## 1. Configure Provider
24936
+ Axon uses OhMyOpenCode (OMO) to manage LLM Providers.
24937
+
24938
+ \`\`\`bash
24939
+ # Install OMO (if not already installed)
24940
+ bunx oh-my-opencode install
24941
+
24942
+ # Configure Provider (Antigravity recommended)
24943
+ bunx oh-my-opencode config set-provider antigravity
24944
+
24945
+ # Test connection
24946
+ ax config test
24947
+ \`\`\`
24948
+
24949
+ ## 2. Define Requirements
24950
+ \`\`\`bash
24951
+ ax spec init
24952
+ \`\`\`
24953
+
24954
+ ## 3. Generate Plan
24955
+ \`\`\`bash
24956
+ ax plan
24957
+ \`\`\`
24958
+
24959
+ ## 4. Start Working
24960
+ \`\`\`bash
24961
+ ax work
24962
+ \`\`\`
24963
+
24964
+ For more documentation, see [README.md](./README.md).
24965
+ `, `# ${name} - Axon \u5FEB\u901F\u5165\u95E8
24887
24966
 
24888
24967
  ## 1. \u914D\u7F6E Provider
24889
24968
  Axon \u4F7F\u7528 OhMyOpenCode (OMO) \u7BA1\u7406 LLM Provider\u3002
@@ -24915,12 +24994,48 @@ ax work
24915
24994
  \`\`\`
24916
24995
 
24917
24996
  \u66F4\u591A\u6587\u6863\u8BF7\u67E5\u770B [README.md](./README.md)\u3002
24918
- `;
24997
+ `);
24919
24998
  }
24920
24999
  function generateReadme(name) {
24921
- return `# ${name}
25000
+ return t(`# ${name}
25001
+
25002
+ > AI-assisted development project created by [Axon](https://github.com/arrislink/axon)
25003
+
25004
+ ## Getting Started
25005
+
25006
+ \`\`\`bash
25007
+ # Define project specification
25008
+ ax spec init
25009
+
25010
+ # Generate task graph
25011
+ ax plan
25012
+
25013
+ # Start executing tasks
25014
+ ax work
25015
+ \`\`\`
24922
25016
 
24923
- > \u7531 [Axon](https://github.com/axon) \u521B\u5EFA\u7684 AI \u8F85\u52A9\u5F00\u53D1\u9879\u76EE
25017
+ ## Project Structure
25018
+
25019
+ - \`.axon/\` - Axon configuration
25020
+ - \`.openspec/\` - Project specification document
25021
+ - \`.beads/\` - Task dependency graph
25022
+ - \`.skills/\` - Local skill templates
25023
+
25024
+ ## Common Commands
25025
+
25026
+ | Command | Description |
25027
+ |------|------|
25028
+ | \`ax status\` | View project status |
25029
+ | \`ax work\` | Execute next task |
25030
+ | \`ax skills search <query>\` | Search skill templates |
25031
+ | \`ax doctor\` | Diagnose environment issues |
25032
+
25033
+ ---
25034
+
25035
+ Powered by \uD83E\uDDE0 Axon
25036
+ `, `# ${name}
25037
+
25038
+ > \u7531 [Axon](https://github.com/arrislink/axon) \u521B\u5EFA\u7684 AI \u8F85\u52A9\u5F00\u53D1\u9879\u76EE
24924
25039
 
24925
25040
  ## \u5F00\u59CB
24926
25041
 
@@ -24954,7 +25069,13 @@ ax work
24954
25069
  ---
24955
25070
 
24956
25071
  \u7531 \uD83E\uDDE0 Axon \u63D0\u4F9B\u652F\u6301
24957
- `;
25072
+ `);
25073
+ }
25074
+ function detectExistingConfig(projectPath) {
25075
+ return {
25076
+ hasOpenCode: existsSync3(join4(projectPath, ".opencode")),
25077
+ hasBeads: existsSync3(join4(projectPath, ".beads"))
25078
+ };
24958
25079
  }
24959
25080
  // src/commands/spec.ts
24960
25081
  init_source();
@@ -25010,6 +25131,38 @@ specCommand.command("init").description("\u4EA4\u4E92\u5F0F\u521B\u5EFA\u9879\u7
25010
25131
  console.log(` 1. \u5BA1\u9605\u5E76\u7F16\u8F91 ${source_default.cyan(".openspec/spec.md")}`);
25011
25132
  console.log(` 2. ${source_default.cyan("ax plan")} - \u751F\u6210\u4EFB\u52A1\u56FE`);
25012
25133
  });
25134
+ specCommand.command("edit").description("\u7F16\u8F91\u9879\u76EE\u89C4\u683C\u6587\u6863").action(async () => {
25135
+ const projectRoot = process.cwd();
25136
+ if (!ConfigManager.isAxonProject(projectRoot)) {
25137
+ throw new AxonError("\u5F53\u524D\u76EE\u5F55\u4E0D\u662F Axon \u9879\u76EE", "SPEC_ERROR", [
25138
+ "\u8BF7\u5148\u8FD0\u884C `ax init` \u521D\u59CB\u5316\u9879\u76EE"
25139
+ ]);
25140
+ }
25141
+ const configManager = new ConfigManager(projectRoot);
25142
+ const config = configManager.get();
25143
+ const specPath = join5(projectRoot, config.tools.openspec.path, "spec.md");
25144
+ if (!existsSync6(specPath)) {
25145
+ throw new AxonError("\u89C4\u683C\u6587\u6863\u4E0D\u5B58\u5728", "SPEC_ERROR", ["\u4F7F\u7528 `ax spec init` \u521B\u5EFA\u89C4\u683C\u6587\u6863"]);
25146
+ }
25147
+ const content = readFileSync3(specPath, "utf-8");
25148
+ spinner.start("\u6253\u5F00\u7F16\u8F91\u5668");
25149
+ try {
25150
+ const { editor: editor2 } = await Promise.resolve().then(() => (init_prompt(), exports_prompt));
25151
+ const edited = await editor2("\u7F16\u8F91\u89C4\u683C\u6587\u6863:", content);
25152
+ if (edited !== content) {
25153
+ await Bun.write(specPath, edited);
25154
+ spinner.succeed("\u89C4\u683C\u6587\u6863\u5DF2\u4FDD\u5B58");
25155
+ } else {
25156
+ spinner.stop();
25157
+ logger.info("\u672A\u505A\u4EFB\u4F55\u66F4\u6539");
25158
+ }
25159
+ } catch (error) {
25160
+ spinner.fail();
25161
+ throw new AxonError("\u7F16\u8F91\u89C4\u683C\u6587\u6863\u5931\u8D25", "SPEC_ERROR", [
25162
+ error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"
25163
+ ]);
25164
+ }
25165
+ });
25013
25166
  specCommand.command("show").description("\u663E\u793A\u5F53\u524D\u89C4\u683C\u6587\u6863").action(() => {
25014
25167
  const projectRoot = process.cwd();
25015
25168
  if (!ConfigManager.isAxonProject(projectRoot)) {
@@ -25035,9 +25188,7 @@ specCommand.command("validate").description("\u9A8C\u8BC1\u89C4\u683C\u6587\u686
25035
25188
  const config = configManager.get();
25036
25189
  const specPath = join5(projectRoot, config.tools.openspec.path, "spec.md");
25037
25190
  if (!existsSync6(specPath)) {
25038
- throw new AxonError("\u89C4\u683C\u6587\u6863\u4E0D\u5B58\u5728", "SPEC_ERROR", [
25039
- "\u4F7F\u7528 `ax spec init` \u521B\u5EFA\u89C4\u683C\u6587\u6863"
25040
- ]);
25191
+ throw new AxonError("\u89C4\u683C\u6587\u6863\u4E0D\u5B58\u5728", "SPEC_ERROR", ["\u4F7F\u7528 `ax spec init` \u521B\u5EFA\u89C4\u683C\u6587\u6863"]);
25041
25192
  }
25042
25193
  const content = readFileSync3(specPath, "utf-8");
25043
25194
  const issues = [];
@@ -25317,7 +25468,7 @@ skillsCommand.command("list").description("\u5217\u51FA\u6240\u6709\u6280\u80FD"
25317
25468
  const library2 = new SkillsLibrary(localPath, globalPath);
25318
25469
  const filter = {};
25319
25470
  if (options.tags) {
25320
- filter.tags = options.tags.split(",").map((t) => t.trim());
25471
+ filter.tags = options.tags.split(",").map((t2) => t2.trim());
25321
25472
  }
25322
25473
  if (options.difficulty) {
25323
25474
  filter.difficulty = options.difficulty;
@@ -25362,7 +25513,7 @@ skillsCommand.command("save <path>").description("\u5C06\u6587\u4EF6\u4FDD\u5B58
25362
25513
  const library2 = new SkillsLibrary(join9(projectRoot, config.tools.skills.local_path), config.tools.skills.global_path);
25363
25514
  const content = await Bun.file(filePath).text();
25364
25515
  const name = options.name || basename3(filePath).replace(/\.[^.]+$/, "");
25365
- const tags = options.tags ? options.tags.split(",").map((t) => t.trim()) : ["custom"];
25516
+ const tags = options.tags ? options.tags.split(",").map((t2) => t2.trim()) : ["custom"];
25366
25517
  const skill = {
25367
25518
  metadata: {
25368
25519
  name,
@@ -25893,9 +26044,12 @@ configCommand.command("keys").description("\u5FEB\u901F\u8BBE\u7F6E API \u5BC6\u
25893
26044
  });
25894
26045
  // src/index.ts
25895
26046
  init_errors();
25896
- var VERSION = "1.0.0";
26047
+ var __dirname2 = dirname5(fileURLToPath(import.meta.url));
26048
+ var pkgPath = join12(__dirname2, "../package.json");
26049
+ var pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
26050
+ var VERSION = pkg.version;
25897
26051
  var program2 = new Command;
25898
- program2.name("ax").description(`${source_default.green("\uD83E\uDDE0")} ${source_default.bold("Axon")} - AI-Powered Development Operating System
26052
+ program2.name("ax").description(`${source_default.green("\uD83E\uDDE0")} ${source_default.bold("Axon")} - AI-Powered Development Operating System (v${VERSION})
25899
26053
 
25900
26054
  ${source_default.dim("\u4ECE\u9700\u6C42\u5230\u4EE3\u7801\uFF0C\u8BA9 AI \u6210\u4E3A\u4F60\u7684\u5F00\u53D1\u4F19\u4F34\uFF0C\u800C\u975E\u5DE5\u5177\u3002")}`).version(VERSION, "-v, --version", "\u663E\u793A\u7248\u672C\u53F7").helpOption("-h, --help", "\u663E\u793A\u5E2E\u52A9\u4FE1\u606F");
25901
26055
  program2.addCommand(initCommand);
@@ -25922,7 +26076,7 @@ ${source_default.bold("\u5FEB\u901F\u5F00\u59CB:")}
25922
26076
  4. ${source_default.cyan("ax plan")} \u62C6\u89E3\u4EFB\u52A1
25923
26077
  5. ${source_default.cyan("ax work")} \u5F00\u59CB\u6267\u884C
25924
26078
 
25925
- ${source_default.dim("\u6587\u6863: https://axon.dev/docs")}
26079
+ ${source_default.dim("\u6587\u6863: https://github.com/arrislink/axon")}
25926
26080
  ${source_default.dim("\u95EE\u9898\u53CD\u9988: https://github.com/arrislink/axon/issues")}
25927
26081
  `);
25928
26082
  process.on("uncaughtException", handleError);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arrislink/axon",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "AI-Powered Development Operating System with unified LLM provider support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",