atavi 0.1.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/ARCHITECTURE.md +167 -0
- package/CHANGELOG.md +20 -0
- package/CONTRIBUTING.md +42 -0
- package/HOSTS.md +177 -0
- package/LICENSE +22 -0
- package/README.md +232 -0
- package/TESTING.md +68 -0
- package/bin/atavi.js +10 -0
- package/package.json +51 -0
- package/protocol/ATAVI.md +149 -0
- package/protocol/agents/critic.md +19 -0
- package/protocol/agents/experimentalist.md +30 -0
- package/protocol/agents/scout.md +34 -0
- package/protocol/agents/synthesist.md +19 -0
- package/protocol/agents/theorist.md +31 -0
- package/src/cli.js +98 -0
- package/src/commands/doctor.js +39 -0
- package/src/commands/init.js +26 -0
- package/src/commands/memory-export.js +22 -0
- package/src/commands/memory-import.js +31 -0
- package/src/commands/migrate.js +68 -0
- package/src/commands/path.js +6 -0
- package/src/commands/resume-check.js +57 -0
- package/src/commands/validate.js +40 -0
- package/src/lib/config.js +62 -0
- package/src/lib/filesystem.js +27 -0
- package/src/lib/memory.js +75 -0
- package/src/lib/protocol-manifest.js +318 -0
- package/src/lib/status.js +111 -0
- package/templates/cpr.md +12 -0
- package/templates/output-report.md +39 -0
- package/templates/pod.md +22 -0
- package/templates/research-brief.md +32 -0
package/TESTING.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
ATAVI needs a package-level test strategy, not just command smoke tests.
|
|
4
|
+
|
|
5
|
+
## Test layers
|
|
6
|
+
|
|
7
|
+
### Layer 1: Manifest integrity
|
|
8
|
+
|
|
9
|
+
Goal: fail fast if the shipped package stops containing required protocol or
|
|
10
|
+
template files.
|
|
11
|
+
|
|
12
|
+
Current coverage:
|
|
13
|
+
|
|
14
|
+
- `scripts/check-manifest.js`
|
|
15
|
+
- `doctor` command tests
|
|
16
|
+
|
|
17
|
+
### Layer 2: CLI contract
|
|
18
|
+
|
|
19
|
+
Goal: verify the user-facing package commands keep working.
|
|
20
|
+
|
|
21
|
+
Current coverage:
|
|
22
|
+
|
|
23
|
+
- `--path`
|
|
24
|
+
- `init`
|
|
25
|
+
- `doctor`
|
|
26
|
+
- `validate`
|
|
27
|
+
- `resume-check`
|
|
28
|
+
|
|
29
|
+
### Layer 3: Scaffold contract
|
|
30
|
+
|
|
31
|
+
Goal: verify `.atavi/` contains the exact files a host AI expects.
|
|
32
|
+
|
|
33
|
+
Current coverage:
|
|
34
|
+
|
|
35
|
+
- scaffold file existence
|
|
36
|
+
- idempotent init behavior
|
|
37
|
+
- registry and report placeholders
|
|
38
|
+
- explicit memory bucket scaffolding
|
|
39
|
+
- pass and log placeholder scaffolding
|
|
40
|
+
- snapshot coverage for scaffolded markdown
|
|
41
|
+
- deeper memory layout coverage
|
|
42
|
+
- host compatibility coverage for Codex, Claude, and Gemini guidance
|
|
43
|
+
|
|
44
|
+
## Planned deepening inside this repo
|
|
45
|
+
|
|
46
|
+
The product is all-or-nothing in terms of quality bar, so the test plan should
|
|
47
|
+
grow toward:
|
|
48
|
+
|
|
49
|
+
- config schema validation tests
|
|
50
|
+
- snapshot tests for scaffolded markdown files
|
|
51
|
+
- deeper resume-state tests around `status.md` and `config.json`
|
|
52
|
+
- memory layout tests
|
|
53
|
+
- host compatibility tests for Codex / Claude / Gemini loading patterns
|
|
54
|
+
|
|
55
|
+
## Run commands
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
node scripts/check-manifest.js
|
|
59
|
+
node test/run-all.js
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CI expectation
|
|
63
|
+
|
|
64
|
+
CI must stop merges that:
|
|
65
|
+
|
|
66
|
+
- remove a packaged asset
|
|
67
|
+
- break a top-level command
|
|
68
|
+
- change scaffold output unintentionally
|
package/bin/atavi.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { runCli } from "../src/cli.js";
|
|
4
|
+
|
|
5
|
+
runCli(process.argv.slice(2)).catch((error) => {
|
|
6
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7
|
+
process.stderr.write(`${message}\n`);
|
|
8
|
+
process.exitCode = 1;
|
|
9
|
+
});
|
|
10
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "atavi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Host-agnostic multi-agent iterative research refinement protocol.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/mechramc/Atavi#readme",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/mechramc/Atavi/issues"
|
|
10
|
+
},
|
|
11
|
+
"bin": "bin/atavi.js",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin/",
|
|
17
|
+
"src/",
|
|
18
|
+
"protocol/",
|
|
19
|
+
"templates/",
|
|
20
|
+
"README.md",
|
|
21
|
+
"HOSTS.md",
|
|
22
|
+
"ARCHITECTURE.md",
|
|
23
|
+
"CONTRIBUTING.md",
|
|
24
|
+
"TESTING.md",
|
|
25
|
+
"CHANGELOG.md",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"test": "node test/run-all.js",
|
|
33
|
+
"test:watch": "node --watch test/run-all.js",
|
|
34
|
+
"lint": "node --check bin/atavi.js && node --check src/cli.js && node --check src/commands/init.js && node --check src/commands/migrate.js && node --check src/commands/memory-export.js && node --check src/commands/memory-import.js && node --check src/commands/doctor.js && node --check src/commands/path.js && node --check src/commands/validate.js && node --check src/commands/resume-check.js && node --check src/lib/filesystem.js && node --check src/lib/protocol-manifest.js && node --check src/lib/config.js && node --check src/lib/status.js && node --check src/lib/memory.js",
|
|
35
|
+
"check": "node scripts/check-manifest.js",
|
|
36
|
+
"check:release": "node scripts/check-release-surface.js",
|
|
37
|
+
"ci": "node scripts/check-manifest.js && node scripts/check-release-surface.js && node test/run-all.js"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"ai",
|
|
41
|
+
"agents",
|
|
42
|
+
"research",
|
|
43
|
+
"cli",
|
|
44
|
+
"protocol",
|
|
45
|
+
"orchestration"
|
|
46
|
+
],
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/mechramc/Atavi.git"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# ATAVI
|
|
2
|
+
|
|
3
|
+
ATAVI is a host-agnostic multi-agent iterative research refinement protocol.
|
|
4
|
+
The package does not run the research loop itself. It ships the protocol, agent
|
|
5
|
+
contracts, templates, and scaffold helpers that a host AI can execute.
|
|
6
|
+
|
|
7
|
+
## Core Position
|
|
8
|
+
|
|
9
|
+
- ATAVI is a protocol, not a daemon-backed application.
|
|
10
|
+
- The host AI is the orchestrator.
|
|
11
|
+
- Novelty verification is mandatory before any experiment survives.
|
|
12
|
+
- Cross-pollination is mandatory on every pass.
|
|
13
|
+
- Every decision must be inspectable through persistent artifacts.
|
|
14
|
+
|
|
15
|
+
## Modes
|
|
16
|
+
|
|
17
|
+
### Full
|
|
18
|
+
|
|
19
|
+
Run the complete refinement loop with adaptive agent selection, convergence
|
|
20
|
+
tracking, final report generation, and persistent memory updates.
|
|
21
|
+
|
|
22
|
+
### Scout
|
|
23
|
+
|
|
24
|
+
Run novelty search only. Produce a Prior Art Registry and verdicts for claims
|
|
25
|
+
or experiments without generating new experimental design work.
|
|
26
|
+
|
|
27
|
+
### Theorist
|
|
28
|
+
|
|
29
|
+
Formalize a thesis into falsifiable claims, metrics, assumptions, and limits.
|
|
30
|
+
|
|
31
|
+
### Vision
|
|
32
|
+
|
|
33
|
+
Challenge the framing before the loop starts. Produce a Reimagination Brief
|
|
34
|
+
that argues for the original direction, a stronger direction, or a hybrid.
|
|
35
|
+
|
|
36
|
+
### Audit
|
|
37
|
+
|
|
38
|
+
Review a product or system and produce a completion summary that covers
|
|
39
|
+
architecture gaps, security issues, edge cases, tests, observability, and
|
|
40
|
+
deployment risk.
|
|
41
|
+
|
|
42
|
+
## Adaptive Agent Selection
|
|
43
|
+
|
|
44
|
+
ATAVI always includes:
|
|
45
|
+
|
|
46
|
+
- Theorist
|
|
47
|
+
- Experimentalist
|
|
48
|
+
- Scout
|
|
49
|
+
|
|
50
|
+
ATAVI conditionally adds:
|
|
51
|
+
|
|
52
|
+
- Critic when cost of failure is high, work is irreversible, or the novelty
|
|
53
|
+
landscape is crowded
|
|
54
|
+
- Synthesist when the problem spans multiple domains or adjacent disciplines
|
|
55
|
+
|
|
56
|
+
## Run Lifecycle
|
|
57
|
+
|
|
58
|
+
1. Detect an ATAVI invocation inside the host environment.
|
|
59
|
+
2. Discover the input spec, codebase, or product documents.
|
|
60
|
+
3. Extract and confirm a research brief.
|
|
61
|
+
4. Create a local `.atavi/` workspace.
|
|
62
|
+
5. Execute the multi-pass refinement loop.
|
|
63
|
+
6. Compile `ATAVI-REPORT.md`.
|
|
64
|
+
7. Persist reusable memory artifacts for future runs.
|
|
65
|
+
|
|
66
|
+
## Refinement Loop
|
|
67
|
+
|
|
68
|
+
Each pass runs in four ordered phases.
|
|
69
|
+
|
|
70
|
+
### Phase 1: Independent Work
|
|
71
|
+
|
|
72
|
+
Each agent writes a POD to `.atavi/pass-N/[agent]-pod.md`.
|
|
73
|
+
|
|
74
|
+
### Phase 2: Cross-Pollination
|
|
75
|
+
|
|
76
|
+
Each agent reads the other PODs and writes a CPR to
|
|
77
|
+
`.atavi/pass-N/cross-pollination/[agent]-cpr.md`.
|
|
78
|
+
|
|
79
|
+
### Phase 3: Synthesis
|
|
80
|
+
|
|
81
|
+
The host AI updates the Claim Registry, Experiment Ledger, Prior Art Registry,
|
|
82
|
+
conflict list, and convergence score. The host also writes a pass summary to
|
|
83
|
+
`.atavi/pass-N/synthesis.md`.
|
|
84
|
+
|
|
85
|
+
### Phase 4: Decision Gate
|
|
86
|
+
|
|
87
|
+
The host AI either terminates, continues, or escalates to the researcher based
|
|
88
|
+
on convergence, blocking concerns, and surviving experiments. The pass outcome
|
|
89
|
+
is written to `.atavi/pass-N/decision.md`, and cross-pass state remains visible
|
|
90
|
+
in `.atavi/status.md` and `.atavi/run-log.md`.
|
|
91
|
+
|
|
92
|
+
## Novelty Gate
|
|
93
|
+
|
|
94
|
+
The Scout performs structured novelty search on every active claim and active
|
|
95
|
+
experiment. Verdicts are:
|
|
96
|
+
|
|
97
|
+
- `NOVEL`
|
|
98
|
+
- `PARTIAL`
|
|
99
|
+
- `DUPLICATE`
|
|
100
|
+
- `SUPERSEDED`
|
|
101
|
+
|
|
102
|
+
Duplicate or superseded experiments are killed unless the Experimentalist
|
|
103
|
+
supplies a concrete methodological delta and the Scout re-verifies it.
|
|
104
|
+
|
|
105
|
+
Claim-level novelty evidence is recorded in `.atavi/registries/prior-art.md`.
|
|
106
|
+
Experiment-level novelty verdicts are recorded in
|
|
107
|
+
`.atavi/registries/experiments.md` and summarized in `.atavi/pass-N/synthesis.md`.
|
|
108
|
+
|
|
109
|
+
## Convergence
|
|
110
|
+
|
|
111
|
+
Agents vote on surviving experiments using:
|
|
112
|
+
|
|
113
|
+
- `STRONG_YES`
|
|
114
|
+
- `YES`
|
|
115
|
+
- `WEAK_YES`
|
|
116
|
+
- `NO`
|
|
117
|
+
|
|
118
|
+
ATAVI converges when the convergence threshold is met for two consecutive
|
|
119
|
+
passes. If perfect agreement happens too early, the host must force an
|
|
120
|
+
adversarial pass to avoid a coherence trap.
|
|
121
|
+
|
|
122
|
+
## Persistent Memory
|
|
123
|
+
|
|
124
|
+
ATAVI stores:
|
|
125
|
+
|
|
126
|
+
- prior art cache
|
|
127
|
+
- kill archive
|
|
128
|
+
- claim patterns
|
|
129
|
+
- convergence history
|
|
130
|
+
- strategy insights
|
|
131
|
+
|
|
132
|
+
Memories are scoped by domain and keywords, weighted by confidence, expired
|
|
133
|
+
when stale, and corrected when contradicted by new evidence.
|
|
134
|
+
|
|
135
|
+
Reusable memory exports are written into `.atavi/memory/` after a run, using
|
|
136
|
+
the bucketed directories for prior art cache, kill archive, claim patterns,
|
|
137
|
+
convergence history, and strategy insights.
|
|
138
|
+
|
|
139
|
+
## Output Contract
|
|
140
|
+
|
|
141
|
+
The final report must include:
|
|
142
|
+
|
|
143
|
+
- completion summary
|
|
144
|
+
- executive summary
|
|
145
|
+
- ranked recommended experiments
|
|
146
|
+
- rejected experiments / kill log
|
|
147
|
+
- final claim registry
|
|
148
|
+
- final prior art registry
|
|
149
|
+
- full process log
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Critic
|
|
2
|
+
|
|
3
|
+
## Mandate
|
|
4
|
+
|
|
5
|
+
Stress-test the run adversarially when the cost of being wrong is high or the
|
|
6
|
+
landscape is crowded.
|
|
7
|
+
|
|
8
|
+
## Responsibilities
|
|
9
|
+
|
|
10
|
+
- Attempt to falsify claims.
|
|
11
|
+
- Expose confounds and brittle assumptions.
|
|
12
|
+
- Challenge weak differentiation stories.
|
|
13
|
+
- Raise blocking concerns when the run is drifting into self-confirmation.
|
|
14
|
+
|
|
15
|
+
## Constraints
|
|
16
|
+
|
|
17
|
+
- Do not replace the Theorist or Experimentalist.
|
|
18
|
+
- Every criticism must be concrete, testable, and written for action.
|
|
19
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Experimentalist
|
|
2
|
+
|
|
3
|
+
## Mandate
|
|
4
|
+
|
|
5
|
+
Design the experiments that reduce uncertainty about the thesis.
|
|
6
|
+
|
|
7
|
+
## Responsibilities
|
|
8
|
+
|
|
9
|
+
- Propose experiments for the current claim set.
|
|
10
|
+
- Define variables, controls, runtime, feasibility, and failure criteria.
|
|
11
|
+
- Rank experiments by information gain.
|
|
12
|
+
- Respond to Scout novelty verdicts with either differentiation or rejection.
|
|
13
|
+
- Design ablations that isolate causal mechanisms.
|
|
14
|
+
|
|
15
|
+
## Constraints
|
|
16
|
+
|
|
17
|
+
- Do not redefine claims or metrics directly.
|
|
18
|
+
- Every experiment needs a pre-registered expected outcome.
|
|
19
|
+
- Every infeasible or low-value experiment must be explicitly killed.
|
|
20
|
+
|
|
21
|
+
## Output
|
|
22
|
+
|
|
23
|
+
Write a POD containing:
|
|
24
|
+
|
|
25
|
+
- status summary
|
|
26
|
+
- active experiments
|
|
27
|
+
- killed experiments
|
|
28
|
+
- requests to other agents
|
|
29
|
+
- confidence scores
|
|
30
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Scout
|
|
2
|
+
|
|
3
|
+
## Mandate
|
|
4
|
+
|
|
5
|
+
Protect the run from reinventing prior work and missing decisive outside
|
|
6
|
+
evidence.
|
|
7
|
+
|
|
8
|
+
## Responsibilities
|
|
9
|
+
|
|
10
|
+
- Search the web and domain-specific sources for every active claim.
|
|
11
|
+
- Search the web and domain-specific sources for every active experiment.
|
|
12
|
+
- Log search queries and top findings.
|
|
13
|
+
- Issue `NOVEL`, `PARTIAL`, `DUPLICATE`, or `SUPERSEDED` verdicts.
|
|
14
|
+
- Surface adjacent work that could strengthen or redirect the run.
|
|
15
|
+
|
|
16
|
+
## Constraints
|
|
17
|
+
|
|
18
|
+
- Web search is non-negotiable.
|
|
19
|
+
- At least three distinct queries per claim and two per experiment.
|
|
20
|
+
- Do not modify claims or propose experiments.
|
|
21
|
+
- A `DUPLICATE` or `SUPERSEDED` verdict kills an experiment unless a concrete
|
|
22
|
+
methodological delta is re-verified.
|
|
23
|
+
|
|
24
|
+
## Output
|
|
25
|
+
|
|
26
|
+
Write a POD containing:
|
|
27
|
+
|
|
28
|
+
- status summary
|
|
29
|
+
- prior art findings
|
|
30
|
+
- novelty verdicts
|
|
31
|
+
- killed items
|
|
32
|
+
- requests to other agents
|
|
33
|
+
- confidence scores
|
|
34
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Synthesist
|
|
2
|
+
|
|
3
|
+
## Mandate
|
|
4
|
+
|
|
5
|
+
Find useful analogies, methods, and literature from adjacent domains when the
|
|
6
|
+
problem is cross-disciplinary.
|
|
7
|
+
|
|
8
|
+
## Responsibilities
|
|
9
|
+
|
|
10
|
+
- Surface methods from adjacent domains.
|
|
11
|
+
- Identify vocabulary mismatches that hide relevant prior art.
|
|
12
|
+
- Suggest productive cross-domain bridges for the Experimentalist and Theorist.
|
|
13
|
+
|
|
14
|
+
## Constraints
|
|
15
|
+
|
|
16
|
+
- Do not own the novelty gate.
|
|
17
|
+
- Do not directly propose final experiments without routing through the
|
|
18
|
+
Experimentalist.
|
|
19
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Theorist
|
|
2
|
+
|
|
3
|
+
## Mandate
|
|
4
|
+
|
|
5
|
+
Own the theoretical framework. Convert a thesis into falsifiable claims,
|
|
6
|
+
metrics, assumptions, and limits.
|
|
7
|
+
|
|
8
|
+
## Responsibilities
|
|
9
|
+
|
|
10
|
+
- Decompose the thesis into discrete claims.
|
|
11
|
+
- Define metrics for each claim.
|
|
12
|
+
- Surface hidden assumptions.
|
|
13
|
+
- Reject experiments that do not actually test the stated claims.
|
|
14
|
+
- Revise claims when Scout evidence narrows or reframes the thesis.
|
|
15
|
+
|
|
16
|
+
## Constraints
|
|
17
|
+
|
|
18
|
+
- Do not propose experiments directly.
|
|
19
|
+
- Flag tautologies, already-proven claims, and untestable claims.
|
|
20
|
+
- Maintain a structured Claim Registry update in every pass.
|
|
21
|
+
|
|
22
|
+
## Output
|
|
23
|
+
|
|
24
|
+
Write a POD containing:
|
|
25
|
+
|
|
26
|
+
- status summary
|
|
27
|
+
- active claims
|
|
28
|
+
- killed claims
|
|
29
|
+
- requests to other agents
|
|
30
|
+
- confidence scores
|
|
31
|
+
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { commandDoctor } from "./commands/doctor.js";
|
|
2
|
+
import { commandInit } from "./commands/init.js";
|
|
3
|
+
import { commandMemoryExport } from "./commands/memory-export.js";
|
|
4
|
+
import { commandMemoryImport } from "./commands/memory-import.js";
|
|
5
|
+
import { commandMigrate } from "./commands/migrate.js";
|
|
6
|
+
import { commandPath } from "./commands/path.js";
|
|
7
|
+
import { commandResumeCheck } from "./commands/resume-check.js";
|
|
8
|
+
import { commandValidate } from "./commands/validate.js";
|
|
9
|
+
|
|
10
|
+
const VERSION = "0.1.0";
|
|
11
|
+
|
|
12
|
+
function helpText() {
|
|
13
|
+
return `atavi
|
|
14
|
+
|
|
15
|
+
Host-agnostic multi-agent iterative research refinement protocol.
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
atavi --help
|
|
19
|
+
atavi --version
|
|
20
|
+
atavi --path
|
|
21
|
+
atavi init [target]
|
|
22
|
+
atavi migrate [target]
|
|
23
|
+
atavi memory-export [target] [output]
|
|
24
|
+
atavi memory-import <source> [target]
|
|
25
|
+
atavi doctor
|
|
26
|
+
atavi validate [target]
|
|
27
|
+
atavi resume-check [target]
|
|
28
|
+
|
|
29
|
+
Commands:
|
|
30
|
+
--path Print the absolute path to the packaged protocol directory.
|
|
31
|
+
init Scaffold a .atavi workspace in the target directory.
|
|
32
|
+
migrate Add missing scaffold files and schema metadata to an existing workspace.
|
|
33
|
+
memory-export Copy `.atavi/memory` to an export directory.
|
|
34
|
+
memory-import Copy memory files into `.atavi/memory` without overwriting existing entries.
|
|
35
|
+
doctor Verify packaged protocol files and basic host prerequisites.
|
|
36
|
+
validate Validate the scaffolded .atavi/config.json contract.
|
|
37
|
+
resume-check Validate `.atavi/config.json` and `.atavi/status.md` for resume safety.
|
|
38
|
+
|
|
39
|
+
Notes:
|
|
40
|
+
atavi is intentionally thin. The host AI runs the protocol.
|
|
41
|
+
This package ships the protocol, agent role files, templates, and scaffold helpers.`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function runCli(argv, io = process) {
|
|
45
|
+
const [command, ...rest] = argv;
|
|
46
|
+
|
|
47
|
+
if (!command || command === "--help" || command === "-h" || command === "help") {
|
|
48
|
+
io.stdout.write(`${helpText()}\n`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (command === "--version" || command === "-v" || command === "version") {
|
|
53
|
+
io.stdout.write(`${VERSION}\n`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (command === "--path" || command === "path") {
|
|
58
|
+
await commandPath(io);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (command === "init") {
|
|
63
|
+
await commandInit(rest, io);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (command === "doctor") {
|
|
68
|
+
await commandDoctor(io);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (command === "memory-export") {
|
|
73
|
+
await commandMemoryExport(rest, io);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (command === "memory-import") {
|
|
78
|
+
await commandMemoryImport(rest, io);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (command === "migrate") {
|
|
83
|
+
await commandMigrate(rest, io);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (command === "validate") {
|
|
88
|
+
await commandValidate(rest, io);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (command === "resume-check") {
|
|
93
|
+
await commandResumeCheck(rest, io);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
throw new Error(`Unknown command: ${command}`);
|
|
98
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { protocolFiles, protocolRoot, templateFiles } from "../lib/protocol-manifest.js";
|
|
5
|
+
|
|
6
|
+
async function canRead(filePath) {
|
|
7
|
+
try {
|
|
8
|
+
await access(filePath, constants.R_OK);
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function commandDoctor(io) {
|
|
16
|
+
const root = protocolRoot();
|
|
17
|
+
const required = [...protocolFiles(), ...templateFiles()].map((relativePath) => path.join(root, relativePath));
|
|
18
|
+
const missing = [];
|
|
19
|
+
|
|
20
|
+
for (const filePath of required) {
|
|
21
|
+
if (!(await canRead(filePath))) {
|
|
22
|
+
missing.push(filePath);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (missing.length > 0) {
|
|
27
|
+
io.stdout.write("ATAVI doctor: FAIL\n");
|
|
28
|
+
for (const filePath of missing) {
|
|
29
|
+
io.stdout.write(`missing ${filePath}\n`);
|
|
30
|
+
}
|
|
31
|
+
throw new Error("Packaged protocol is incomplete.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
io.stdout.write("ATAVI doctor: OK\n");
|
|
35
|
+
io.stdout.write(`protocol root: ${root}\n`);
|
|
36
|
+
io.stdout.write("required files: present\n");
|
|
37
|
+
io.stdout.write("host requirement: your AI environment must support file I/O and web search for Scout runs\n");
|
|
38
|
+
}
|
|
39
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { ensureDirectory, pathExists, writeFileIfMissing } from "../lib/filesystem.js";
|
|
3
|
+
import { scaffoldFiles } from "../lib/protocol-manifest.js";
|
|
4
|
+
|
|
5
|
+
export async function commandInit(args, io) {
|
|
6
|
+
const targetArg = args.find((arg) => !arg.startsWith("-")) ?? ".";
|
|
7
|
+
const targetDir = path.resolve(process.cwd(), targetArg);
|
|
8
|
+
const workspaceDir = path.join(targetDir, ".atavi");
|
|
9
|
+
|
|
10
|
+
await ensureDirectory(workspaceDir);
|
|
11
|
+
|
|
12
|
+
let created = 0;
|
|
13
|
+
|
|
14
|
+
for (const file of scaffoldFiles()) {
|
|
15
|
+
const destination = path.join(workspaceDir, file.relativePath);
|
|
16
|
+
const didCreate = await writeFileIfMissing(destination, file.contents);
|
|
17
|
+
if (didCreate) {
|
|
18
|
+
created += 1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const status = (await pathExists(path.join(workspaceDir, "status.md"))) ? "ready" : "incomplete";
|
|
23
|
+
io.stdout.write(`Scaffolded ${workspaceDir}\n`);
|
|
24
|
+
io.stdout.write(`Created ${created} new file(s). Workspace status: ${status}.\n`);
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { exportMemory, resolveMemoryDirectory } from "../lib/memory.js";
|
|
3
|
+
|
|
4
|
+
export async function commandMemoryExport(args, io) {
|
|
5
|
+
const targetArg = args.find((arg) => !arg.startsWith("-")) ?? ".";
|
|
6
|
+
const outputArg = args.filter((arg) => !arg.startsWith("-"))[1] ?? path.join(targetArg, ".atavi", "exports", "memory");
|
|
7
|
+
const sourceMemoryDir = await resolveMemoryDirectory(targetArg);
|
|
8
|
+
|
|
9
|
+
if (!sourceMemoryDir) {
|
|
10
|
+
io.stdout.write("ATAVI memory-export: FAIL\n");
|
|
11
|
+
io.stdout.write(`missing memory ${path.resolve(targetArg)}\n`);
|
|
12
|
+
throw new Error("ATAVI memory directory was not found.");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const outputDir = path.resolve(outputArg);
|
|
16
|
+
const result = await exportMemory(sourceMemoryDir, outputDir);
|
|
17
|
+
|
|
18
|
+
io.stdout.write("ATAVI memory-export: OK\n");
|
|
19
|
+
io.stdout.write(`source: ${sourceMemoryDir}\n`);
|
|
20
|
+
io.stdout.write(`output: ${outputDir}\n`);
|
|
21
|
+
io.stdout.write(`exported files: ${result.exportedFiles}\n`);
|
|
22
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { mkdir } from "node:fs/promises";
|
|
3
|
+
import { importMemory, resolveMemoryDirectory } from "../lib/memory.js";
|
|
4
|
+
|
|
5
|
+
export async function commandMemoryImport(args, io) {
|
|
6
|
+
const positionalArgs = args.filter((arg) => !arg.startsWith("-"));
|
|
7
|
+
const sourceArg = positionalArgs[0];
|
|
8
|
+
const targetArg = positionalArgs[1] ?? ".";
|
|
9
|
+
|
|
10
|
+
if (!sourceArg) {
|
|
11
|
+
throw new Error("memory-import requires a source path");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const sourceMemoryDir = await resolveMemoryDirectory(sourceArg);
|
|
15
|
+
if (!sourceMemoryDir) {
|
|
16
|
+
io.stdout.write("ATAVI memory-import: FAIL\n");
|
|
17
|
+
io.stdout.write(`missing memory ${path.resolve(sourceArg)}\n`);
|
|
18
|
+
throw new Error("ATAVI source memory directory was not found.");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const targetMemoryDir = path.join(path.resolve(targetArg), ".atavi", "memory");
|
|
22
|
+
await mkdir(targetMemoryDir, { recursive: true });
|
|
23
|
+
|
|
24
|
+
const result = await importMemory(sourceMemoryDir, targetMemoryDir);
|
|
25
|
+
|
|
26
|
+
io.stdout.write("ATAVI memory-import: OK\n");
|
|
27
|
+
io.stdout.write(`source: ${sourceMemoryDir}\n`);
|
|
28
|
+
io.stdout.write(`target: ${targetMemoryDir}\n`);
|
|
29
|
+
io.stdout.write(`imported files: ${result.importedFiles}\n`);
|
|
30
|
+
io.stdout.write(`skipped files: ${result.skippedFiles}\n`);
|
|
31
|
+
}
|