@lamentis/naome 1.2.0 → 1.3.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/Cargo.lock +2 -2
- package/README.md +108 -47
- package/bin/naome-node.js +2 -1579
- package/bin/naome.js +34 -5
- package/crates/naome-cli/Cargo.toml +1 -1
- package/crates/naome-cli/src/dispatcher.rs +7 -2
- package/crates/naome-cli/src/main.rs +37 -22
- package/crates/naome-cli/src/quality_commands.rs +317 -10
- package/crates/naome-cli/src/workflow_commands.rs +21 -1
- package/crates/naome-core/Cargo.toml +1 -1
- package/crates/naome-core/src/decision/checks.rs +64 -0
- package/crates/naome-core/src/decision/idle.rs +67 -0
- package/crates/naome-core/src/decision/json.rs +36 -0
- package/crates/naome-core/src/decision/states.rs +165 -0
- package/crates/naome-core/src/decision.rs +131 -353
- package/crates/naome-core/src/git.rs +4 -2
- package/crates/naome-core/src/install_plan.rs +4 -0
- package/crates/naome-core/src/lib.rs +12 -6
- package/crates/naome-core/src/paths.rs +3 -1
- package/crates/naome-core/src/quality/adapter_support.rs +89 -0
- package/crates/naome-core/src/quality/adapters.rs +20 -67
- package/crates/naome-core/src/quality/baseline.rs +8 -0
- package/crates/naome-core/src/quality/cache.rs +153 -0
- package/crates/naome-core/src/quality/checks/duplicate_blocks.rs +25 -11
- package/crates/naome-core/src/quality/checks/near_duplicates.rs +4 -2
- package/crates/naome-core/src/quality/checks.rs +7 -8
- package/crates/naome-core/src/quality/cleanup.rs +48 -3
- package/crates/naome-core/src/quality/config.rs +8 -15
- package/crates/naome-core/src/quality/config_support.rs +24 -0
- package/crates/naome-core/src/quality/mod.rs +72 -6
- package/crates/naome-core/src/quality/scanner/analysis/normalize.rs +78 -0
- package/crates/naome-core/src/quality/scanner/analysis.rs +160 -0
- package/crates/naome-core/src/quality/scanner/repo_paths.rs +39 -3
- package/crates/naome-core/src/quality/scanner.rs +200 -215
- package/crates/naome-core/src/quality/semantic/checks.rs +134 -0
- package/crates/naome-core/src/quality/semantic/extract.rs +158 -0
- package/crates/naome-core/src/quality/semantic/model.rs +85 -0
- package/crates/naome-core/src/quality/semantic/route.rs +52 -0
- package/crates/naome-core/src/quality/semantic.rs +68 -0
- package/crates/naome-core/src/quality/structure/adapters.rs +84 -0
- package/crates/naome-core/src/quality/structure/checks/basic.rs +153 -0
- package/crates/naome-core/src/quality/structure/checks/directory.rs +134 -0
- package/crates/naome-core/src/quality/structure/checks/pairing.rs +63 -0
- package/crates/naome-core/src/quality/structure/checks.rs +124 -0
- package/crates/naome-core/src/quality/structure/classify/roles.rs +188 -0
- package/crates/naome-core/src/quality/structure/classify.rs +146 -0
- package/crates/naome-core/src/quality/structure/config.rs +89 -0
- package/crates/naome-core/src/quality/structure/defaults.rs +107 -0
- package/crates/naome-core/src/quality/structure/mod.rs +77 -0
- package/crates/naome-core/src/quality/structure/model.rs +131 -0
- package/crates/naome-core/src/quality/types.rs +43 -2
- package/crates/naome-core/src/route/builtin_checks.rs +141 -0
- package/crates/naome-core/src/route/builtin_context.rs +73 -0
- package/crates/naome-core/src/route/builtin_integrity.rs +49 -0
- package/crates/naome-core/src/route/builtin_require.rs +40 -0
- package/crates/naome-core/src/route/context.rs +180 -0
- package/crates/naome-core/src/route/execution.rs +96 -0
- package/crates/naome-core/src/route/execution_baselines.rs +146 -0
- package/crates/naome-core/src/route/execution_support.rs +57 -0
- package/crates/naome-core/src/route/execution_tasks.rs +71 -0
- package/crates/naome-core/src/route/git_ops.rs +72 -0
- package/crates/naome-core/src/route/quality_gate.rs +73 -0
- package/crates/naome-core/src/route/quality_gate_config.rs +126 -0
- package/crates/naome-core/src/route/quality_gate_snapshot.rs +69 -0
- package/crates/naome-core/src/route/worktree.rs +75 -0
- package/crates/naome-core/src/route/worktree_files.rs +32 -0
- package/crates/naome-core/src/route/worktree_plan.rs +131 -0
- package/crates/naome-core/src/route.rs +44 -1217
- package/crates/naome-core/src/verification.rs +1 -0
- package/crates/naome-core/src/workflow/doctor.rs +144 -0
- package/crates/naome-core/src/workflow/mod.rs +2 -0
- package/crates/naome-core/src/workflow/mutation.rs +1 -2
- package/crates/naome-core/tests/decision.rs +24 -118
- package/crates/naome-core/tests/harness_health.rs +2 -0
- package/crates/naome-core/tests/install_plan.rs +2 -0
- package/crates/naome-core/tests/quality.rs +26 -123
- package/crates/naome-core/tests/quality_performance.rs +231 -0
- package/crates/naome-core/tests/quality_structure.rs +116 -0
- package/crates/naome-core/tests/quality_structure_adapters.rs +98 -0
- package/crates/naome-core/tests/quality_structure_policy.rs +144 -0
- package/crates/naome-core/tests/quality_structure_support/mod.rs +249 -0
- package/crates/naome-core/tests/repo_support/mod.rs +16 -0
- package/crates/naome-core/tests/repo_support/repo.rs +113 -0
- package/crates/naome-core/tests/repo_support/repo_factories.rs +99 -0
- package/crates/naome-core/tests/repo_support/repo_helpers.rs +123 -0
- package/crates/naome-core/tests/repo_support/routes.rs +81 -0
- package/crates/naome-core/tests/repo_support/verification.rs +168 -0
- package/crates/naome-core/tests/repo_support/verification_values.rs +135 -0
- package/crates/naome-core/tests/route.rs +1 -1376
- package/crates/naome-core/tests/route_baseline.rs +86 -0
- package/crates/naome-core/tests/route_completion.rs +141 -0
- package/crates/naome-core/tests/route_harness_refresh.rs +135 -0
- package/crates/naome-core/tests/route_user_diff.rs +202 -0
- package/crates/naome-core/tests/route_worktree.rs +54 -0
- package/crates/naome-core/tests/semantic_legacy.rs +140 -0
- package/crates/naome-core/tests/task_state.rs +60 -432
- package/crates/naome-core/tests/task_state_compact_support/repo.rs +1 -1
- package/crates/naome-core/tests/task_state_support/mod.rs +163 -0
- package/crates/naome-core/tests/task_state_support/states.rs +84 -0
- package/crates/naome-core/tests/verification.rs +4 -45
- package/crates/naome-core/tests/verification_contract.rs +22 -78
- package/crates/naome-core/tests/workflow_doctor.rs +24 -0
- package/crates/naome-core/tests/workflow_policy.rs +6 -1
- package/crates/naome-core/tests/workflow_support/mod.rs +1 -1
- package/installer/agents.js +90 -0
- package/installer/context.js +67 -0
- package/installer/filesystem.js +166 -0
- package/installer/flows.js +84 -0
- package/installer/git-boundary.js +171 -0
- package/installer/git-hook-content.js +36 -0
- package/installer/git-hooks.js +134 -0
- package/installer/git-local.js +2 -0
- package/installer/git-shared.js +35 -0
- package/installer/harness-file-ops.js +140 -0
- package/installer/harness-files.js +56 -0
- package/installer/harness-verification.js +123 -0
- package/installer/install-plan.js +66 -0
- package/installer/main.js +25 -0
- package/installer/manifest-state.js +167 -0
- package/installer/native-build.js +24 -0
- package/installer/native-format.js +6 -0
- package/installer/native.js +162 -0
- package/installer/output.js +131 -0
- package/installer/version.js +32 -0
- package/native/darwin-arm64/naome +0 -0
- package/native/linux-x64/naome +0 -0
- package/package.json +2 -1
- package/templates/naome-root/.naome/bin/check-harness-health.js +3 -3
- package/templates/naome-root/.naome/bin/check-task-state.js +3 -3
- package/templates/naome-root/.naome/bin/naome.js +32 -21
- package/templates/naome-root/.naome/manifest.json +5 -3
- package/templates/naome-root/.naome/repository-structure.json +90 -0
- package/templates/naome-root/.naome/verification.json +1 -0
- package/templates/naome-root/.naomeignore +1 -0
- package/templates/naome-root/docs/naome/agent-workflow.md +16 -14
- package/templates/naome-root/docs/naome/index.md +4 -3
- package/templates/naome-root/docs/naome/repository-quality.md +66 -4
- package/templates/naome-root/docs/naome/repository-structure.md +51 -0
- package/templates/naome-root/docs/naome/testing.md +2 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
chmodSync,
|
|
4
|
+
copyFileSync,
|
|
5
|
+
existsSync,
|
|
6
|
+
lstatSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
readFileSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from "node:fs";
|
|
11
|
+
import { dirname, join, resolve } from "node:path";
|
|
12
|
+
|
|
13
|
+
import { hasSymlinkInTargetPath } from "./filesystem.js";
|
|
14
|
+
import { buildNativeDecisionBinary } from "./native-build.js";
|
|
15
|
+
import { formatExpectedIntegrityBlock } from "./native-format.js";
|
|
16
|
+
import { printError } from "./output.js";
|
|
17
|
+
|
|
18
|
+
export function installNativeDecisionBinary(ctx) {
|
|
19
|
+
const targetPath = join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
|
|
20
|
+
|
|
21
|
+
if (hasSymlinkInTargetPath(ctx, ctx.nativeBinaryRelativePath)) {
|
|
22
|
+
ctx.skipped.push(ctx.nativeBinaryRelativePath);
|
|
23
|
+
ctx.unsafeSkipped.push(ctx.nativeBinaryRelativePath);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const sourcePath = findNativeDecisionBinary(ctx);
|
|
28
|
+
if (!sourcePath) {
|
|
29
|
+
printError(ctx, "NAOME native decision binary is unavailable.");
|
|
30
|
+
console.error("Install Cargo or provide NAOME_NATIVE_BIN with a built naome binary, then rerun naome sync.");
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (usesSourceNativeFallback(ctx)) {
|
|
35
|
+
patchNaomeCommandNativeIntegrity(ctx, "sha256:generated");
|
|
36
|
+
ctx.skipped.push(ctx.nativeBinaryRelativePath);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
41
|
+
const sourceHash = sha256(readFileSync(sourcePath));
|
|
42
|
+
const targetHash =
|
|
43
|
+
existsSync(targetPath) && lstatSync(targetPath).isFile()
|
|
44
|
+
? sha256(readFileSync(targetPath))
|
|
45
|
+
: null;
|
|
46
|
+
|
|
47
|
+
if (sourceHash !== targetHash) {
|
|
48
|
+
copyFileSync(sourcePath, targetPath);
|
|
49
|
+
ctx.updated.push(ctx.nativeBinaryRelativePath);
|
|
50
|
+
} else {
|
|
51
|
+
ctx.skipped.push(ctx.nativeBinaryRelativePath);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
chmodSync(targetPath, 0o755);
|
|
55
|
+
patchNaomeCommandNativeIntegrity(ctx, `sha256:${sourceHash}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function findNativeDecisionBinary(ctx) {
|
|
59
|
+
const candidates = [];
|
|
60
|
+
|
|
61
|
+
if (process.env.NAOME_NATIVE_BIN) {
|
|
62
|
+
candidates.push(resolve(ctx.targetRoot, process.env.NAOME_NATIVE_BIN));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
candidates.push(join(ctx.packageRoot, "native", `${process.platform}-${process.arch}`, ctx.nativeBinaryName));
|
|
66
|
+
candidates.push(join(ctx.packageRoot, "target", "release", ctx.nativeBinaryName));
|
|
67
|
+
|
|
68
|
+
for (const candidate of candidates) {
|
|
69
|
+
if (existsSync(candidate) && lstatSync(candidate).isFile()) {
|
|
70
|
+
return candidate;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return buildNativeDecisionBinary(ctx);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function patchInstalledMachineOwnedIntegrity(ctx) {
|
|
78
|
+
const integrityBlock = formatExpectedIntegrityBlock(templateIntegrity(ctx));
|
|
79
|
+
|
|
80
|
+
for (const relativePath of [ctx.healthCheckerRelativePath, ctx.taskStateCheckerRelativePath]) {
|
|
81
|
+
const targetPath = join(ctx.targetRoot, relativePath);
|
|
82
|
+
if (!existsSync(targetPath) || hasSymlinkInTargetPath(ctx, relativePath)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const content = readFileSync(targetPath, "utf8");
|
|
87
|
+
const nextContent = content.replace(ctx.integrityBlockPattern, integrityBlock);
|
|
88
|
+
if (nextContent !== content) {
|
|
89
|
+
writeFileSync(targetPath, nextContent);
|
|
90
|
+
ctx.updated.push(relativePath);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function usesSourceNativeFallback(ctx) {
|
|
96
|
+
return existsSync(join(ctx.targetRoot, "packages", "naome", "Cargo.toml"))
|
|
97
|
+
&& existsSync(join(ctx.targetRoot, "packages", "naome", "crates", "naome-cli", "src", "main.rs"));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function installedNativeBinaryHash(ctx) {
|
|
101
|
+
const targetPath = join(ctx.targetRoot, ctx.nativeBinaryRelativePath);
|
|
102
|
+
if (
|
|
103
|
+
!existsSync(targetPath) ||
|
|
104
|
+
hasSymlinkInTargetPath(ctx, ctx.nativeBinaryRelativePath) ||
|
|
105
|
+
!lstatSync(targetPath).isFile()
|
|
106
|
+
) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return sha256(readFileSync(targetPath));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function templateIntegrity(ctx) {
|
|
114
|
+
const integrity = {};
|
|
115
|
+
|
|
116
|
+
for (const relativePath of ctx.machineOwnedPaths) {
|
|
117
|
+
const sourcePath = join(ctx.templateRoot, relativePath);
|
|
118
|
+
integrity[relativePath] = `sha256:${machineFileHash(ctx, relativePath, readFileSync(sourcePath))}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return integrity;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function sha256(content) {
|
|
125
|
+
return createHash("sha256").update(content).digest("hex");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function machineFileHash(ctx, relativePath, content) {
|
|
129
|
+
let normalized = content;
|
|
130
|
+
|
|
131
|
+
if (hasGeneratedIntegrity(ctx, relativePath)) {
|
|
132
|
+
normalized = normalized.toString("utf8").replace(ctx.integrityBlockPattern, ctx.normalizedIntegrityBlock);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (relativePath === ctx.naomeCommandRelativePath) {
|
|
136
|
+
normalized = normalized.toString("utf8").replace(ctx.nativeIntegrityPattern, ctx.normalizedNativeIntegrity);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return sha256(normalized);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function hasGeneratedIntegrity(ctx, relativePath) {
|
|
143
|
+
return relativePath === ctx.healthCheckerRelativePath || relativePath === ctx.taskStateCheckerRelativePath;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function patchNaomeCommandNativeIntegrity(ctx, expectedIntegrity) {
|
|
147
|
+
const commandPath = join(ctx.targetRoot, ctx.naomeCommandRelativePath);
|
|
148
|
+
if (!existsSync(commandPath) || hasSymlinkInTargetPath(ctx, ctx.naomeCommandRelativePath)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const content = readFileSync(commandPath, "utf8");
|
|
153
|
+
const nextContent = content.replace(
|
|
154
|
+
ctx.nativeIntegrityPattern,
|
|
155
|
+
`const expectedNativeBinaryIntegrity = "${expectedIntegrity}";\n`,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
if (nextContent !== content) {
|
|
159
|
+
writeFileSync(commandPath, nextContent);
|
|
160
|
+
ctx.updated.push(ctx.naomeCommandRelativePath);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
export function printHeader(ctx) {
|
|
5
|
+
console.log("");
|
|
6
|
+
console.log(`${ctx.color.bold("NAOME")} ${ctx.color.dim(`v${ctx.packageVersion}`)}`);
|
|
7
|
+
console.log(ctx.color.dim("AI coding-agent harness installer"));
|
|
8
|
+
console.log("");
|
|
9
|
+
console.log(`${ctx.color.dim("target ")} ${ctx.targetRoot}`);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function printSection(ctx, title) {
|
|
13
|
+
console.log("");
|
|
14
|
+
console.log(ctx.color.bold(title));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function printList(ctx, items, marker) {
|
|
18
|
+
for (const item of uniqueStrings(items)) {
|
|
19
|
+
console.log(`${ctx.color.dim(marker)} ${item}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function uniqueStrings(items) {
|
|
24
|
+
return Array.from(new Set(items));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function printError(ctx, message) {
|
|
28
|
+
console.error("");
|
|
29
|
+
console.error(`${ctx.color.red("x")} ${message}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function printCancelled(ctx, message) {
|
|
33
|
+
console.log("");
|
|
34
|
+
console.log(`${ctx.color.yellow("-")} ${message}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function printCommandFailure(ctx, message, result) {
|
|
38
|
+
printError(ctx, message);
|
|
39
|
+
if (result.stdout.trim()) {
|
|
40
|
+
console.error(result.stdout.trim());
|
|
41
|
+
}
|
|
42
|
+
if (result.stderr.trim()) {
|
|
43
|
+
console.error(result.stderr.trim());
|
|
44
|
+
}
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function printSummary(ctx, existingInstall) {
|
|
49
|
+
console.log("");
|
|
50
|
+
console.log(`${ctx.color.green("+")} ${ctx.summaryTitle}`);
|
|
51
|
+
|
|
52
|
+
const detailedOutput = shouldPrintDetailedSummary(ctx, existingInstall);
|
|
53
|
+
if (!detailedOutput) {
|
|
54
|
+
printCompactSummary(ctx);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
printDetailedSummary(ctx, detailedOutput);
|
|
58
|
+
if (ctx.unsafeSkipped.length > 0) {
|
|
59
|
+
printSection(ctx, "Skipped unsafe symlinked paths");
|
|
60
|
+
printList(ctx, ctx.unsafeSkipped, "!");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (isRepositoryInitialized(ctx)) {
|
|
64
|
+
console.log("");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
printSection(ctx, "Next step");
|
|
69
|
+
console.log("Copy this into your coding agent:");
|
|
70
|
+
console.log("");
|
|
71
|
+
console.log(ctx.color.dim("```"));
|
|
72
|
+
console.log(ctx.nextStepPrompt);
|
|
73
|
+
console.log(ctx.color.dim("```"));
|
|
74
|
+
console.log("");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function printDetailedSummary(ctx, detailedOutput) {
|
|
78
|
+
if (detailedOutput && ctx.installed.length > 0) {
|
|
79
|
+
const items = uniqueStrings(ctx.installed);
|
|
80
|
+
printSection(ctx, `Installed ${items.length} ${items.length === 1 ? "item" : "items"}`);
|
|
81
|
+
printList(ctx, ctx.installed, "+");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (detailedOutput && ctx.updated.length > 0) {
|
|
85
|
+
const items = uniqueStrings(ctx.updated);
|
|
86
|
+
printSection(ctx, `Updated ${items.length} ${items.length === 1 ? "item" : "items"}`);
|
|
87
|
+
printList(ctx, ctx.updated, "~");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (detailedOutput && ctx.archived.length > 0) {
|
|
91
|
+
printSection(ctx, "Archived");
|
|
92
|
+
for (const entry of ctx.archived) {
|
|
93
|
+
console.log(`${ctx.color.dim(">")} ${entry.from} -> ${entry.to}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (detailedOutput && ctx.skipped.length > 0) {
|
|
98
|
+
const items = uniqueStrings(ctx.skipped);
|
|
99
|
+
printSection(ctx, `Skipped ${items.length} existing ${items.length === 1 ? "path" : "paths"}`);
|
|
100
|
+
printList(ctx, ctx.skipped, "-");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function shouldPrintDetailedSummary(ctx, existingInstall) {
|
|
105
|
+
return ctx.verboseOutput || !existingInstall;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function printCompactSummary(ctx) {
|
|
109
|
+
const installedCount = uniqueStrings(ctx.installed).length;
|
|
110
|
+
const updatedCount = uniqueStrings(ctx.updated).length;
|
|
111
|
+
const archivedCount = ctx.archived.length;
|
|
112
|
+
|
|
113
|
+
if (installedCount > 0) {
|
|
114
|
+
console.log(`${ctx.color.dim("installed")} ${installedCount}`);
|
|
115
|
+
}
|
|
116
|
+
if (updatedCount > 0) {
|
|
117
|
+
console.log(`${ctx.color.dim("updated")} ${updatedCount}`);
|
|
118
|
+
}
|
|
119
|
+
if (archivedCount > 0) {
|
|
120
|
+
console.log(`${ctx.color.dim("archived")} ${archivedCount}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isRepositoryInitialized(ctx) {
|
|
125
|
+
try {
|
|
126
|
+
const initState = JSON.parse(readFileSync(join(ctx.targetRoot, ".naome", "init-state.json"), "utf8"));
|
|
127
|
+
return initState.initialized === true;
|
|
128
|
+
} catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { printError } from "./output.js";
|
|
2
|
+
|
|
3
|
+
export function compareVersions(ctx, left, right) {
|
|
4
|
+
const leftParts = parseVersion(ctx, left);
|
|
5
|
+
const rightParts = parseVersion(ctx, right);
|
|
6
|
+
|
|
7
|
+
for (let index = 0; index < 3; index += 1) {
|
|
8
|
+
if (leftParts[index] > rightParts[index]) {
|
|
9
|
+
return 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (leftParts[index] < rightParts[index]) {
|
|
13
|
+
return -1;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function isVersion(version) {
|
|
21
|
+
return typeof version === "string" && /^\d+\.\d+\.\d+$/.test(version);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function parseVersion(ctx, version) {
|
|
25
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
|
|
26
|
+
if (!match) {
|
|
27
|
+
printError(ctx, `Invalid NAOME version: ${version}`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return match.slice(1).map((part) => Number.parseInt(part, 10));
|
|
32
|
+
}
|
|
Binary file
|
package/native/linux-x64/naome
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lamentis/naome",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Native-first CLI for the NAOME agent harness.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"Cargo.lock",
|
|
32
32
|
"Cargo.toml",
|
|
33
33
|
"crates",
|
|
34
|
+
"installer",
|
|
34
35
|
"native",
|
|
35
36
|
"templates",
|
|
36
37
|
"README.md"
|
|
@@ -11,14 +11,14 @@ const nativeBinaryName = process.platform === "win32" ? "naome.exe" : "naome";
|
|
|
11
11
|
const expectedMachineOwnedIntegrity = Object.freeze({
|
|
12
12
|
".naome/bin/check-harness-health.js": "sha256:dc4de52b79c69600b9ba47b924e2c2b8de61a2cbfab6d1ccc0f1924d963db657",
|
|
13
13
|
".naome/bin/check-task-state.js": "sha256:43c02868072d0d13499aefba2e9a5ec9517d59539fd19ff0f11e3e4623a51b44",
|
|
14
|
-
".naome/bin/naome.js": "sha256:
|
|
14
|
+
".naome/bin/naome.js": "sha256:3d2edd9cf7b04ffb8845db2c55ce1b9c243bd3aba112f53af4af3c11fae5b8e1",
|
|
15
15
|
".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
|
|
16
16
|
".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
|
|
17
17
|
"AGENTS.md": "sha256:9192ea81f90bb19f8043513c49b5da9e9598ee694da8356f345e7ccbca0e28df",
|
|
18
|
-
"docs/naome/agent-workflow.md": "sha256:
|
|
18
|
+
"docs/naome/agent-workflow.md": "sha256:97788255e26282ca1b7fcaaf86c9408c9040246727e3de96b4126fcb68c10b38",
|
|
19
19
|
"docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
|
|
20
20
|
"docs/naome/first-run.md": "sha256:a1dd0bd17ec9d71955a473cd2c4a615538e89a7d81e8f4e1015a50ab9efe3558",
|
|
21
|
-
"docs/naome/index.md": "sha256:
|
|
21
|
+
"docs/naome/index.md": "sha256:a674102cc801702dc77102afb59be0f5ab189dc638caf0bef358b9d6087d0742",
|
|
22
22
|
"docs/naome/upgrade.md": "sha256:2c60f0441bbd98bd528d109b30a7ded4b0ad55d61ffb9f52edac9e93b7999cb1"
|
|
23
23
|
});
|
|
24
24
|
|
|
@@ -11,14 +11,14 @@ const nativeBinaryName = process.platform === "win32" ? "naome.exe" : "naome";
|
|
|
11
11
|
const expectedMachineOwnedIntegrity = Object.freeze({
|
|
12
12
|
".naome/bin/check-harness-health.js": "sha256:dc4de52b79c69600b9ba47b924e2c2b8de61a2cbfab6d1ccc0f1924d963db657",
|
|
13
13
|
".naome/bin/check-task-state.js": "sha256:43c02868072d0d13499aefba2e9a5ec9517d59539fd19ff0f11e3e4623a51b44",
|
|
14
|
-
".naome/bin/naome.js": "sha256:
|
|
14
|
+
".naome/bin/naome.js": "sha256:3d2edd9cf7b04ffb8845db2c55ce1b9c243bd3aba112f53af4af3c11fae5b8e1",
|
|
15
15
|
".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
|
|
16
16
|
".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
|
|
17
17
|
"AGENTS.md": "sha256:9192ea81f90bb19f8043513c49b5da9e9598ee694da8356f345e7ccbca0e28df",
|
|
18
|
-
"docs/naome/agent-workflow.md": "sha256:
|
|
18
|
+
"docs/naome/agent-workflow.md": "sha256:97788255e26282ca1b7fcaaf86c9408c9040246727e3de96b4126fcb68c10b38",
|
|
19
19
|
"docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
|
|
20
20
|
"docs/naome/first-run.md": "sha256:a1dd0bd17ec9d71955a473cd2c4a615538e89a7d81e8f4e1015a50ab9efe3558",
|
|
21
|
-
"docs/naome/index.md": "sha256:
|
|
21
|
+
"docs/naome/index.md": "sha256:a674102cc801702dc77102afb59be0f5ab189dc638caf0bef358b9d6087d0742",
|
|
22
22
|
"docs/naome/upgrade.md": "sha256:2c60f0441bbd98bd528d109b30a7ded4b0ad55d61ffb9f52edac9e93b7999cb1"
|
|
23
23
|
});
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ function main(argv) {
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
if (["status", "next", "intent", "route", "explain", "quality", "cleanup", "refresh-integrity", "workflow"].includes(command)) {
|
|
30
|
+
if (["status", "next", "intent", "route", "explain", "doctor", "quality", "semantic", "structure", "cleanup", "refresh-integrity", "workflow"].includes(command)) {
|
|
31
31
|
runNativeDecisionCommand(command, args);
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
@@ -349,26 +349,37 @@ function findAncestorWithMarker(startPath, markerParts) {
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
function printHelp() {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
352
|
+
const commands = [
|
|
353
|
+
"naome status [--json]",
|
|
354
|
+
"naome next [--json]",
|
|
355
|
+
"naome intent --prompt-file <path> [--json]",
|
|
356
|
+
"naome intent --prompt <text> [--json]",
|
|
357
|
+
"naome route --prompt-file <path> [--execute] [--json]",
|
|
358
|
+
"naome route --prompt <text> [--execute] [--json]",
|
|
359
|
+
"naome explain --prompt-file <path> [--json]",
|
|
360
|
+
"naome explain --prompt <text> [--json]",
|
|
361
|
+
"naome doctor [--json]",
|
|
362
|
+
"naome quality init [--baseline|--deep-baseline] [--json]",
|
|
363
|
+
"naome quality check --changed [--include-scanned-paths] [--json]",
|
|
364
|
+
"naome quality report [--deep] [--include-scanned-paths] [--json]",
|
|
365
|
+
"naome quality cache status [--json]",
|
|
366
|
+
"naome quality cache clear",
|
|
367
|
+
"naome semantic report [--deep] [--json]",
|
|
368
|
+
"naome semantic check --changed [--json]",
|
|
369
|
+
"naome semantic route --finding <id> [--json]",
|
|
370
|
+
"naome semantic loop [--json]",
|
|
371
|
+
"naome structure report [--json]",
|
|
372
|
+
"naome structure explain --path <path> [--json]",
|
|
373
|
+
"naome cleanup plan [--json]",
|
|
374
|
+
"naome cleanup route --path <path> [--json]",
|
|
375
|
+
"naome refresh-integrity [--json]",
|
|
376
|
+
"naome workflow search-profile|check-search|phases|processes|mutations [--json]",
|
|
377
|
+
"naome install",
|
|
378
|
+
"naome sync",
|
|
379
|
+
"naome commit -m \"type(scope): message\"",
|
|
380
|
+
"node .naome/bin/naome.js commit -m \"type(scope): message\""
|
|
381
|
+
];
|
|
382
|
+
console.log(["Usage:", ...commands.map((command) => ` ${command}`)].join("\n"));
|
|
372
383
|
}
|
|
373
384
|
|
|
374
385
|
function fail(message) {
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
"integrity": {
|
|
5
5
|
".naome/bin/check-harness-health.js": "sha256:dc4de52b79c69600b9ba47b924e2c2b8de61a2cbfab6d1ccc0f1924d963db657",
|
|
6
6
|
".naome/bin/check-task-state.js": "sha256:43c02868072d0d13499aefba2e9a5ec9517d59539fd19ff0f11e3e4623a51b44",
|
|
7
|
-
".naome/bin/naome.js": "sha256:
|
|
7
|
+
".naome/bin/naome.js": "sha256:3d2edd9cf7b04ffb8845db2c55ce1b9c243bd3aba112f53af4af3c11fae5b8e1",
|
|
8
8
|
".naome/package.json": "sha256:8005a3491db7d92f36ac66369861589f9c47123d3a7c71e643fc2c06168cd45a",
|
|
9
9
|
".naome/task-contract.schema.json": "sha256:1b3b62350328d0d6d660e36d1d1baaa2b88718530db774f9ab2a9e2fcba369c8",
|
|
10
10
|
"AGENTS.md": "sha256:9192ea81f90bb19f8043513c49b5da9e9598ee694da8356f345e7ccbca0e28df",
|
|
11
|
-
"docs/naome/agent-workflow.md": "sha256:
|
|
11
|
+
"docs/naome/agent-workflow.md": "sha256:97788255e26282ca1b7fcaaf86c9408c9040246727e3de96b4126fcb68c10b38",
|
|
12
12
|
"docs/naome/execution.md": "sha256:bfc5d55838942ec8e3d790b59e3c634ff5bf6a2298265cef3dca9788a097eafb",
|
|
13
13
|
"docs/naome/first-run.md": "sha256:a1dd0bd17ec9d71955a473cd2c4a615538e89a7d81e8f4e1015a50ab9efe3558",
|
|
14
|
-
"docs/naome/index.md": "sha256:
|
|
14
|
+
"docs/naome/index.md": "sha256:a674102cc801702dc77102afb59be0f5ab189dc638caf0bef358b9d6087d0742",
|
|
15
15
|
"docs/naome/upgrade.md": "sha256:2c60f0441bbd98bd528d109b30a7ded4b0ad55d61ffb9f52edac9e93b7999cb1"
|
|
16
16
|
},
|
|
17
17
|
"machineOwned": [
|
|
@@ -37,11 +37,13 @@
|
|
|
37
37
|
".naome/upgrade-state.json",
|
|
38
38
|
".naome/verification.json",
|
|
39
39
|
".naome/repository-quality.json",
|
|
40
|
+
".naome/repository-structure.json",
|
|
40
41
|
".naome/repository-quality-baseline.json",
|
|
41
42
|
"docs/naome/architecture.md",
|
|
42
43
|
"docs/naome/decisions.md",
|
|
43
44
|
"docs/naome/repo-profile.md",
|
|
44
45
|
"docs/naome/repository-quality.md",
|
|
46
|
+
"docs/naome/repository-structure.md",
|
|
45
47
|
"docs/naome/security.md",
|
|
46
48
|
"docs/naome/testing.md"
|
|
47
49
|
]
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "naome.repository-structure.v1",
|
|
3
|
+
"version": 1,
|
|
4
|
+
"status": "ready",
|
|
5
|
+
"enabledAdapters": [],
|
|
6
|
+
"sourceRoots": [
|
|
7
|
+
"src/**",
|
|
8
|
+
"app/**",
|
|
9
|
+
"apps/*/src/**",
|
|
10
|
+
"packages/*/src/**",
|
|
11
|
+
"crates/*/src/**",
|
|
12
|
+
"**/src/**",
|
|
13
|
+
"lib/**"
|
|
14
|
+
],
|
|
15
|
+
"testRoots": [
|
|
16
|
+
"test/**",
|
|
17
|
+
"tests/**",
|
|
18
|
+
"__tests__/**",
|
|
19
|
+
"packages/*/test/**",
|
|
20
|
+
"packages/*/tests/**",
|
|
21
|
+
"crates/*/tests/**",
|
|
22
|
+
"**/tests/**",
|
|
23
|
+
"scripts/*.test.js"
|
|
24
|
+
],
|
|
25
|
+
"docsRoots": [
|
|
26
|
+
"docs/**",
|
|
27
|
+
"doc/**"
|
|
28
|
+
],
|
|
29
|
+
"generatedRoots": [
|
|
30
|
+
"**/generated/**",
|
|
31
|
+
"**/__generated__/**",
|
|
32
|
+
"**/codegen/**",
|
|
33
|
+
"**/*.generated.*"
|
|
34
|
+
],
|
|
35
|
+
"artifactRoots": [
|
|
36
|
+
"dist/**",
|
|
37
|
+
"build/**",
|
|
38
|
+
"coverage/**",
|
|
39
|
+
".next/**",
|
|
40
|
+
"target/**",
|
|
41
|
+
"**/dist/**",
|
|
42
|
+
"**/build/**"
|
|
43
|
+
],
|
|
44
|
+
"moduleRoots": [
|
|
45
|
+
"src/**",
|
|
46
|
+
"app/**",
|
|
47
|
+
"packages/*/src/**",
|
|
48
|
+
"crates/*/src/**",
|
|
49
|
+
"**/src/**"
|
|
50
|
+
],
|
|
51
|
+
"allowedRootFiles": [
|
|
52
|
+
"README.md",
|
|
53
|
+
"LICENSE",
|
|
54
|
+
"NOTICE",
|
|
55
|
+
"CHANGELOG.md",
|
|
56
|
+
"CONTRIBUTING.md",
|
|
57
|
+
"SECURITY.md",
|
|
58
|
+
"AGENTS.md",
|
|
59
|
+
"package.json",
|
|
60
|
+
"Cargo.toml",
|
|
61
|
+
"pyproject.toml",
|
|
62
|
+
"go.mod",
|
|
63
|
+
"go.sum",
|
|
64
|
+
"Makefile",
|
|
65
|
+
".gitignore",
|
|
66
|
+
".naomeignore"
|
|
67
|
+
],
|
|
68
|
+
"directoryRoleRules": [],
|
|
69
|
+
"layerRules": [],
|
|
70
|
+
"ignoredPaths": [
|
|
71
|
+
".git/**",
|
|
72
|
+
"node_modules/**",
|
|
73
|
+
"vendor/**",
|
|
74
|
+
"target/**",
|
|
75
|
+
"**/target/**",
|
|
76
|
+
"dist/**",
|
|
77
|
+
"build/**",
|
|
78
|
+
"coverage/**",
|
|
79
|
+
".next/**"
|
|
80
|
+
],
|
|
81
|
+
"disabledChecks": [],
|
|
82
|
+
"changedCodePolicy": "block",
|
|
83
|
+
"debtPolicy": "report",
|
|
84
|
+
"limits": {
|
|
85
|
+
"maxDirectoryFiles": 40,
|
|
86
|
+
"maxPathDepth": 10,
|
|
87
|
+
"maxDirectoryRoles": 2,
|
|
88
|
+
"maxDumpingGroundFiles": 12
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -20,37 +20,39 @@ Use this workflow after first-run intake is complete.
|
|
|
20
20
|
debugging why a policy won.
|
|
21
21
|
4. Run `node .naome/bin/naome.js status --json` when reporting state without
|
|
22
22
|
routing a new request.
|
|
23
|
-
5. Run `node .naome/bin/
|
|
24
|
-
|
|
23
|
+
5. Run `node .naome/bin/naome.js doctor --json` when state is unclear or a
|
|
24
|
+
gate blocks unexpectedly; use its `nextAction` as the first diagnostic.
|
|
25
|
+
6. Run `node .naome/bin/check-harness-health.js`.
|
|
26
|
+
7. If harness health fails, do not start new feature work. Ask the user to
|
|
25
27
|
choose `repair_harness`, `review_harness_diff`, or
|
|
26
28
|
`cancel_repair_baseline`.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
8. Run `node .naome/bin/check-task-state.js --admission`.
|
|
30
|
+
9. If task admission fails for a natural-language work request, use
|
|
29
31
|
`naome route --execute --json`. Route may baseline valid completed setup or
|
|
30
32
|
task diffs, create an isolated task worktree around unrelated user edits,
|
|
31
33
|
baseline pure harness refreshes in the current worktree, and rerun
|
|
32
34
|
admission. Ask the user only when `humanOptions` is non-empty,
|
|
33
35
|
route blocks as unsafe/ambiguous, or automatic baselining fails.
|
|
34
|
-
|
|
36
|
+
10. If route blocks or returns no mutation, do not use raw `git commit`, IDE
|
|
35
37
|
commit, `git add`, or hook bypass commands as a fallback. Unowned changes
|
|
36
38
|
are user-owned unless NAOME route explicitly isolates around them or
|
|
37
39
|
baselines a deterministic harness/task diff. If the user explicitly asks to
|
|
38
40
|
commit their own unowned changes, route must run the configured quality gate
|
|
39
41
|
first, require committed verification coverage for every path, and commit
|
|
40
42
|
only the final stabilized paths it evaluated.
|
|
41
|
-
|
|
43
|
+
11. Record the passed admission check in `.naome/task-state.json` when starting
|
|
42
44
|
the task.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
12. Restate the task in concrete terms.
|
|
46
|
+
13. Read `.naomeignore`.
|
|
47
|
+
14. Exclude every path matched by `.naomeignore` from context gathering.
|
|
48
|
+
15. For broad searches, use `node .naome/bin/naome.js workflow search-profile`
|
|
47
49
|
or equivalent excludes for `.git`, `.naome/archive`, dependencies, build
|
|
48
50
|
outputs, caches, and `.naomeignore` paths.
|
|
49
|
-
|
|
51
|
+
16. Read only the `requiredContext` returned by route/status plus the smallest
|
|
50
52
|
task-relevant NAOME docs.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
17. Inspect the existing code or docs before proposing changes.
|
|
54
|
+
18. Read `testing.md` and `.naome/verification.json`.
|
|
55
|
+
19. Identify the required proof before claiming success.
|
|
54
56
|
|
|
55
57
|
## Instruction Boundaries
|
|
56
58
|
|
|
@@ -18,9 +18,10 @@ for the current step.
|
|
|
18
18
|
11. `testing.md`
|
|
19
19
|
12. `.naome/verification.json`
|
|
20
20
|
13. `repository-quality.md`, when repository-quality checks or cleanup are relevant
|
|
21
|
-
14. `
|
|
22
|
-
15. `
|
|
23
|
-
16. `
|
|
21
|
+
14. `repository-structure.md`, when path roles or structure cleanup are relevant
|
|
22
|
+
15. `security.md`
|
|
23
|
+
16. `agent-workflow.md`
|
|
24
|
+
17. `decisions.md`, when changing durable project policy
|
|
24
25
|
|
|
25
26
|
## Source Types
|
|
26
27
|
|