@lamentis/naome 1.3.0 → 1.3.2
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 +11 -2
- package/bin/naome.js +62 -24
- package/crates/naome-cli/Cargo.toml +1 -1
- package/crates/naome-cli/src/context_commands.rs +47 -0
- package/crates/naome-cli/src/dispatcher.rs +6 -0
- package/crates/naome-cli/src/main.rs +43 -6
- package/crates/naome-cli/src/quality_commands.rs +31 -46
- package/crates/naome-cli/src/quality_output.rs +34 -0
- package/crates/naome-cli/src/quality_reconcile_command.rs +45 -0
- package/crates/naome-cli/src/repository_model_commands.rs +84 -0
- package/crates/naome-cli/src/task_commands.rs +62 -0
- package/crates/naome-cli/src/workflow_commands.rs +100 -3
- package/crates/naome-core/Cargo.toml +1 -1
- package/crates/naome-core/src/context/helpers.rs +75 -0
- package/crates/naome-core/src/context/select.rs +134 -0
- package/crates/naome-core/src/context/types.rs +43 -0
- package/crates/naome-core/src/context.rs +6 -0
- package/crates/naome-core/src/decision/states.rs +1 -1
- package/crates/naome-core/src/decision.rs +4 -1
- package/crates/naome-core/src/install_plan.rs +18 -0
- package/crates/naome-core/src/intent/resolver_catalog/active.rs +38 -0
- package/crates/naome-core/src/intent/resolver_catalog/baseline.rs +44 -0
- package/crates/naome-core/src/intent/resolver_catalog/completed.rs +56 -0
- package/crates/naome-core/src/intent/resolver_catalog/dirty.rs +32 -0
- package/crates/naome-core/src/intent/resolver_catalog/ready.rs +32 -0
- package/crates/naome-core/src/intent/resolver_catalog/system.rs +20 -0
- package/crates/naome-core/src/intent/resolver_catalog.rs +12 -166
- package/crates/naome-core/src/journal.rs +2 -7
- package/crates/naome-core/src/lib.rs +33 -10
- package/crates/naome-core/src/quality/adapter_ios.rs +131 -0
- package/crates/naome-core/src/quality/adapter_support.rs +67 -0
- package/crates/naome-core/src/quality/adapters.rs +81 -18
- package/crates/naome-core/src/quality/cache.rs +7 -9
- package/crates/naome-core/src/quality/checks/duplicate_blocks.rs +4 -7
- package/crates/naome-core/src/quality/config.rs +21 -3
- package/crates/naome-core/src/quality/mod.rs +138 -7
- package/crates/naome-core/src/quality/reconcile.rs +138 -0
- package/crates/naome-core/src/quality/reconcile_anchors.rs +64 -0
- package/crates/naome-core/src/quality/scanner/analysis.rs +20 -5
- package/crates/naome-core/src/quality/scanner.rs +62 -17
- package/crates/naome-core/src/quality/semantic/checks.rs +17 -0
- package/crates/naome-core/src/quality/semantic/route.rs +1 -1
- package/crates/naome-core/src/quality/structure/adapter_ios.rs +149 -0
- package/crates/naome-core/src/quality/structure/adapters.rs +60 -42
- package/crates/naome-core/src/quality/structure/checks/directory.rs +6 -4
- package/crates/naome-core/src/quality/structure/classify/roles.rs +51 -5
- package/crates/naome-core/src/quality/structure/config.rs +24 -3
- package/crates/naome-core/src/quality/structure/mod.rs +3 -0
- package/crates/naome-core/src/quality/types.rs +20 -1
- package/crates/naome-core/src/repository_model/detect.rs +188 -0
- package/crates/naome-core/src/repository_model/explain.rs +121 -0
- package/crates/naome-core/src/repository_model/path_scan.rs +67 -0
- package/crates/naome-core/src/repository_model/path_support.rs +59 -0
- package/crates/naome-core/src/repository_model/types.rs +152 -0
- package/crates/naome-core/src/repository_model/world.rs +48 -0
- package/crates/naome-core/src/repository_model/world_adapters.rs +145 -0
- package/crates/naome-core/src/repository_model/world_path_facts.rs +55 -0
- package/crates/naome-core/src/repository_model/world_paths.rs +168 -0
- package/crates/naome-core/src/repository_model.rs +164 -0
- package/crates/naome-core/src/route/builtin_checks.rs +40 -1
- package/crates/naome-core/src/task_ledger/import.rs +142 -0
- package/crates/naome-core/src/task_ledger/model.rs +13 -0
- package/crates/naome-core/src/task_ledger/proof_record.rs +52 -0
- package/crates/naome-core/src/task_ledger/read.rs +118 -0
- package/crates/naome-core/src/task_ledger/render.rs +55 -0
- package/crates/naome-core/src/task_ledger/write.rs +38 -0
- package/crates/naome-core/src/task_ledger.rs +48 -0
- package/crates/naome-core/src/task_state/api.rs +4 -2
- package/crates/naome-core/src/task_state/completed_refresh.rs +5 -16
- package/crates/naome-core/src/task_state/diff.rs +2 -2
- package/crates/naome-core/src/task_state/evidence.rs +8 -3
- package/crates/naome-core/src/task_state/mod.rs +1 -1
- package/crates/naome-core/src/task_state/progress.rs +13 -0
- package/crates/naome-core/src/task_state/proof_model.rs +8 -8
- package/crates/naome-core/src/task_state/repair.rs +2 -2
- package/crates/naome-core/src/task_state/task_diff_api.rs +9 -18
- package/crates/naome-core/src/task_state/types.rs +24 -0
- package/crates/naome-core/src/verification.rs +29 -18
- package/crates/naome-core/src/workflow/agent/capability.rs +194 -0
- package/crates/naome-core/src/workflow/agent/context_delta.rs +42 -0
- package/crates/naome-core/src/workflow/agent/decision.rs +32 -0
- package/crates/naome-core/src/workflow/agent/execution.rs +80 -0
- package/crates/naome-core/src/workflow/agent/proof.rs +24 -0
- package/crates/naome-core/src/workflow/agent/support.rs +58 -0
- package/crates/naome-core/src/workflow/agent/watchdog.rs +47 -0
- package/crates/naome-core/src/workflow/agent.rs +34 -0
- package/crates/naome-core/src/workflow/agent_types.rs +105 -0
- package/crates/naome-core/src/workflow/doctor.rs +39 -0
- package/crates/naome-core/src/workflow/mod.rs +11 -0
- package/crates/naome-core/src/workflow/output.rs +8 -2
- package/crates/naome-core/src/workflow/phase_inference.rs +1 -1
- package/crates/naome-core/tests/context.rs +99 -0
- package/crates/naome-core/tests/harness_health.rs +33 -40
- package/crates/naome-core/tests/install_plan.rs +12 -0
- package/crates/naome-core/tests/quality.rs +178 -2
- package/crates/naome-core/tests/quality_performance.rs +39 -2
- package/crates/naome-core/tests/quality_structure_adapters.rs +39 -0
- package/crates/naome-core/tests/repo_support/mod.rs +7 -1
- package/crates/naome-core/tests/repo_support/verification_values.rs +148 -1
- package/crates/naome-core/tests/repository_model.rs +281 -0
- package/crates/naome-core/tests/route_user_diff.rs +49 -1
- package/crates/naome-core/tests/semantic_legacy.rs +72 -38
- package/crates/naome-core/tests/task_ledger.rs +328 -0
- package/crates/naome-core/tests/task_state.rs +34 -14
- package/crates/naome-core/tests/task_state_support/mod.rs +2 -1
- package/crates/naome-core/tests/task_state_support/states.rs +28 -11
- package/crates/naome-core/tests/verification.rs +14 -39
- package/crates/naome-core/tests/verification_contract.rs +6 -52
- package/crates/naome-core/tests/workflow_agent.rs +233 -0
- package/crates/naome-core/tests/workflow_agent_support/mod.rs +159 -0
- package/crates/naome-core/tests/workflow_doctor.rs +21 -0
- package/crates/naome-core/tests/workflow_integrity.rs +2 -20
- package/crates/naome-core/tests/workflow_support/mod.rs +59 -20
- package/installer/codex-hooks.js +121 -0
- package/installer/context.js +10 -0
- package/installer/filesystem.js +4 -0
- package/installer/flows.js +8 -4
- package/installer/harness-files.js +6 -0
- package/installer/install-plan.js +4 -0
- package/installer/main.js +1 -1
- package/installer/native.js +1 -1
- package/native/darwin-arm64/naome +0 -0
- package/native/linux-x64/naome +0 -0
- package/package.json +1 -1
- package/templates/naome-root/.codex/config.toml +2 -0
- package/templates/naome-root/.codex/hooks.json +70 -0
- package/templates/naome-root/.naome/bin/check-harness-health.js +8 -6
- package/templates/naome-root/.naome/bin/check-task-state.js +12 -7
- package/templates/naome-root/.naome/bin/codex-hook-io.js +122 -0
- package/templates/naome-root/.naome/bin/codex-hook-policy.js +180 -0
- package/templates/naome-root/.naome/bin/codex-hook-runtime.js +174 -0
- package/templates/naome-root/.naome/bin/codex-hook.js +6 -0
- package/templates/naome-root/.naome/bin/naome.js +35 -4
- package/templates/naome-root/.naome/manifest.json +12 -6
- package/templates/naome-root/.naome/repository-model.json +6 -0
- package/templates/naome-root/.naome/repository-quality.json +3 -1
- package/templates/naome-root/.naome/verification.json +15 -1
- package/templates/naome-root/AGENTS.md +38 -83
- package/templates/naome-root/docs/naome/agent-workflow.md +54 -18
- package/templates/naome-root/docs/naome/codex-hooks.md +82 -0
- package/templates/naome-root/docs/naome/context-economy.md +73 -0
- package/templates/naome-root/docs/naome/first-run.md +25 -14
- package/templates/naome-root/docs/naome/index.md +18 -10
- package/templates/naome-root/docs/naome/repository-model.md +92 -0
- package/templates/naome-root/docs/naome/repository-quality.md +47 -7
- package/templates/naome-root/docs/naome/repository-structure.md +10 -3
- package/templates/naome-root/docs/naome/task-ledger.md +71 -0
- package/templates/naome-root/docs/naome/testing.md +16 -3
package/Cargo.lock
CHANGED
|
@@ -76,7 +76,7 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
|
|
76
76
|
|
|
77
77
|
[[package]]
|
|
78
78
|
name = "naome-cli"
|
|
79
|
-
version = "1.3.
|
|
79
|
+
version = "1.3.2"
|
|
80
80
|
dependencies = [
|
|
81
81
|
"naome-core",
|
|
82
82
|
"serde_json",
|
|
@@ -84,7 +84,7 @@ dependencies = [
|
|
|
84
84
|
|
|
85
85
|
[[package]]
|
|
86
86
|
name = "naome-core"
|
|
87
|
-
version = "1.3.
|
|
87
|
+
version = "1.3.2"
|
|
88
88
|
dependencies = [
|
|
89
89
|
"serde",
|
|
90
90
|
"serde_json",
|
package/README.md
CHANGED
|
@@ -50,6 +50,8 @@ naome route --prompt-file /path/to/prompt.txt --execute --json
|
|
|
50
50
|
perfect on day one.
|
|
51
51
|
- Records verification proof before a task can be treated as complete.
|
|
52
52
|
- Keeps sync fast by making baseline and deep quality scans explicit.
|
|
53
|
+
- Can install optional Codex hooks for earlier agent feedback without making
|
|
54
|
+
hooks a human workflow requirement.
|
|
53
55
|
|
|
54
56
|
## Safety Model
|
|
55
57
|
|
|
@@ -77,12 +79,15 @@ naome quality init --baseline
|
|
|
77
79
|
naome quality report
|
|
78
80
|
naome quality report --deep
|
|
79
81
|
naome quality check --changed
|
|
82
|
+
naome semantic check --changed
|
|
83
|
+
naome task render-state --write --json
|
|
80
84
|
naome commit -m "type(scope): summary"
|
|
81
85
|
```
|
|
82
86
|
|
|
83
87
|
`naome sync` installs or repairs the local harness files. It does not run a
|
|
84
|
-
hidden full-repository quality scan.
|
|
85
|
-
|
|
88
|
+
hidden full-repository quality scan. It also migrates any active legacy
|
|
89
|
+
task-state into the task ledger automatically. If quality policy is newly
|
|
90
|
+
seeded, run `naome quality init --baseline` deliberately; use `--deep` or
|
|
86
91
|
`--deep-baseline` only when you want expensive repository-wide checks.
|
|
87
92
|
|
|
88
93
|
## Repository Docs
|
|
@@ -94,6 +99,8 @@ After sync, NAOME writes the agent-facing workflow into `docs/naome/`:
|
|
|
94
99
|
- `docs/naome/testing.md` maps change types to required checks.
|
|
95
100
|
- `docs/naome/repository-quality.md` explains quality, structure, and cleanup
|
|
96
101
|
policy.
|
|
102
|
+
- `docs/naome/codex-hooks.md` explains the optional Codex hook acceleration
|
|
103
|
+
layer.
|
|
97
104
|
|
|
98
105
|
Agents should follow the repository's NAOME docs instead of guessing workflow
|
|
99
106
|
rules from generic project files.
|
|
@@ -109,6 +116,7 @@ The main local policy files are:
|
|
|
109
116
|
- `.naome/repository-structure.json` for path role, module, and directory
|
|
110
117
|
structure policy.
|
|
111
118
|
- `.naome/task-state.json` for active task state and proof.
|
|
119
|
+
- `.codex/hooks.json` only when optional Codex hooks were explicitly enabled.
|
|
112
120
|
|
|
113
121
|
Product defaults stay generic. Repository-specific policy belongs in the local
|
|
114
122
|
`.naome/` config files.
|
|
@@ -123,6 +131,7 @@ npm run test:decision-engine
|
|
|
123
131
|
npm run test:naome-installer
|
|
124
132
|
npm run pack:dry-run
|
|
125
133
|
node .naome/bin/naome.js quality check --changed --json
|
|
134
|
+
node .naome/bin/naome.js semantic check --changed --json
|
|
126
135
|
git diff --check
|
|
127
136
|
```
|
|
128
137
|
|
package/bin/naome.js
CHANGED
|
@@ -12,7 +12,7 @@ const packageVersion = packageMetadata.version;
|
|
|
12
12
|
const nativeBinaryName = process.platform === "win32" ? "naome.exe" : "naome";
|
|
13
13
|
const args = process.argv.slice(2);
|
|
14
14
|
const [command] = args;
|
|
15
|
-
const helpCommands = "status [--json]|next [--json]|intent --prompt-file <path> [--json]|intent --prompt <text> [--json]|route --prompt-file <path> [--execute] [--json]|route --prompt <text> [--execute] [--json]|explain --prompt-file <path> [--json]|explain --prompt <text> [--json]|doctor [--json]|install|sync [--check-update]|update [--json] [--execute]|quality init [--baseline|--deep-baseline] [--json]|quality check --changed [--include-scanned-paths] [--json]|quality report [--deep] [--include-scanned-paths] [--json]|quality cache status [--json]|quality cache clear|semantic report [--deep] [--json]|semantic check --changed [--json]|semantic route --finding <id> [--json]|semantic loop [--json]|structure report [--json]|structure explain --path <path> [--json]|cleanup plan [--json]|cleanup route --path <path> [--json]|refresh-integrity [--json]|workflow search-profile|check-search|phases|processes|mutations [--json]|commit -m \"type(scope): message\"".split("|");
|
|
15
|
+
const helpCommands = "status [--json]|next [--json]|intent --prompt-file <path> [--json]|intent --prompt <text> [--json]|route --prompt-file <path> [--execute] [--json]|route --prompt <text> [--execute] [--json]|explain --prompt-file <path> [--json]|explain --prompt <text> [--json]|context select --changed [--json]|context select --prompt-file <path> [--json]|context select --prompt <text> [--json]|doctor [--json]|install|sync [--check-update]|update [--json] [--execute]|task render-state [--write] [--json]|task migrate-ledger [--write] [--json]|quality init [--baseline|--deep-baseline] [--json]|quality reconcile [--write] [--json]|quality check --changed [--include-scanned-paths] [--json]|quality check --path <path> [--path <path>...] [--include-scanned-paths] [--json]|quality report [--deep] [--include-scanned-paths] [--json]|quality cache status [--json]|quality cache clear|semantic report [--deep] [--json]|semantic check --changed [--json]|semantic check --path <path> [--path <path>...] [--json]|semantic route --finding <id> [--json]|semantic loop [--json]|repo model [--write] [--json]|repo check [--json]|repo explain --path <path> [--json]|structure report [--json]|structure explain --path <path> [--json]|cleanup plan [--json]|cleanup route --path <path> [--json]|refresh-integrity [--json]|workflow agent-plan|context-delta|proof-plan|capabilities|edit-watchdog|decision-gate|digest [--json]|workflow search-profile|check-search|phases|processes|mutations [--json]|commit -m \"type(scope): message\"".split("|");
|
|
16
16
|
|
|
17
17
|
if (isHelpRequest(args)) {
|
|
18
18
|
printHelp();
|
|
@@ -31,6 +31,7 @@ if (command === "install" || command === "sync") {
|
|
|
31
31
|
const qualityConfigExisted = existsSync(repositoryQualityConfigPath(process.cwd()));
|
|
32
32
|
const result = runNativePackageCommand(args.filter((arg) => arg !== "--check-update"));
|
|
33
33
|
if (result.status === 0) {
|
|
34
|
+
ensureTaskLedgerMigrated(result.nativeBinary);
|
|
34
35
|
ensureRepositoryQualityInitialized(result.nativeBinary, qualityConfigExisted);
|
|
35
36
|
}
|
|
36
37
|
process.exit(result.status === null ? 1 : result.status);
|
|
@@ -281,27 +282,11 @@ function ensureRepositoryQualityInitialized(nativeBinary, qualityConfigExisted)
|
|
|
281
282
|
}
|
|
282
283
|
}
|
|
283
284
|
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
NAOME_NODE_BIN: process.execPath
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
if (result.status !== 0) {
|
|
294
|
-
console.error("NAOME: repository quality initialization failed.");
|
|
295
|
-
if (result.stdout.trim()) {
|
|
296
|
-
console.error(result.stdout.trim());
|
|
297
|
-
}
|
|
298
|
-
if (result.stderr.trim()) {
|
|
299
|
-
console.error(result.stderr.trim());
|
|
300
|
-
}
|
|
301
|
-
process.exit(result.status === null ? 1 : result.status);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const output = result.stdout.trim();
|
|
285
|
+
const output = runNativeJsonCommand(
|
|
286
|
+
nativeBinary,
|
|
287
|
+
["quality", "init", "--json"],
|
|
288
|
+
"repository quality initialization failed"
|
|
289
|
+
);
|
|
305
290
|
if (output) {
|
|
306
291
|
try {
|
|
307
292
|
const init = JSON.parse(output);
|
|
@@ -317,6 +302,59 @@ function ensureRepositoryQualityInitialized(nativeBinary, qualityConfigExisted)
|
|
|
317
302
|
}
|
|
318
303
|
}
|
|
319
304
|
|
|
305
|
+
function ensureTaskLedgerMigrated(nativeBinary) {
|
|
306
|
+
const root = process.cwd();
|
|
307
|
+
if (!existsSync(join(root, ".naome"))) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const output = runNativeJsonCommand(
|
|
312
|
+
nativeBinary,
|
|
313
|
+
["task", "migrate-ledger", "--write", "--json"],
|
|
314
|
+
"task ledger migration failed"
|
|
315
|
+
);
|
|
316
|
+
if (!output) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
try {
|
|
321
|
+
const migration = JSON.parse(output);
|
|
322
|
+
if (migration.updated && migration.migration?.source === "task-state") {
|
|
323
|
+
console.log("task ledger migrated from task-state");
|
|
324
|
+
}
|
|
325
|
+
} catch (_error) {
|
|
326
|
+
console.log(output);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function runNativeJsonCommand(nativeBinary, commandArgs, failureLabel) {
|
|
331
|
+
const result = spawnSync(nativeBinary, commandArgs, {
|
|
332
|
+
cwd: process.cwd(),
|
|
333
|
+
encoding: "utf8",
|
|
334
|
+
env: {
|
|
335
|
+
...process.env,
|
|
336
|
+
NAOME_NODE_BIN: process.execPath
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
if (result.status !== 0) {
|
|
341
|
+
exitNativeJsonFailure(failureLabel, result);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return result.stdout.trim();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function exitNativeJsonFailure(label, result) {
|
|
348
|
+
console.error(`NAOME: ${label}.`);
|
|
349
|
+
for (const stream of [result.stdout, result.stderr]) {
|
|
350
|
+
const text = stream.trim();
|
|
351
|
+
if (text) {
|
|
352
|
+
console.error(text);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
356
|
+
}
|
|
357
|
+
|
|
320
358
|
function repositoryQualityConfigPath(root) {
|
|
321
359
|
return join(root, ".naome", "repository-quality.json");
|
|
322
360
|
}
|
|
@@ -339,8 +377,8 @@ function repositoryQualitySupportFilesExist(root) {
|
|
|
339
377
|
function resolveNativePackageBinary() {
|
|
340
378
|
const candidates = [
|
|
341
379
|
process.env.NAOME_NATIVE_BIN && resolve(process.cwd(), process.env.NAOME_NATIVE_BIN),
|
|
342
|
-
join(packageRoot, "
|
|
343
|
-
join(packageRoot, "
|
|
380
|
+
join(packageRoot, "target", "release", nativeBinaryName),
|
|
381
|
+
join(packageRoot, "native", `${process.platform}-${process.arch}`, nativeBinaryName)
|
|
344
382
|
].filter(Boolean);
|
|
345
383
|
|
|
346
384
|
for (const candidate of candidates) {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
use std::fs;
|
|
2
|
+
use std::path::Path;
|
|
3
|
+
|
|
4
|
+
use naome_core::{select_context_for_changed_paths, select_context_for_prompt};
|
|
5
|
+
|
|
6
|
+
use crate::cli_args::option_value;
|
|
7
|
+
|
|
8
|
+
pub fn run_context_command(root: &Path, args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
|
|
9
|
+
let Some(subcommand) = args.get(1).map(String::as_str) else {
|
|
10
|
+
return Err("naome context requires select.".into());
|
|
11
|
+
};
|
|
12
|
+
match subcommand {
|
|
13
|
+
"select" => run_context_select(root, args)?,
|
|
14
|
+
_ => return Err(format!("unknown naome context command: {subcommand}").into()),
|
|
15
|
+
}
|
|
16
|
+
Ok(())
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fn run_context_select(root: &Path, args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
|
|
20
|
+
let selection = if args.iter().any(|arg| arg == "--changed") {
|
|
21
|
+
select_context_for_changed_paths(root)?
|
|
22
|
+
} else if let Some(prompt) = option_value(args, "--prompt") {
|
|
23
|
+
select_context_for_prompt(root, prompt)?
|
|
24
|
+
} else if let Some(prompt_file) = option_value(args, "--prompt-file") {
|
|
25
|
+
select_context_for_prompt(root, fs::read_to_string(prompt_file)?)?
|
|
26
|
+
} else {
|
|
27
|
+
return Err(
|
|
28
|
+
"naome context select requires --changed, --prompt <text>, or --prompt-file <path>."
|
|
29
|
+
.into(),
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if args.iter().any(|arg| arg == "--json") {
|
|
34
|
+
println!("{}", serde_json::to_string_pretty(&selection)?);
|
|
35
|
+
} else {
|
|
36
|
+
println!(
|
|
37
|
+
"NAOME context capsule: {} ({} file(s), ~{} token(s))",
|
|
38
|
+
selection.capsule.id,
|
|
39
|
+
selection.budget_ledger.selected_files,
|
|
40
|
+
selection.budget_ledger.estimated_tokens
|
|
41
|
+
);
|
|
42
|
+
for item in &selection.required_context {
|
|
43
|
+
println!("- {}", item.path);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
Ok(())
|
|
47
|
+
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
use std::path::Path;
|
|
2
2
|
|
|
3
3
|
use crate::check_commands::{run_harness_health, run_task_state, run_verification_contract};
|
|
4
|
+
use crate::context_commands::run_context_command;
|
|
4
5
|
use crate::install_bridge::run_install_bridge;
|
|
5
6
|
use crate::prompt_commands::{run_explain, run_intent, run_route};
|
|
6
7
|
use crate::quality_commands::{
|
|
7
8
|
run_cleanup_command, run_quality_command, run_semantic_command, run_structure_command,
|
|
8
9
|
};
|
|
10
|
+
use crate::repository_model_commands::run_repo_command;
|
|
9
11
|
use crate::simple_commands::{
|
|
10
12
|
print_install_plan, run_commit_paths, run_journal_task, seed_verification,
|
|
11
13
|
};
|
|
14
|
+
use crate::task_commands::run_task_command;
|
|
12
15
|
use crate::workflow_commands::{run_doctor, run_refresh_integrity, run_workflow_command};
|
|
13
16
|
|
|
14
17
|
pub fn dispatch_command(
|
|
@@ -20,10 +23,13 @@ pub fn dispatch_command(
|
|
|
20
23
|
"install" | "sync" => run_install_bridge(command, args)?,
|
|
21
24
|
"install-plan" => print_install_plan(args)?,
|
|
22
25
|
"seed-verification" => seed_verification(root)?,
|
|
26
|
+
"task" => run_task_command(root, args)?,
|
|
23
27
|
"refresh-integrity" => run_refresh_integrity(root, args)?,
|
|
28
|
+
"context" => run_context_command(root, args)?,
|
|
24
29
|
"doctor" => run_doctor(root, args)?,
|
|
25
30
|
"quality" => run_quality_command(root, args)?,
|
|
26
31
|
"semantic" => run_semantic_command(root, args)?,
|
|
32
|
+
"repo" => run_repo_command(root, args)?,
|
|
27
33
|
"structure" => run_structure_command(root, args)?,
|
|
28
34
|
"cleanup" => run_cleanup_command(root, args)?,
|
|
29
35
|
"workflow" => run_workflow_command(root, args)?,
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
mod check_commands;
|
|
2
2
|
mod cli_args;
|
|
3
|
+
mod context_commands;
|
|
3
4
|
mod dispatcher;
|
|
4
5
|
mod install_bridge;
|
|
5
6
|
mod prompt_commands;
|
|
6
7
|
mod quality_commands;
|
|
8
|
+
mod quality_output;
|
|
9
|
+
mod quality_reconcile_command;
|
|
10
|
+
mod repository_model_commands;
|
|
7
11
|
mod simple_commands;
|
|
12
|
+
mod task_commands;
|
|
8
13
|
mod workflow_commands;
|
|
9
14
|
|
|
10
15
|
use std::path::{Path, PathBuf};
|
|
@@ -22,26 +27,44 @@ const HELP: &str = r#"Usage:
|
|
|
22
27
|
naome route --prompt <text> [--execute] [--json]
|
|
23
28
|
naome explain --prompt-file <path> [--json]
|
|
24
29
|
naome explain --prompt <text> [--json]
|
|
30
|
+
naome context select --changed [--json]
|
|
31
|
+
naome context select --prompt-file <path> [--json]
|
|
32
|
+
naome context select --prompt <text> [--json]
|
|
25
33
|
naome doctor [--json]
|
|
26
34
|
naome install [--package-root <path>] [--installer-js <path>]
|
|
27
35
|
naome sync [--package-root <path>] [--installer-js <path>]
|
|
28
36
|
naome install-plan [--harness-version <version>]
|
|
29
37
|
naome seed-verification
|
|
38
|
+
naome task render-state [--write] [--json]
|
|
39
|
+
naome task migrate-ledger [--write] [--json]
|
|
30
40
|
naome refresh-integrity [--root <path>] [--json]
|
|
31
41
|
naome quality init [--baseline|--deep-baseline] [--json]
|
|
42
|
+
naome quality reconcile [--write] [--json]
|
|
32
43
|
naome quality check --changed [--include-scanned-paths] [--json]
|
|
44
|
+
naome quality check --path <path> [--path <path>...] [--include-scanned-paths] [--json]
|
|
33
45
|
naome quality report [--deep] [--include-scanned-paths] [--json]
|
|
34
46
|
naome quality cache status [--json]
|
|
35
47
|
naome quality cache clear
|
|
36
48
|
naome semantic report [--deep] [--json]
|
|
37
49
|
naome semantic check --changed [--json]
|
|
50
|
+
naome semantic check --path <path> [--path <path>...] [--json]
|
|
38
51
|
naome semantic route --finding <id> [--json]
|
|
39
52
|
naome semantic loop [--json]
|
|
53
|
+
naome repo model [--write] [--json]
|
|
54
|
+
naome repo check [--json]
|
|
55
|
+
naome repo explain --path <path> [--json]
|
|
40
56
|
naome structure report [--json]
|
|
41
57
|
naome structure explain --path <path> [--json]
|
|
42
58
|
naome cleanup plan [--json]
|
|
43
59
|
naome cleanup route --path <path> [--json]
|
|
44
60
|
naome workflow search-profile [--json]
|
|
61
|
+
naome workflow agent-plan [--json]
|
|
62
|
+
naome workflow context-delta [--read-path <path>...] [--json]
|
|
63
|
+
naome workflow proof-plan [--json]
|
|
64
|
+
naome workflow capabilities [--json]
|
|
65
|
+
naome workflow edit-watchdog --path <path> [--path <path>...] [--json]
|
|
66
|
+
naome workflow decision-gate [--json]
|
|
67
|
+
naome workflow digest --command <cmd> --exit-code <code> [--output <text>|--output-file <path>] [--json]
|
|
45
68
|
naome workflow check-search --command <cmd> [--json]
|
|
46
69
|
naome workflow phases [--json]
|
|
47
70
|
naome workflow processes [--json]
|
|
@@ -60,10 +83,13 @@ const PUBLIC_COMMANDS: &[&str] = &[
|
|
|
60
83
|
"journal-task",
|
|
61
84
|
"commit-paths",
|
|
62
85
|
"seed-verification",
|
|
86
|
+
"task",
|
|
63
87
|
"refresh-integrity",
|
|
88
|
+
"context",
|
|
64
89
|
"workflow",
|
|
65
90
|
"quality",
|
|
66
91
|
"semantic",
|
|
92
|
+
"repo",
|
|
67
93
|
"structure",
|
|
68
94
|
"cleanup",
|
|
69
95
|
"install-plan",
|
|
@@ -140,7 +166,13 @@ fn is_help_request(args: &[String]) -> bool {
|
|
|
140
166
|
}
|
|
141
167
|
|
|
142
168
|
fn find_harness_root(start: &Path) -> Option<PathBuf> {
|
|
143
|
-
|
|
169
|
+
find_root_with_any_marker(
|
|
170
|
+
start,
|
|
171
|
+
&[
|
|
172
|
+
&[".naome", "task-state.json"],
|
|
173
|
+
&[".naome", "tasks", "active.json"],
|
|
174
|
+
],
|
|
175
|
+
)
|
|
144
176
|
}
|
|
145
177
|
|
|
146
178
|
fn find_manifest_root(start: &Path) -> Option<PathBuf> {
|
|
@@ -148,13 +180,18 @@ fn find_manifest_root(start: &Path) -> Option<PathBuf> {
|
|
|
148
180
|
}
|
|
149
181
|
|
|
150
182
|
fn find_root_with_marker(start: &Path, marker: &[&str]) -> Option<PathBuf> {
|
|
183
|
+
find_root_with_any_marker(start, &[marker])
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
fn find_root_with_any_marker(start: &Path, markers: &[&[&str]]) -> Option<PathBuf> {
|
|
151
187
|
let mut current = start.to_path_buf();
|
|
152
188
|
loop {
|
|
153
|
-
if marker
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
189
|
+
if markers.iter().any(|marker| {
|
|
190
|
+
marker
|
|
191
|
+
.iter()
|
|
192
|
+
.fold(current.clone(), |path, part| path.join(part))
|
|
193
|
+
.is_file()
|
|
194
|
+
}) {
|
|
158
195
|
return Some(current);
|
|
159
196
|
}
|
|
160
197
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
use std::path::Path;
|
|
2
2
|
|
|
3
3
|
use naome_core::{
|
|
4
|
-
check_repository_quality, check_semantic_legacy,
|
|
5
|
-
explain_repository_structure, init_repository_quality_with_mode,
|
|
6
|
-
quality_cache_status, route_quality_cleanup, semantic_route_for_finding,
|
|
7
|
-
QualityMode,
|
|
4
|
+
check_repository_quality, check_repository_quality_paths, check_semantic_legacy, check_semantic_legacy_paths,
|
|
5
|
+
clear_quality_cache, explain_repository_structure, init_repository_quality_with_mode,
|
|
6
|
+
plan_quality_cleanup, quality_cache_status, route_quality_cleanup, semantic_route_for_finding,
|
|
7
|
+
QualityInitMode, QualityMode,
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
use crate::cli_args::option_value;
|
|
11
|
+
use crate::quality_output::{is_structure_check, print_quality_violation, report_json};
|
|
12
|
+
use crate::quality_reconcile_command::run_quality_reconcile;
|
|
11
13
|
|
|
12
14
|
pub fn run_quality_command(root: &Path, args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
|
|
13
15
|
let Some(subcommand) = args.get(1).map(String::as_str) else {
|
|
14
|
-
return Err("naome quality requires init, check, report, or cache.".into());
|
|
16
|
+
return Err("naome quality requires init, reconcile, check, report, or cache.".into());
|
|
15
17
|
};
|
|
16
18
|
let json = args.iter().any(|arg| arg == "--json");
|
|
17
19
|
|
|
@@ -30,6 +32,7 @@ pub fn run_quality_command(root: &Path, args: &[String]) -> Result<(), Box<dyn s
|
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
34
|
}
|
|
35
|
+
"reconcile" => run_quality_reconcile(root, args, json)?,
|
|
33
36
|
"check" => run_quality_check(root, args, json)?,
|
|
34
37
|
"report" => run_quality_report(root, args, json)?,
|
|
35
38
|
"cache" => run_quality_cache(root, args, json)?,
|
|
@@ -93,10 +96,15 @@ fn run_quality_check(
|
|
|
93
96
|
args: &[String],
|
|
94
97
|
json: bool,
|
|
95
98
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
let paths = option_values(args, "--path");
|
|
100
|
+
let report = if paths.is_empty() {
|
|
101
|
+
if !args.iter().any(|arg| arg == "--changed") {
|
|
102
|
+
return Err("naome quality check requires --changed or --path <path>.".into());
|
|
103
|
+
}
|
|
104
|
+
check_repository_quality(root, QualityMode::ChangedFast)?
|
|
105
|
+
} else {
|
|
106
|
+
check_repository_quality_paths(root, &paths)?
|
|
107
|
+
};
|
|
100
108
|
if json {
|
|
101
109
|
println!("{}", report_json(&report, args)?);
|
|
102
110
|
} else if report.ok {
|
|
@@ -303,10 +311,15 @@ fn run_semantic_check(
|
|
|
303
311
|
args: &[String],
|
|
304
312
|
json: bool,
|
|
305
313
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
314
|
+
let paths = option_values(args, "--path");
|
|
315
|
+
let report = if paths.is_empty() {
|
|
316
|
+
if !args.iter().any(|arg| arg == "--changed") {
|
|
317
|
+
return Err("naome semantic check requires --changed or --path <path>.".into());
|
|
318
|
+
}
|
|
319
|
+
check_semantic_legacy(root, QualityMode::ChangedFast)?
|
|
320
|
+
} else {
|
|
321
|
+
check_semantic_legacy_paths(root, &paths)?
|
|
322
|
+
};
|
|
310
323
|
if json {
|
|
311
324
|
println!("{}", serde_json::to_string_pretty(&report)?);
|
|
312
325
|
} else if report.ok {
|
|
@@ -397,20 +410,6 @@ fn run_semantic_loop(root: &Path, json: bool) -> Result<(), Box<dyn std::error::
|
|
|
397
410
|
Ok(())
|
|
398
411
|
}
|
|
399
412
|
|
|
400
|
-
fn is_structure_check(check_id: &str) -> bool {
|
|
401
|
-
matches!(
|
|
402
|
-
check_id,
|
|
403
|
-
"directory-role-mixing"
|
|
404
|
-
| "misplaced-file-role"
|
|
405
|
-
| "root-file-sprawl"
|
|
406
|
-
| "dumping-ground-directory"
|
|
407
|
-
| "directory-size"
|
|
408
|
-
| "path-depth"
|
|
409
|
-
| "case-collision"
|
|
410
|
-
| "test-source-pairing"
|
|
411
|
-
)
|
|
412
|
-
}
|
|
413
|
-
|
|
414
413
|
fn quality_init_mode(args: &[String]) -> Result<QualityInitMode, Box<dyn std::error::Error>> {
|
|
415
414
|
let baseline = args.iter().any(|arg| arg == "--baseline");
|
|
416
415
|
let deep_baseline = args.iter().any(|arg| arg == "--deep-baseline");
|
|
@@ -426,23 +425,9 @@ fn quality_init_mode(args: &[String]) -> Result<QualityInitMode, Box<dyn std::er
|
|
|
426
425
|
})
|
|
427
426
|
}
|
|
428
427
|
|
|
429
|
-
fn
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
)
|
|
433
|
-
|
|
434
|
-
if !args.iter().any(|arg| arg == "--include-scanned-paths") {
|
|
435
|
-
if let Some(object) = value.as_object_mut() {
|
|
436
|
-
object.remove("scannedPaths");
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
Ok(serde_json::to_string_pretty(&value)?)
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
fn print_quality_violation(violation: &naome_core::QualityViolation) {
|
|
443
|
-
let location = violation
|
|
444
|
-
.line
|
|
445
|
-
.map(|line| format!("{}:{line}", violation.path))
|
|
446
|
-
.unwrap_or_else(|| violation.path.clone());
|
|
447
|
-
eprintln!("- {location} {}: {}", violation.check_id, violation.message);
|
|
428
|
+
fn option_values(args: &[String], name: &str) -> Vec<String> {
|
|
429
|
+
args.windows(2)
|
|
430
|
+
.filter(|window| window[0] == name)
|
|
431
|
+
.map(|window| window[1].clone())
|
|
432
|
+
.collect()
|
|
448
433
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
pub fn report_json(
|
|
2
|
+
report: &naome_core::QualityReport,
|
|
3
|
+
args: &[String],
|
|
4
|
+
) -> Result<String, Box<dyn std::error::Error>> {
|
|
5
|
+
let mut value = serde_json::to_value(report)?;
|
|
6
|
+
if !args.iter().any(|arg| arg == "--include-scanned-paths") {
|
|
7
|
+
if let Some(object) = value.as_object_mut() {
|
|
8
|
+
object.remove("scannedPaths");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
Ok(serde_json::to_string_pretty(&value)?)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub fn print_quality_violation(violation: &naome_core::QualityViolation) {
|
|
15
|
+
let location = violation
|
|
16
|
+
.line
|
|
17
|
+
.map(|line| format!("{}:{line}", violation.path))
|
|
18
|
+
.unwrap_or_else(|| violation.path.clone());
|
|
19
|
+
eprintln!("- {location} {}: {}", violation.check_id, violation.message);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub fn is_structure_check(check_id: &str) -> bool {
|
|
23
|
+
matches!(
|
|
24
|
+
check_id,
|
|
25
|
+
"directory-role-mixing"
|
|
26
|
+
| "misplaced-file-role"
|
|
27
|
+
| "root-file-sprawl"
|
|
28
|
+
| "dumping-ground-directory"
|
|
29
|
+
| "directory-size"
|
|
30
|
+
| "path-depth"
|
|
31
|
+
| "case-collision"
|
|
32
|
+
| "test-source-pairing"
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
use std::collections::BTreeSet;
|
|
2
|
+
use std::path::Path;
|
|
3
|
+
|
|
4
|
+
use naome_core::reconcile_repository_quality;
|
|
5
|
+
|
|
6
|
+
pub fn run_quality_reconcile(
|
|
7
|
+
root: &Path,
|
|
8
|
+
args: &[String],
|
|
9
|
+
json: bool,
|
|
10
|
+
) -> Result<(), Box<dyn std::error::Error>> {
|
|
11
|
+
let write = args.iter().any(|arg| arg == "--write");
|
|
12
|
+
let report = reconcile_repository_quality(root, write)?;
|
|
13
|
+
if json {
|
|
14
|
+
println!("{}", serde_json::to_string_pretty(&report)?);
|
|
15
|
+
} else if report.ok && report.updated_paths.is_empty() {
|
|
16
|
+
println!("NAOME repository quality adapter policy is current.");
|
|
17
|
+
} else if report.ok {
|
|
18
|
+
println!(
|
|
19
|
+
"NAOME repository quality adapter policy updated: {}",
|
|
20
|
+
report.updated_paths.join(", ")
|
|
21
|
+
);
|
|
22
|
+
} else {
|
|
23
|
+
eprintln!(
|
|
24
|
+
"NAOME repository quality adapter policy is stale. Missing adapter(s): {}",
|
|
25
|
+
missing_adapters(&report)
|
|
26
|
+
);
|
|
27
|
+
eprintln!("Run: naome quality reconcile --write");
|
|
28
|
+
}
|
|
29
|
+
if !report.ok {
|
|
30
|
+
std::process::exit(1);
|
|
31
|
+
}
|
|
32
|
+
Ok(())
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fn missing_adapters(report: &naome_core::QualityReconcileReport) -> String {
|
|
36
|
+
report
|
|
37
|
+
.missing_quality_adapters
|
|
38
|
+
.iter()
|
|
39
|
+
.chain(report.missing_structure_adapters.iter())
|
|
40
|
+
.cloned()
|
|
41
|
+
.collect::<BTreeSet<_>>()
|
|
42
|
+
.into_iter()
|
|
43
|
+
.collect::<Vec<_>>()
|
|
44
|
+
.join(", ")
|
|
45
|
+
}
|