@inkobytes/nexus 1.0.3 → 1.0.5
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/CHANGELOG.md +8 -1
- package/package.json +1 -1
- package/src/commands/doctor.js +137 -4
- package/src/commands/init.js +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 1.0.
|
|
3
|
+
## 1.0.5 - 2026-06-03
|
|
4
|
+
|
|
5
|
+
- Reframed doctor-managed agent guides around agent-native, file-native release flow instead of human-oriented feature commit bundling.
|
|
6
|
+
- Updated `nexus doctor --fix` and `nexus init` scaffolds to teach release-by-file at coherent checkpoints.
|
|
7
|
+
- Added regression coverage so scaffold generation and repair keep the new agent-native wording stable.
|
|
8
|
+
|
|
9
|
+
## 1.0.4 - 2026-06-03
|
|
4
10
|
|
|
5
11
|
- Collapsed large `nexus doctor` Git Privacy floods into grouped per-root summaries with sample paths.
|
|
6
12
|
- Prioritized `CONTINUITY.md` and `memories/` samples first so agent-local issues stay visible.
|
|
7
13
|
- Collapsed shared agent roots like `.claude/`, `.codex/`, and `.gemini/` into one concise Git Privacy note for repos that intentionally track them.
|
|
8
14
|
- Colorized `nexus doctor` output and grouped findings under clearer action buckets like `Fix the following` and `Review / informational`.
|
|
9
15
|
- Added `.nexus/config.json` support for `doctor.allowTrackedAgentTrees` so intentionally tracked shared agent trees can be treated as informational.
|
|
16
|
+
- Reformatted lock and queue findings into compact field-style output like `file`, `by`, `needs`, `impact`, and shorter `fix` lines.
|
|
10
17
|
|
|
11
18
|
## 1.0.1 - 2026-06-02
|
|
12
19
|
|
package/package.json
CHANGED
package/src/commands/doctor.js
CHANGED
|
@@ -93,8 +93,9 @@ This project uses Nexus for multi-agent coordination.
|
|
|
93
93
|
### Nexus Rules
|
|
94
94
|
|
|
95
95
|
- Claim before editing shared project files: \`nexus claim <path> @Agent "intent"\`.
|
|
96
|
-
- Nexus is agent-native and file-native, not
|
|
97
|
-
-
|
|
96
|
+
- Nexus is agent-native and file-native, not human-native: optimize for concurrency and rollback, not feature-commit aesthetics.
|
|
97
|
+
- Release each claimed file as soon as it reaches a coherent checkpoint.
|
|
98
|
+
- Never hold claims just to bundle a prettier feature commit; that blocks other agents.
|
|
98
99
|
- Release finished work through Nexus: \`nexus release <path> "commit message"\`.
|
|
99
100
|
- Use \`nexus next @Agent\` for the next safe queue task.
|
|
100
101
|
- Do not free-roam into unassigned or \`Auto-flow: no\` work without user approval.
|
|
@@ -521,6 +522,13 @@ export default function doctor(args) {
|
|
|
521
522
|
sections.Locks.push({
|
|
522
523
|
issue: `Stale lock on ${lock.target} (${lock.age}s old)`,
|
|
523
524
|
fix: 'Run `nexus clean --stale`.',
|
|
525
|
+
displayGroup: lock.target,
|
|
526
|
+
lockInfo: {
|
|
527
|
+
target: lock.target,
|
|
528
|
+
agent: lock.agent || '',
|
|
529
|
+
kind: 'stale',
|
|
530
|
+
age: `${lock.age}s old`,
|
|
531
|
+
},
|
|
524
532
|
});
|
|
525
533
|
}
|
|
526
534
|
}
|
|
@@ -532,18 +540,38 @@ export default function doctor(args) {
|
|
|
532
540
|
issue: `Active lock on ${lock.target} (${age})`,
|
|
533
541
|
fix: 'No action if the agent is still working. Use `nexus status` to inspect.',
|
|
534
542
|
ok: true,
|
|
543
|
+
displayGroup: lock.target,
|
|
544
|
+
lockInfo: {
|
|
545
|
+
target: lock.target,
|
|
546
|
+
agent: lock.agent || '',
|
|
547
|
+
kind: 'active',
|
|
548
|
+
age,
|
|
549
|
+
},
|
|
535
550
|
});
|
|
536
551
|
if (!lock.model) {
|
|
537
552
|
sections.Locks.push({
|
|
538
553
|
issue: `Active lock on ${lock.target} has no --model metadata`,
|
|
539
554
|
fix: 'Use `nexus claim ... --model <name>` for future claims; only the human operator can declare the real model.',
|
|
540
555
|
ok: true,
|
|
556
|
+
displayGroup: lock.target,
|
|
557
|
+
lockInfo: {
|
|
558
|
+
target: lock.target,
|
|
559
|
+
agent: lock.agent || '',
|
|
560
|
+
kind: 'missing_model',
|
|
561
|
+
},
|
|
541
562
|
});
|
|
542
563
|
}
|
|
543
564
|
if (!lock.verified) {
|
|
544
565
|
sections.Locks.push({
|
|
545
566
|
issue: `Unverified claim on ${lock.target} by ${lock.agent} (trust: ${lock.trustSource}) — no CLAUDECODE or NEXUS_AGENT env detected at claim time`,
|
|
546
567
|
fix: 'If this is a local/unverified model, set NEXUS_AGENT=@handle before claiming. If unexpected, inspect the lock.',
|
|
568
|
+
displayGroup: lock.target,
|
|
569
|
+
lockInfo: {
|
|
570
|
+
target: lock.target,
|
|
571
|
+
agent: lock.agent || '',
|
|
572
|
+
kind: 'unverified',
|
|
573
|
+
trustSource: lock.trustSource,
|
|
574
|
+
},
|
|
547
575
|
});
|
|
548
576
|
}
|
|
549
577
|
}
|
|
@@ -612,8 +640,15 @@ export default function doctor(args) {
|
|
|
612
640
|
if (unapproved.length) {
|
|
613
641
|
for (const id of unapproved) {
|
|
614
642
|
sections['Queue Authorship'].push({
|
|
615
|
-
issue: `Task "${id}" is
|
|
616
|
-
fix: '
|
|
643
|
+
issue: `Task "${id}" is missing Review: approved`,
|
|
644
|
+
fix: 'add `Review: approved` and `Approved by: human`, or move it to `## Proposed Queue`',
|
|
645
|
+
displayGroup: id,
|
|
646
|
+
queueInfo: {
|
|
647
|
+
taskId: id,
|
|
648
|
+
state: 'auto-flow: yes in Ready Queue',
|
|
649
|
+
needs: 'Review: approved',
|
|
650
|
+
impact: 'nexus next will skip it',
|
|
651
|
+
},
|
|
617
652
|
});
|
|
618
653
|
}
|
|
619
654
|
} else {
|
|
@@ -693,6 +728,14 @@ export default function doctor(args) {
|
|
|
693
728
|
|
|
694
729
|
function renderEntryBucket(label, entries, headingColor, markerColor, sectionTitle, colors) {
|
|
695
730
|
console.log(` ${headingColor(label)}`);
|
|
731
|
+
if (sectionTitle === 'Locks') {
|
|
732
|
+
renderLockEntries(entries, markerColor, colors);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
if (sectionTitle === 'Queue Authorship') {
|
|
736
|
+
renderQueueEntries(entries, markerColor, colors);
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
696
739
|
const groups = groupEntriesForDisplay(entries, sectionTitle);
|
|
697
740
|
for (const group of groups) {
|
|
698
741
|
if (group.label) {
|
|
@@ -715,6 +758,96 @@ function renderEntryBucket(label, entries, headingColor, markerColor, sectionTit
|
|
|
715
758
|
}
|
|
716
759
|
}
|
|
717
760
|
|
|
761
|
+
function renderLockEntries(entries, markerColor, colors) {
|
|
762
|
+
const groups = new Map();
|
|
763
|
+
|
|
764
|
+
for (const entry of entries) {
|
|
765
|
+
const target = entry.lockInfo?.target || entry.displayGroup || entry.issue;
|
|
766
|
+
if (!groups.has(target)) groups.set(target, []);
|
|
767
|
+
groups.get(target).push(entry);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
for (const [target, lockEntries] of groups) {
|
|
771
|
+
const agent = lockEntries.find((entry) => entry.lockInfo?.agent)?.lockInfo?.agent || '';
|
|
772
|
+
console.log(` ${colors.bold(`file: ${target}`)}`);
|
|
773
|
+
console.log(` ${colors.dim(`by: ${agent || 'unknown'}`)}`);
|
|
774
|
+
for (const entry of lockEntries) {
|
|
775
|
+
const prefix = entry.ok ? '-' : '!';
|
|
776
|
+
const state = formatLockState(entry);
|
|
777
|
+
console.log(` ${markerColor(prefix)} ${state}`);
|
|
778
|
+
if (entry.fix) {
|
|
779
|
+
console.log(` ${colors.bold('fix:')} ${colors.dim(compactLockFix(entry))}`);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
function renderQueueEntries(entries, markerColor, colors) {
|
|
786
|
+
const groups = new Map();
|
|
787
|
+
|
|
788
|
+
for (const entry of entries) {
|
|
789
|
+
const taskId = entry.queueInfo?.taskId || entry.displayGroup || entry.issue;
|
|
790
|
+
if (!groups.has(taskId)) groups.set(taskId, []);
|
|
791
|
+
groups.get(taskId).push(entry);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
for (const [taskId, taskEntries] of groups) {
|
|
795
|
+
console.log(` ${colors.bold(`task: ${taskId}`)}`);
|
|
796
|
+
for (const entry of taskEntries) {
|
|
797
|
+
const prefix = entry.ok ? '-' : '!';
|
|
798
|
+
const state = entry.queueInfo?.state || entry.issue;
|
|
799
|
+
const needs = entry.queueInfo?.needs;
|
|
800
|
+
const impact = entry.queueInfo?.impact;
|
|
801
|
+
console.log(` ${markerColor(prefix)} ${state}`);
|
|
802
|
+
if (needs) {
|
|
803
|
+
console.log(` ${colors.dim(`needs: ${needs}`)}`);
|
|
804
|
+
}
|
|
805
|
+
if (impact) {
|
|
806
|
+
console.log(` ${colors.dim(`impact: ${impact}`)}`);
|
|
807
|
+
}
|
|
808
|
+
if (entry.fix) {
|
|
809
|
+
console.log(` ${colors.bold('fix:')} ${colors.dim(entry.fix)}`);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function formatLockState(entry) {
|
|
816
|
+
const info = entry.lockInfo;
|
|
817
|
+
if (!info) return entry.issue;
|
|
818
|
+
|
|
819
|
+
switch (info.kind) {
|
|
820
|
+
case 'stale':
|
|
821
|
+
return `stale lock (${info.age})`;
|
|
822
|
+
case 'active':
|
|
823
|
+
return `active lock (${info.age})`;
|
|
824
|
+
case 'missing_model':
|
|
825
|
+
return 'missing --model metadata';
|
|
826
|
+
case 'unverified':
|
|
827
|
+
return `unverified claim (trust: ${info.trustSource || 'unknown'})`;
|
|
828
|
+
default:
|
|
829
|
+
return entry.issue;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function compactLockFix(entry) {
|
|
834
|
+
const info = entry.lockInfo;
|
|
835
|
+
if (!info) return entry.fix;
|
|
836
|
+
|
|
837
|
+
switch (info.kind) {
|
|
838
|
+
case 'stale':
|
|
839
|
+
return 'run `nexus clean --stale`';
|
|
840
|
+
case 'active':
|
|
841
|
+
return 'leave it if someone is working, or inspect with `nexus status`';
|
|
842
|
+
case 'missing_model':
|
|
843
|
+
return 'use `nexus claim ... --model <name>` on future claims';
|
|
844
|
+
case 'unverified':
|
|
845
|
+
return 'set `NEXUS_AGENT=@handle` for local claims, or inspect the lock';
|
|
846
|
+
default:
|
|
847
|
+
return entry.fix;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
|
|
718
851
|
function groupEntriesForDisplay(entries, sectionTitle) {
|
|
719
852
|
const groups = [];
|
|
720
853
|
const grouped = new Map();
|
package/src/commands/init.js
CHANGED
|
@@ -379,8 +379,9 @@ This project uses Nexus for multi-agent coordination.
|
|
|
379
379
|
### Nexus Rules
|
|
380
380
|
|
|
381
381
|
- Claim before editing shared project files: \`nexus claim <path> @Agent "intent"\`.
|
|
382
|
-
- Nexus is agent-native and file-native, not
|
|
383
|
-
-
|
|
382
|
+
- Nexus is agent-native and file-native, not human-native: optimize for concurrency and rollback, not feature-commit aesthetics.
|
|
383
|
+
- Release each claimed file as soon as it reaches a coherent checkpoint.
|
|
384
|
+
- Never hold claims just to bundle a prettier feature commit; that blocks other agents.
|
|
384
385
|
- Release finished work through Nexus: \`nexus release <path> "commit message"\`.
|
|
385
386
|
- Use \`nexus next @Agent\` for the next safe queue task.
|
|
386
387
|
- Do not free-roam into unassigned or \`Auto-flow: no\` work without user approval.
|