@voxslopuli/openagentsy 0.0.0-stage → 0.2.1
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/LICENSE +674 -0
- package/README.md +21 -2
- package/dist/adapter-dependency.test.d.ts +2 -0
- package/dist/adapter-dependency.test.d.ts.map +1 -0
- package/dist/adapter-dependency.test.js +51 -0
- package/dist/adapter-dependency.test.js.map +1 -0
- package/dist/commands/approve.d.ts +63 -0
- package/dist/commands/approve.d.ts.map +1 -0
- package/dist/commands/approve.js +218 -0
- package/dist/commands/approve.js.map +1 -0
- package/dist/commands/approve.test.d.ts +2 -0
- package/dist/commands/approve.test.d.ts.map +1 -0
- package/dist/commands/approve.test.js +219 -0
- package/dist/commands/approve.test.js.map +1 -0
- package/dist/commands/audit.d.ts +74 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +230 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/audit.test.d.ts +2 -0
- package/dist/commands/audit.test.d.ts.map +1 -0
- package/dist/commands/audit.test.js +194 -0
- package/dist/commands/audit.test.js.map +1 -0
- package/dist/commands/board.d.ts +33 -0
- package/dist/commands/board.d.ts.map +1 -0
- package/dist/commands/board.js +65 -0
- package/dist/commands/board.js.map +1 -0
- package/dist/commands/build.d.ts +17 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +145 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/conformance.d.ts +31 -0
- package/dist/commands/conformance.d.ts.map +1 -0
- package/dist/commands/conformance.js +57 -0
- package/dist/commands/conformance.js.map +1 -0
- package/dist/commands/conformance.test.d.ts +2 -0
- package/dist/commands/conformance.test.d.ts.map +1 -0
- package/dist/commands/conformance.test.js +74 -0
- package/dist/commands/conformance.test.js.map +1 -0
- package/dist/commands/doctor.d.ts +132 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +768 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/doctor.test.d.ts +2 -0
- package/dist/commands/doctor.test.d.ts.map +1 -0
- package/dist/commands/doctor.test.js +329 -0
- package/dist/commands/doctor.test.js.map +1 -0
- package/dist/commands/ledger.d.ts +109 -0
- package/dist/commands/ledger.d.ts.map +1 -0
- package/dist/commands/ledger.js +286 -0
- package/dist/commands/ledger.js.map +1 -0
- package/dist/commands/ledger.test.d.ts +2 -0
- package/dist/commands/ledger.test.d.ts.map +1 -0
- package/dist/commands/ledger.test.js +238 -0
- package/dist/commands/ledger.test.js.map +1 -0
- package/dist/commands/lessons.d.ts +73 -0
- package/dist/commands/lessons.d.ts.map +1 -0
- package/dist/commands/lessons.js +97 -0
- package/dist/commands/lessons.js.map +1 -0
- package/dist/commands/lessons.test.d.ts +2 -0
- package/dist/commands/lessons.test.d.ts.map +1 -0
- package/dist/commands/lessons.test.js +146 -0
- package/dist/commands/lessons.test.js.map +1 -0
- package/dist/commands/models.d.ts +49 -0
- package/dist/commands/models.d.ts.map +1 -0
- package/dist/commands/models.js +125 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/report.d.ts +57 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +164 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/report.test.d.ts +2 -0
- package/dist/commands/report.test.d.ts.map +1 -0
- package/dist/commands/report.test.js +294 -0
- package/dist/commands/report.test.js.map +1 -0
- package/dist/commands/scope.d.ts +34 -0
- package/dist/commands/scope.d.ts.map +1 -0
- package/dist/commands/scope.js +78 -0
- package/dist/commands/scope.js.map +1 -0
- package/dist/commands/scope.test.d.ts +2 -0
- package/dist/commands/scope.test.d.ts.map +1 -0
- package/dist/commands/scope.test.js +98 -0
- package/dist/commands/scope.test.js.map +1 -0
- package/dist/commands/setup.d.ts +31 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +93 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/waivers.d.ts +47 -0
- package/dist/commands/waivers.d.ts.map +1 -0
- package/dist/commands/waivers.js +68 -0
- package/dist/commands/waivers.js.map +1 -0
- package/dist/commands/waivers.test.d.ts +2 -0
- package/dist/commands/waivers.test.d.ts.map +1 -0
- package/dist/commands/waivers.test.js +64 -0
- package/dist/commands/waivers.test.js.map +1 -0
- package/dist/generate/agent.d.ts +19 -0
- package/dist/generate/agent.d.ts.map +1 -0
- package/dist/generate/agent.js +35 -0
- package/dist/generate/agent.js.map +1 -0
- package/dist/generate/agent.test.d.ts +2 -0
- package/dist/generate/agent.test.d.ts.map +1 -0
- package/dist/generate/agent.test.js +245 -0
- package/dist/generate/agent.test.js.map +1 -0
- package/dist/generate/commands.d.ts +15 -0
- package/dist/generate/commands.d.ts.map +1 -0
- package/dist/generate/commands.js +59 -0
- package/dist/generate/commands.js.map +1 -0
- package/dist/generate/lock.d.ts +18 -0
- package/dist/generate/lock.d.ts.map +1 -0
- package/dist/generate/lock.js +26 -0
- package/dist/generate/lock.js.map +1 -0
- package/dist/generate/prompt.d.ts +11 -0
- package/dist/generate/prompt.d.ts.map +1 -0
- package/dist/generate/prompt.js +114 -0
- package/dist/generate/prompt.js.map +1 -0
- package/dist/generate/prompt.test.d.ts +2 -0
- package/dist/generate/prompt.test.d.ts.map +1 -0
- package/dist/generate/prompt.test.js +59 -0
- package/dist/generate/prompt.test.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +448 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +237 -0
- package/dist/index.test.js.map +1 -0
- package/dist/opencode.d.ts +29 -0
- package/dist/opencode.d.ts.map +1 -0
- package/dist/opencode.js +125 -0
- package/dist/opencode.js.map +1 -0
- package/dist/plugin-bundle.test.d.ts +2 -0
- package/dist/plugin-bundle.test.d.ts.map +1 -0
- package/dist/plugin-bundle.test.js +43 -0
- package/dist/plugin-bundle.test.js.map +1 -0
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +46 -0
- package/dist/plugin.js.map +1 -0
- package/dist/quality-skills.test.d.ts +2 -0
- package/dist/quality-skills.test.d.ts.map +1 -0
- package/dist/quality-skills.test.js +141 -0
- package/dist/quality-skills.test.js.map +1 -0
- package/dist/report/footprint.d.ts +12 -0
- package/dist/report/footprint.d.ts.map +1 -0
- package/dist/report/footprint.js +121 -0
- package/dist/report/footprint.js.map +1 -0
- package/dist/report/ledger.d.ts +27 -0
- package/dist/report/ledger.d.ts.map +1 -0
- package/dist/report/ledger.js +197 -0
- package/dist/report/ledger.js.map +1 -0
- package/dist/report/oversight.d.ts +21 -0
- package/dist/report/oversight.d.ts.map +1 -0
- package/dist/report/oversight.js +146 -0
- package/dist/report/oversight.js.map +1 -0
- package/dist/report/policy-firing.test.d.ts +2 -0
- package/dist/report/policy-firing.test.d.ts.map +1 -0
- package/dist/report/policy-firing.test.js +68 -0
- package/dist/report/policy-firing.test.js.map +1 -0
- package/dist/report/scope.d.ts +64 -0
- package/dist/report/scope.d.ts.map +1 -0
- package/dist/report/scope.js +146 -0
- package/dist/report/scope.js.map +1 -0
- package/dist/who.d.ts +9 -0
- package/dist/who.d.ts.map +1 -0
- package/dist/who.js +11 -0
- package/dist/who.js.map +1 -0
- package/package.json +55 -4
- package/plugin/openagentsy.js +39478 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type BuildOptions = {
|
|
2
|
+
/** The workspace: the roles, the templates and the output live here. */
|
|
3
|
+
workspace: string;
|
|
4
|
+
/** The state root: the model lock lives here. */
|
|
5
|
+
stateRoot: string;
|
|
6
|
+
rolesPath?: string;
|
|
7
|
+
lockPath?: string;
|
|
8
|
+
outDir?: string;
|
|
9
|
+
};
|
|
10
|
+
export type BuildResult = {
|
|
11
|
+
agents: string[];
|
|
12
|
+
commands: string[];
|
|
13
|
+
skills: string[];
|
|
14
|
+
warnings: string[];
|
|
15
|
+
};
|
|
16
|
+
export declare function runBuild(options: BuildOptions): Promise<BuildResult>;
|
|
17
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,YAAY,GAAG;IACzB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AA4HF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAsC1E"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, unlink, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { agentIdFor, agentIdOf, loadRoles } from '@openagentsy/core';
|
|
4
|
+
import { agentFileName, renderAgent } from '../generate/agent.js';
|
|
5
|
+
import { COMMANDS, renderCommand } from '../generate/commands.js';
|
|
6
|
+
import { lockEntryFor, lockVariants, readModelLock } from '../generate/lock.js';
|
|
7
|
+
async function writeFileAt(path, content) {
|
|
8
|
+
await mkdir(dirname(path), { recursive: true });
|
|
9
|
+
await writeFile(path, content);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Remove the agent files a previous build wrote that this one does not.
|
|
13
|
+
*
|
|
14
|
+
* A file the build wrote is one whose name carries the agent prefix, or one
|
|
15
|
+
* whose name is the agent name of a role in the roles file. A role may name
|
|
16
|
+
* its own agent, and that name does not carry the prefix, so a role that was
|
|
17
|
+
* renamed or removed leaves its file behind unless the name is looked up in
|
|
18
|
+
* the roles file as well.
|
|
19
|
+
*
|
|
20
|
+
* A file that is neither is not ours, so it is left alone.
|
|
21
|
+
*/
|
|
22
|
+
async function removeStaleAgents(agentsDir, current, knownNames) {
|
|
23
|
+
let entries;
|
|
24
|
+
try {
|
|
25
|
+
entries = await readdir(agentsDir, { withFileTypes: true });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const entry of entries) {
|
|
31
|
+
if (!entry.isFile())
|
|
32
|
+
continue;
|
|
33
|
+
if (!entry.name.endsWith('.md'))
|
|
34
|
+
continue;
|
|
35
|
+
const name = entry.name.replace(/\.md$/, '');
|
|
36
|
+
if (current.has(name))
|
|
37
|
+
continue;
|
|
38
|
+
if (!name.startsWith('oa-') && !knownNames.has(name))
|
|
39
|
+
continue;
|
|
40
|
+
await unlink(join(agentsDir, entry.name));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Copy a directory, with everything in it.
|
|
45
|
+
*
|
|
46
|
+
* A skill may link to reference files beside its SKILL.md, and a copy
|
|
47
|
+
* that took only the SKILL.md would leave those links pointing at
|
|
48
|
+
* nothing. The whole tree is copied, so a file the skill names is
|
|
49
|
+
* there when the skill is read.
|
|
50
|
+
*/
|
|
51
|
+
async function copyTree(from, to) {
|
|
52
|
+
const entries = await readdir(from, { withFileTypes: true });
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
const source = join(from, entry.name);
|
|
55
|
+
const target = join(to, entry.name);
|
|
56
|
+
if (entry.isDirectory()) {
|
|
57
|
+
await mkdir(target, { recursive: true });
|
|
58
|
+
await copyTree(source, target);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
await writeFileAt(target, await readFile(source));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function copySkills(sourceDir, targetDir) {
|
|
65
|
+
const copied = [];
|
|
66
|
+
const warnings = [];
|
|
67
|
+
let entries;
|
|
68
|
+
try {
|
|
69
|
+
entries = await readdir(sourceDir, { withFileTypes: true });
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return { copied, warnings };
|
|
73
|
+
}
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
if (!entry.isDirectory())
|
|
76
|
+
continue;
|
|
77
|
+
const skillDir = join(sourceDir, entry.name);
|
|
78
|
+
try {
|
|
79
|
+
await readFile(join(skillDir, 'SKILL.md'), 'utf8');
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
warnings.push(`skill "${entry.name}" has no SKILL.md, skipped`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
await copyTree(skillDir, join(targetDir, entry.name));
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
warnings.push(`skill "${entry.name}" could not be copied: ${error.message}`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
copied.push(entry.name);
|
|
93
|
+
}
|
|
94
|
+
return { copied, warnings };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Render every role's agent file, and return the ids that were written.
|
|
98
|
+
*
|
|
99
|
+
* The roles and the templates are the workspace's, and the model lock is
|
|
100
|
+
* the state root's: the lock is the choice of models the project made, and
|
|
101
|
+
* a worktree of the project has the same lock as the project.
|
|
102
|
+
*/
|
|
103
|
+
async function renderAgents(roles, lock, agentsDir) {
|
|
104
|
+
const ids = [];
|
|
105
|
+
for (const role of Object.values(roles.roles)) {
|
|
106
|
+
const entry = lockEntryFor(lock, role.name);
|
|
107
|
+
const variants = lockVariants(entry);
|
|
108
|
+
const content = renderAgent(role, roles, {
|
|
109
|
+
...(entry?.model ? { model: entry.model } : {}),
|
|
110
|
+
// The agent frontmatter pins the variant of the model it starts on.
|
|
111
|
+
...(variants.start !== undefined ? { modelVariant: variants.start } : {}),
|
|
112
|
+
effort: variants,
|
|
113
|
+
});
|
|
114
|
+
await writeFileAt(join(agentsDir, agentFileName(role)), content);
|
|
115
|
+
ids.push(agentIdOf(role));
|
|
116
|
+
}
|
|
117
|
+
return ids;
|
|
118
|
+
}
|
|
119
|
+
export async function runBuild(options) {
|
|
120
|
+
const { workspace, stateRoot } = options;
|
|
121
|
+
const rolesPath = options.rolesPath ?? join(workspace, 'roles.yaml');
|
|
122
|
+
const lockPath = options.lockPath ?? join(stateRoot, 'openagentsy.models.lock.json');
|
|
123
|
+
const outDir = options.outDir ?? join(workspace, '.opencode');
|
|
124
|
+
const roles = await loadRoles(rolesPath);
|
|
125
|
+
const lock = await readModelLock(lockPath);
|
|
126
|
+
const warnings = [];
|
|
127
|
+
if (!lock) {
|
|
128
|
+
warnings.push(`no model lock at ${lockPath}, generated agents inherit the OpenCode default model`);
|
|
129
|
+
}
|
|
130
|
+
const agents = await renderAgents(roles, lock, join(outDir, 'agents'));
|
|
131
|
+
const knownNames = new Set(Object.values(roles.roles)
|
|
132
|
+
.map((role) => role.agentName)
|
|
133
|
+
.filter((name) => name !== undefined));
|
|
134
|
+
await removeStaleAgents(join(outDir, 'agents'), new Set(agents), knownNames);
|
|
135
|
+
const commands = [];
|
|
136
|
+
for (const command of COMMANDS) {
|
|
137
|
+
const path = join(outDir, 'commands', `${command.name}.md`);
|
|
138
|
+
await writeFileAt(path, renderCommand(command, agentIdFor(roles, command.role)));
|
|
139
|
+
commands.push(command.name);
|
|
140
|
+
}
|
|
141
|
+
const skills = await copySkills(join(workspace, 'templates', '.opencode', 'skills'), join(outDir, 'skills'));
|
|
142
|
+
warnings.push(...skills.warnings);
|
|
143
|
+
return { agents, commands, skills: skills.copied, warnings };
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ProjectRoots } from '@openagentsy/core';
|
|
2
|
+
import { type ConformanceReport } from '@openagentsy/core';
|
|
3
|
+
/**
|
|
4
|
+
* `oa conformance`: what is proven, observed or unverified (§11).
|
|
5
|
+
*
|
|
6
|
+
* The report says, per capability of the host, which of the three states it
|
|
7
|
+
* is in, and it shows the evidence of an observed capability so a reader can
|
|
8
|
+
* see where the observation came from. A capability with no observation and
|
|
9
|
+
* no static proof is `unverified`, and the report says so rather than
|
|
10
|
+
* leaving it out.
|
|
11
|
+
*
|
|
12
|
+
* The command never writes. The evidence of a project is written by the
|
|
13
|
+
* session that observed it, and a report that wrote would be a report that
|
|
14
|
+
* could make a capability observed without anything having been observed.
|
|
15
|
+
*/
|
|
16
|
+
/** The options the command takes. */
|
|
17
|
+
export type ConformanceOptions = {
|
|
18
|
+
/** The moment the report is stamped with, when a caller holds one. */
|
|
19
|
+
now?: string | undefined;
|
|
20
|
+
};
|
|
21
|
+
/** Build the report of a project. */
|
|
22
|
+
export declare function runConformance(roots: ProjectRoots, options?: ConformanceOptions): Promise<ConformanceReport>;
|
|
23
|
+
/**
|
|
24
|
+
* The report, as plain text.
|
|
25
|
+
*
|
|
26
|
+
* One block per capability, the state first, and the evidence under it when
|
|
27
|
+
* there is one. The lines are plain text with no colour, so the report can
|
|
28
|
+
* be read in a pipe, in a terminal and in a ticket.
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatConformanceReport(report: ConformanceReport): string;
|
|
31
|
+
//# sourceMappingURL=conformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../../src/commands/conformance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAA0B,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEnF;;;;;;;;;;;;GAYG;AAEH,qCAAqC;AACrC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,CAAC;AAEF,qCAAqC;AACrC,wBAAsB,cAAc,CAClC,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAM5B;AAOD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CA4CzE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { buildConformanceReport } from '@openagentsy/core';
|
|
2
|
+
/** Build the report of a project. */
|
|
3
|
+
export async function runConformance(roots, options = {}) {
|
|
4
|
+
return buildConformanceReport({
|
|
5
|
+
workspace: roots.workspace,
|
|
6
|
+
stateRoot: roots.stateRoot,
|
|
7
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
/** The state of a capability, as it is printed. */
|
|
11
|
+
function stateOf(entry) {
|
|
12
|
+
return entry.state;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The report, as plain text.
|
|
16
|
+
*
|
|
17
|
+
* One block per capability, the state first, and the evidence under it when
|
|
18
|
+
* there is one. The lines are plain text with no colour, so the report can
|
|
19
|
+
* be read in a pipe, in a terminal and in a ticket.
|
|
20
|
+
*/
|
|
21
|
+
export function formatConformanceReport(report) {
|
|
22
|
+
const lines = [];
|
|
23
|
+
lines.push(`OpenAgentsy conformance — ${report.counts.total} capabilities, host v2`);
|
|
24
|
+
lines.push(` observed ${report.counts.observed} · proven_static ${report.counts.proven_static} · unverified ${report.counts.unverified}`);
|
|
25
|
+
lines.push('');
|
|
26
|
+
for (const entry of report.capabilities) {
|
|
27
|
+
const reference = entry.verifyRef === undefined ? '' : ` ${entry.verifyRef}`;
|
|
28
|
+
lines.push(` ${entry.id.padEnd(26)}${stateOf(entry).padEnd(15)}${reference}`);
|
|
29
|
+
lines.push(` ${entry.title}`);
|
|
30
|
+
if (entry.evidence.length === 0) {
|
|
31
|
+
lines.push(' no observation');
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
for (const observation of entry.evidence) {
|
|
35
|
+
const source = `${observation.source.kind} ${observation.source.ref}`;
|
|
36
|
+
lines.push(` ${observation.eventType} ${observation.at} ${observation.kind} ${source}`);
|
|
37
|
+
lines.push(` ${observation.note}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
lines.push('');
|
|
41
|
+
if (report.pluginOrderWarnings.length === 0) {
|
|
42
|
+
lines.push(' plugin-order warnings: 0');
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
lines.push(` plugin-order warnings: ${report.pluginOrderWarnings.length}`);
|
|
46
|
+
for (const warning of report.pluginOrderWarnings) {
|
|
47
|
+
lines.push(` ${warning.plugin}: ${warning.detail}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
lines.push(` evidence: ${report.evidencePath}${report.evidenceOnDisk ? '' : ' (the file is not on disk; the seed is in the report)'}`);
|
|
51
|
+
lines.push(` void capabilities: ${report.voided.length} (the V1 entries of the plan; the project speaks OpenCode 2 only)`);
|
|
52
|
+
if (report.evidenceError !== undefined) {
|
|
53
|
+
lines.push(` the evidence file could not be read: ${report.evidenceError}`);
|
|
54
|
+
}
|
|
55
|
+
return `${lines.join('\n')}\n`;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=conformance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../../src/commands/conformance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.test.d.ts","sourceRoot":"","sources":["../../src/commands/conformance.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { main } from '../index.js';
|
|
6
|
+
import { formatConformanceReport, runConformance } from './conformance.js';
|
|
7
|
+
let root;
|
|
8
|
+
let written;
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
root = await mkdtemp(join(tmpdir(), 'openagentsy-conformance-cli-'));
|
|
11
|
+
written = [];
|
|
12
|
+
vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
13
|
+
written.push(String(chunk));
|
|
14
|
+
return true;
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
afterEach(async () => {
|
|
18
|
+
vi.restoreAllMocks();
|
|
19
|
+
await rm(root, { recursive: true, force: true });
|
|
20
|
+
});
|
|
21
|
+
describe('the conformance report', () => {
|
|
22
|
+
it('reports every capability of the registry, with its state', async () => {
|
|
23
|
+
const report = await runConformance({ workspace: root, stateRoot: root });
|
|
24
|
+
expect(report.capabilities.length).toBe(18);
|
|
25
|
+
// The root of the test holds no project, so the local offload router is
|
|
26
|
+
// not there and its capability has no static proof. The ten observed
|
|
27
|
+
// capabilities carry the seed, and the seed is in the package.
|
|
28
|
+
expect(report.counts.observed).toBe(10);
|
|
29
|
+
expect(report.counts.proven_static).toBe(5);
|
|
30
|
+
expect(report.counts.unverified).toBe(3);
|
|
31
|
+
});
|
|
32
|
+
it('prints the state of every capability', async () => {
|
|
33
|
+
const report = await runConformance({ workspace: root, stateRoot: root });
|
|
34
|
+
const text = formatConformanceReport(report);
|
|
35
|
+
expect(text).toContain('permission-hook-agent');
|
|
36
|
+
expect(text).toContain('observed');
|
|
37
|
+
expect(text).toContain('unverified');
|
|
38
|
+
expect(text).toContain('proven_static');
|
|
39
|
+
});
|
|
40
|
+
it('prints the evidence of an observed capability, and where it came from', async () => {
|
|
41
|
+
const report = await runConformance({ workspace: root, stateRoot: root });
|
|
42
|
+
const text = formatConformanceReport(report);
|
|
43
|
+
expect(text).toContain('board-record 688');
|
|
44
|
+
expect(text).toContain('the raw permission event of a live 2.1.3 server carried agent build');
|
|
45
|
+
});
|
|
46
|
+
it('says so when a capability has no observation', async () => {
|
|
47
|
+
const report = await runConformance({ workspace: root, stateRoot: root });
|
|
48
|
+
const text = formatConformanceReport(report);
|
|
49
|
+
expect(text).toContain('no observation');
|
|
50
|
+
});
|
|
51
|
+
it('names the plugin-order warnings and the void capabilities', async () => {
|
|
52
|
+
const report = await runConformance({ workspace: root, stateRoot: root });
|
|
53
|
+
const text = formatConformanceReport(report);
|
|
54
|
+
expect(text).toContain('plugin-order warnings: 0');
|
|
55
|
+
expect(text).toContain('void capabilities: 11');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe('the conformance command', () => {
|
|
59
|
+
it('prints the report', async () => {
|
|
60
|
+
const code = await main(['conformance', '--root', root]);
|
|
61
|
+
expect(code).toBe(0);
|
|
62
|
+
const output = written.join('');
|
|
63
|
+
expect(output).toContain('OpenAgentsy conformance');
|
|
64
|
+
expect(output).toContain('permission-hook-agent');
|
|
65
|
+
});
|
|
66
|
+
it('prints the report as JSON when it is asked to', async () => {
|
|
67
|
+
const code = await main(['conformance', '--root', root, '--json']);
|
|
68
|
+
expect(code).toBe(0);
|
|
69
|
+
const report = JSON.parse(written.join(''));
|
|
70
|
+
expect(report.counts.total).toBe(18);
|
|
71
|
+
expect(report.capabilities[0].state).toBeDefined();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=conformance.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.test.js","sourceRoot":"","sources":["../../src/commands/conformance.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { type ProjectRoots, type Target } from '@openagentsy/core';
|
|
2
|
+
import { type FoundSkill, type OpenCodeVersion } from '../opencode.js';
|
|
3
|
+
export type ConfigReport = {
|
|
4
|
+
path: string | undefined;
|
|
5
|
+
/** Every config file OpenCode merges, in the order it reads them. */
|
|
6
|
+
paths: string[];
|
|
7
|
+
exists: boolean;
|
|
8
|
+
compactionAuto: unknown;
|
|
9
|
+
compactionPrune: unknown;
|
|
10
|
+
mcpServers: string[];
|
|
11
|
+
plugins: string[];
|
|
12
|
+
};
|
|
13
|
+
export type RoleReport = {
|
|
14
|
+
role: string;
|
|
15
|
+
agent: string;
|
|
16
|
+
model: string;
|
|
17
|
+
evidence: string;
|
|
18
|
+
};
|
|
19
|
+
export type BoardReport = {
|
|
20
|
+
root: string;
|
|
21
|
+
databasePath: string;
|
|
22
|
+
databaseExists: boolean;
|
|
23
|
+
leases: number;
|
|
24
|
+
auditPath: string;
|
|
25
|
+
auditExists: boolean;
|
|
26
|
+
auditEntries: number;
|
|
27
|
+
};
|
|
28
|
+
export type PluginReport = {
|
|
29
|
+
path: string;
|
|
30
|
+
installed: boolean;
|
|
31
|
+
bundlePath: string;
|
|
32
|
+
bundleBuilt: boolean;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* What a fresh render of the roles says about the installed files.
|
|
36
|
+
*
|
|
37
|
+
* The generated files are written by a person who runs the generator, so an
|
|
38
|
+
* out-of-band edit is invisible until something compares the tree with the
|
|
39
|
+
* generator. The doctor does that comparison, and it never writes into the
|
|
40
|
+
* project: the render happens in a temporary directory.
|
|
41
|
+
*/
|
|
42
|
+
export type RegenerationReport = {
|
|
43
|
+
/** The generated files that disagree with a fresh render. */
|
|
44
|
+
drifted: string[];
|
|
45
|
+
/** The command that reconciles the tree. */
|
|
46
|
+
reconcile: string;
|
|
47
|
+
/** Why the comparison did not run, when it did not run. */
|
|
48
|
+
error?: string | undefined;
|
|
49
|
+
};
|
|
50
|
+
/** One of the five files that decide how this project is configured. */
|
|
51
|
+
export type ConfigAuthority = {
|
|
52
|
+
/** The file, or the files the host merges. */
|
|
53
|
+
path: string;
|
|
54
|
+
exists: boolean;
|
|
55
|
+
/** What the file is authoritative for, in one line. */
|
|
56
|
+
authority: string;
|
|
57
|
+
/** Who writes it. */
|
|
58
|
+
writtenBy: string;
|
|
59
|
+
/** True when the file is not the tool's to write. */
|
|
60
|
+
protected: boolean;
|
|
61
|
+
};
|
|
62
|
+
/** The Phase 2 keys, with the defaults filled in. */
|
|
63
|
+
export type Phase2Config = {
|
|
64
|
+
tasks: {
|
|
65
|
+
path: string;
|
|
66
|
+
prefix: string;
|
|
67
|
+
idLength: number;
|
|
68
|
+
};
|
|
69
|
+
memory: {
|
|
70
|
+
maxTextChars: number;
|
|
71
|
+
inboxLimit: number;
|
|
72
|
+
};
|
|
73
|
+
footprint: {
|
|
74
|
+
showWarming: boolean;
|
|
75
|
+
prefill: boolean;
|
|
76
|
+
gridRegion: string;
|
|
77
|
+
localDeviceWatts: [number, number];
|
|
78
|
+
models: string[];
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export type ConfigMap = {
|
|
82
|
+
authorities: ConfigAuthority[];
|
|
83
|
+
effective: Phase2Config;
|
|
84
|
+
/** The places two files answer the same question. */
|
|
85
|
+
overlaps: string[];
|
|
86
|
+
};
|
|
87
|
+
/** One of the first-party documents the framework ships at the project root. */
|
|
88
|
+
export type FirstPartyDocument = {
|
|
89
|
+
/** The file name, at the root of the project. */
|
|
90
|
+
file: string;
|
|
91
|
+
/** What the document is for, in one line. */
|
|
92
|
+
what: string;
|
|
93
|
+
/** Where it was looked for. */
|
|
94
|
+
path: string;
|
|
95
|
+
/** Whether the project carries it. */
|
|
96
|
+
exists: boolean;
|
|
97
|
+
/** The version it declares, when it declares one. */
|
|
98
|
+
version: string | undefined;
|
|
99
|
+
};
|
|
100
|
+
/** The first-party documents of a project, and the version they agree on. */
|
|
101
|
+
export type DocumentsReport = {
|
|
102
|
+
documents: FirstPartyDocument[];
|
|
103
|
+
/** The version every document declares, when they all declare the same one. */
|
|
104
|
+
version: string | undefined;
|
|
105
|
+
};
|
|
106
|
+
export type DoctorReport = {
|
|
107
|
+
opencode: {
|
|
108
|
+
version: OpenCodeVersion | undefined;
|
|
109
|
+
target: Target;
|
|
110
|
+
};
|
|
111
|
+
config: ConfigReport;
|
|
112
|
+
configMap: ConfigMap;
|
|
113
|
+
plugin: PluginReport;
|
|
114
|
+
roles: RoleReport[];
|
|
115
|
+
skills: FoundSkill[];
|
|
116
|
+
board: BoardReport;
|
|
117
|
+
regeneration: RegenerationReport;
|
|
118
|
+
documents: DocumentsReport;
|
|
119
|
+
warnings: string[];
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* The doctor, as a person reads it.
|
|
123
|
+
*
|
|
124
|
+
* The report has two halves and they have two roots. The project half — the
|
|
125
|
+
* config, the roles, the skills and the installed plugin — is the
|
|
126
|
+
* workspace's, because those are the files of the project. The state half —
|
|
127
|
+
* the model lock, the board and the audit log — is the state root's, because
|
|
128
|
+
* those are the files of the project as a whole.
|
|
129
|
+
*/
|
|
130
|
+
export declare function runDoctor(roots: ProjectRoots): Promise<DoctorReport>;
|
|
131
|
+
export declare function formatDoctorReport(report: DoctorReport): string;
|
|
132
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|