@rnbsolucoes/axion-code 0.1.5 → 0.1.7

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
@@ -31,6 +31,8 @@ axion-code ask "Explique este projeto"
31
31
  axion-code ask --provider openrouter --model google/gemini-2.5-flash-lite "Responda em uma linha"
32
32
  axion-code run --json
33
33
  axion-code doctor --json
34
+ axion-code init --json
35
+ axion-code init --project --json
34
36
  axion-code session list --json
35
37
  axion-code provider list --json
36
38
  axion-code provider profile init
@@ -174,10 +176,39 @@ For test/dev isolation, set `AXION_HOME` to a temporary folder. In normal use,
174
176
  leave it unset so Desktop and CLI share the same provider catalog while keeping
175
177
  their active provider/model selections independent.
176
178
 
179
+ ## Project Bootstrap
180
+
181
+ `axion-code init --json` bootstraps the shared user-level Axion home used by
182
+ Axion Desktop and Axion Code. It creates missing files under
183
+ `%USERPROFILE%\.axion` without overwriting Desktop-owned provider/model state.
184
+
185
+ `axion-code init --project --json` bootstraps the current workspace. The same
186
+ operation is available inside the TUI with `/init`. It creates only missing
187
+ project scaffolding:
188
+
189
+ ```text
190
+ .brv/ local operational memory and PREVC + A learning buffers
191
+ .context/ workflow, plans, tasks, context snapshots and PREVC evidence
192
+ .docs/ project documents, specs, reports and handoff material
193
+ AGENTS.md project-scoped instructions
194
+ CLAUDE.md Claude-compatible project instructions
195
+ .gitignore ignored local runtime, secrets, cache and build-output patterns
196
+ ```
197
+
198
+ If a legacy `docs/` directory exists and `.docs/` does not, project bootstrap
199
+ renames `docs/` to `.docs/`. If both exist, Axion Code leaves both untouched and
200
+ does not attempt an automatic merge.
201
+
202
+ Instruction layering is explicit: shared `%USERPROFILE%\.axion\AGENTS.md`
203
+ contains global Axion Code agent rules, while the workspace root `AGENTS.md`
204
+ contains project-specific rules. Provider runtime prompts read both layers when
205
+ present, plus `CLAUDE.md` as a compatibility surface.
206
+
177
207
  The interactive TUI supports:
178
208
 
179
209
  ```text
180
210
  / inline slash palette
211
+ /init
181
212
  /provider
182
213
  /provider set <profile-id>
183
214
  /model
@@ -195,6 +226,11 @@ Slash palette behavior: `↑/↓` selects, `Tab` completes the selected command,
195
226
 
196
227
  `/learn` consolidates plan-scoped learning from `.brv/plans/<plan-id>` and `.context/learning-candidates*.md`, filters low-signal material, deduplicates by content hash/summary and promotes relevant notes into native dotcontext at `<workspace>/.axion/context`.
197
228
 
229
+ When the active plan comes from `.context/plans/*.md`, `/task add`, `/task done`
230
+ and `/task progress` update the Markdown plan file directly. Axion Code rewrites
231
+ only the target task line marker/progress and keeps the rest of the document
232
+ unchanged.
233
+
198
234
  `/mcp` opens an inline MCP list. Enabled servers can be disabled, disabled servers can be enabled, and non-native servers can be uninstalled while preserving valid `mcp-servers.json` formatting.
199
235
 
200
236
  `/agents` lists the native isolated subagents. `/agents run <id> <prompt>` calls one with an isolated prompt while inheriting the active provider/model from the main agent. The subagent returns findings/action feedback instead of joining the main context by default.
package/npm/bin/axion.mjs CHANGED
@@ -42,15 +42,49 @@ function sourceAvailable() {
42
42
  return existsSync(join(root, "go.mod")) && existsSync(join(root, "cmd", "axion-code"));
43
43
  }
44
44
 
45
+ function sleep(ms) {
46
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
47
+ }
48
+
49
+ function markerMatches(expectedMarker) {
50
+ try {
51
+ return existsSync(exePath) && readFileSync(markerPath, "utf8").trim() === expectedMarker;
52
+ } catch {
53
+ return false;
54
+ }
55
+ }
56
+
57
+ function copyPackagedBinaryWithRetry(expectedMarker) {
58
+ for (let attempt = 0; attempt < 8; attempt += 1) {
59
+ try {
60
+ copyFileSync(packagedExePath, exePath);
61
+ return;
62
+ } catch (error) {
63
+ const retryable = error && (error.code === "EBUSY" || error.code === "EPERM");
64
+ if (!retryable) {
65
+ throw error;
66
+ }
67
+ if (markerMatches(expectedMarker)) {
68
+ return;
69
+ }
70
+ if (attempt === 7) {
71
+ throw error;
72
+ }
73
+ sleep(75 * (attempt + 1));
74
+ }
75
+ }
76
+ }
77
+
45
78
  function installPackagedBinary() {
46
79
  if (!existsSync(packagedExePath)) {
47
80
  return false;
48
81
  }
49
- copyFileSync(packagedExePath, exePath);
82
+ const marker = packagedBinaryMarker();
83
+ copyPackagedBinaryWithRetry(marker);
50
84
  if (!isWindows) {
51
85
  chmodSync(exePath, 0o755);
52
86
  }
53
- writeFileSync(markerPath, `${packagedBinaryMarker()}\n`, "utf8");
87
+ writeFileSync(markerPath, `${marker}\n`, "utf8");
54
88
  return true;
55
89
  }
56
90
 
@@ -197,7 +231,12 @@ async function fetchLatestPackage() {
197
231
  async function readUpdateInfo({ force = false } = {}) {
198
232
  const cached = readJSON(updateCachePath);
199
233
  const now = Date.now();
200
- if (!force && cached?.latestVersion && now - Number(cached.checkedAt || 0) < updateCacheTTL) {
234
+ if (
235
+ !force &&
236
+ cached?.latestVersion &&
237
+ compareVersions(cached.latestVersion, packageJSON.version) >= 0 &&
238
+ now - Number(cached.checkedAt || 0) < updateCacheTTL
239
+ ) {
201
240
  return {
202
241
  currentVersion: packageJSON.version,
203
242
  latestVersion: cached.latestVersion,
@@ -223,13 +262,17 @@ async function readUpdateInfo({ force = false } = {}) {
223
262
  }
224
263
  return info;
225
264
  } catch (error) {
265
+ const usableCachedVersion =
266
+ cached?.latestVersion && compareVersions(cached.latestVersion, packageJSON.version) >= 0
267
+ ? cached.latestVersion
268
+ : "";
226
269
  return {
227
270
  currentVersion: packageJSON.version,
228
- latestVersion: cached?.latestVersion || "",
229
- updateAvailable: cached?.latestVersion ? compareVersions(cached.latestVersion, packageJSON.version) > 0 : false,
271
+ latestVersion: usableCachedVersion,
272
+ updateAvailable: usableCachedVersion ? compareVersions(usableCachedVersion, packageJSON.version) > 0 : false,
230
273
  source: cached?.source || updateSource,
231
274
  checkedAt: cached?.checkedAt || 0,
232
- fromCache: Boolean(cached?.latestVersion),
275
+ fromCache: Boolean(usableCachedVersion),
233
276
  error: error.message
234
277
  };
235
278
  }
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rnbsolucoes/axion-code",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Axion Code CLI harness for the Axion ecosystem.",
5
5
  "type": "module",
6
6
  "repository": {