@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.
Files changed (168) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +21 -2
  3. package/dist/adapter-dependency.test.d.ts +2 -0
  4. package/dist/adapter-dependency.test.d.ts.map +1 -0
  5. package/dist/adapter-dependency.test.js +51 -0
  6. package/dist/adapter-dependency.test.js.map +1 -0
  7. package/dist/commands/approve.d.ts +63 -0
  8. package/dist/commands/approve.d.ts.map +1 -0
  9. package/dist/commands/approve.js +218 -0
  10. package/dist/commands/approve.js.map +1 -0
  11. package/dist/commands/approve.test.d.ts +2 -0
  12. package/dist/commands/approve.test.d.ts.map +1 -0
  13. package/dist/commands/approve.test.js +219 -0
  14. package/dist/commands/approve.test.js.map +1 -0
  15. package/dist/commands/audit.d.ts +74 -0
  16. package/dist/commands/audit.d.ts.map +1 -0
  17. package/dist/commands/audit.js +230 -0
  18. package/dist/commands/audit.js.map +1 -0
  19. package/dist/commands/audit.test.d.ts +2 -0
  20. package/dist/commands/audit.test.d.ts.map +1 -0
  21. package/dist/commands/audit.test.js +194 -0
  22. package/dist/commands/audit.test.js.map +1 -0
  23. package/dist/commands/board.d.ts +33 -0
  24. package/dist/commands/board.d.ts.map +1 -0
  25. package/dist/commands/board.js +65 -0
  26. package/dist/commands/board.js.map +1 -0
  27. package/dist/commands/build.d.ts +17 -0
  28. package/dist/commands/build.d.ts.map +1 -0
  29. package/dist/commands/build.js +145 -0
  30. package/dist/commands/build.js.map +1 -0
  31. package/dist/commands/conformance.d.ts +31 -0
  32. package/dist/commands/conformance.d.ts.map +1 -0
  33. package/dist/commands/conformance.js +57 -0
  34. package/dist/commands/conformance.js.map +1 -0
  35. package/dist/commands/conformance.test.d.ts +2 -0
  36. package/dist/commands/conformance.test.d.ts.map +1 -0
  37. package/dist/commands/conformance.test.js +74 -0
  38. package/dist/commands/conformance.test.js.map +1 -0
  39. package/dist/commands/doctor.d.ts +132 -0
  40. package/dist/commands/doctor.d.ts.map +1 -0
  41. package/dist/commands/doctor.js +768 -0
  42. package/dist/commands/doctor.js.map +1 -0
  43. package/dist/commands/doctor.test.d.ts +2 -0
  44. package/dist/commands/doctor.test.d.ts.map +1 -0
  45. package/dist/commands/doctor.test.js +329 -0
  46. package/dist/commands/doctor.test.js.map +1 -0
  47. package/dist/commands/ledger.d.ts +109 -0
  48. package/dist/commands/ledger.d.ts.map +1 -0
  49. package/dist/commands/ledger.js +286 -0
  50. package/dist/commands/ledger.js.map +1 -0
  51. package/dist/commands/ledger.test.d.ts +2 -0
  52. package/dist/commands/ledger.test.d.ts.map +1 -0
  53. package/dist/commands/ledger.test.js +238 -0
  54. package/dist/commands/ledger.test.js.map +1 -0
  55. package/dist/commands/lessons.d.ts +73 -0
  56. package/dist/commands/lessons.d.ts.map +1 -0
  57. package/dist/commands/lessons.js +97 -0
  58. package/dist/commands/lessons.js.map +1 -0
  59. package/dist/commands/lessons.test.d.ts +2 -0
  60. package/dist/commands/lessons.test.d.ts.map +1 -0
  61. package/dist/commands/lessons.test.js +146 -0
  62. package/dist/commands/lessons.test.js.map +1 -0
  63. package/dist/commands/models.d.ts +49 -0
  64. package/dist/commands/models.d.ts.map +1 -0
  65. package/dist/commands/models.js +125 -0
  66. package/dist/commands/models.js.map +1 -0
  67. package/dist/commands/report.d.ts +57 -0
  68. package/dist/commands/report.d.ts.map +1 -0
  69. package/dist/commands/report.js +164 -0
  70. package/dist/commands/report.js.map +1 -0
  71. package/dist/commands/report.test.d.ts +2 -0
  72. package/dist/commands/report.test.d.ts.map +1 -0
  73. package/dist/commands/report.test.js +294 -0
  74. package/dist/commands/report.test.js.map +1 -0
  75. package/dist/commands/scope.d.ts +34 -0
  76. package/dist/commands/scope.d.ts.map +1 -0
  77. package/dist/commands/scope.js +78 -0
  78. package/dist/commands/scope.js.map +1 -0
  79. package/dist/commands/scope.test.d.ts +2 -0
  80. package/dist/commands/scope.test.d.ts.map +1 -0
  81. package/dist/commands/scope.test.js +98 -0
  82. package/dist/commands/scope.test.js.map +1 -0
  83. package/dist/commands/setup.d.ts +31 -0
  84. package/dist/commands/setup.d.ts.map +1 -0
  85. package/dist/commands/setup.js +93 -0
  86. package/dist/commands/setup.js.map +1 -0
  87. package/dist/commands/waivers.d.ts +47 -0
  88. package/dist/commands/waivers.d.ts.map +1 -0
  89. package/dist/commands/waivers.js +68 -0
  90. package/dist/commands/waivers.js.map +1 -0
  91. package/dist/commands/waivers.test.d.ts +2 -0
  92. package/dist/commands/waivers.test.d.ts.map +1 -0
  93. package/dist/commands/waivers.test.js +64 -0
  94. package/dist/commands/waivers.test.js.map +1 -0
  95. package/dist/generate/agent.d.ts +19 -0
  96. package/dist/generate/agent.d.ts.map +1 -0
  97. package/dist/generate/agent.js +35 -0
  98. package/dist/generate/agent.js.map +1 -0
  99. package/dist/generate/agent.test.d.ts +2 -0
  100. package/dist/generate/agent.test.d.ts.map +1 -0
  101. package/dist/generate/agent.test.js +245 -0
  102. package/dist/generate/agent.test.js.map +1 -0
  103. package/dist/generate/commands.d.ts +15 -0
  104. package/dist/generate/commands.d.ts.map +1 -0
  105. package/dist/generate/commands.js +59 -0
  106. package/dist/generate/commands.js.map +1 -0
  107. package/dist/generate/lock.d.ts +18 -0
  108. package/dist/generate/lock.d.ts.map +1 -0
  109. package/dist/generate/lock.js +26 -0
  110. package/dist/generate/lock.js.map +1 -0
  111. package/dist/generate/prompt.d.ts +11 -0
  112. package/dist/generate/prompt.d.ts.map +1 -0
  113. package/dist/generate/prompt.js +114 -0
  114. package/dist/generate/prompt.js.map +1 -0
  115. package/dist/generate/prompt.test.d.ts +2 -0
  116. package/dist/generate/prompt.test.d.ts.map +1 -0
  117. package/dist/generate/prompt.test.js +59 -0
  118. package/dist/generate/prompt.test.js.map +1 -0
  119. package/dist/index.d.ts +40 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +448 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/index.test.d.ts +2 -0
  124. package/dist/index.test.d.ts.map +1 -0
  125. package/dist/index.test.js +237 -0
  126. package/dist/index.test.js.map +1 -0
  127. package/dist/opencode.d.ts +29 -0
  128. package/dist/opencode.d.ts.map +1 -0
  129. package/dist/opencode.js +125 -0
  130. package/dist/opencode.js.map +1 -0
  131. package/dist/plugin-bundle.test.d.ts +2 -0
  132. package/dist/plugin-bundle.test.d.ts.map +1 -0
  133. package/dist/plugin-bundle.test.js +43 -0
  134. package/dist/plugin-bundle.test.js.map +1 -0
  135. package/dist/plugin.d.ts +11 -0
  136. package/dist/plugin.d.ts.map +1 -0
  137. package/dist/plugin.js +46 -0
  138. package/dist/plugin.js.map +1 -0
  139. package/dist/quality-skills.test.d.ts +2 -0
  140. package/dist/quality-skills.test.d.ts.map +1 -0
  141. package/dist/quality-skills.test.js +141 -0
  142. package/dist/quality-skills.test.js.map +1 -0
  143. package/dist/report/footprint.d.ts +12 -0
  144. package/dist/report/footprint.d.ts.map +1 -0
  145. package/dist/report/footprint.js +121 -0
  146. package/dist/report/footprint.js.map +1 -0
  147. package/dist/report/ledger.d.ts +27 -0
  148. package/dist/report/ledger.d.ts.map +1 -0
  149. package/dist/report/ledger.js +197 -0
  150. package/dist/report/ledger.js.map +1 -0
  151. package/dist/report/oversight.d.ts +21 -0
  152. package/dist/report/oversight.d.ts.map +1 -0
  153. package/dist/report/oversight.js +146 -0
  154. package/dist/report/oversight.js.map +1 -0
  155. package/dist/report/policy-firing.test.d.ts +2 -0
  156. package/dist/report/policy-firing.test.d.ts.map +1 -0
  157. package/dist/report/policy-firing.test.js +68 -0
  158. package/dist/report/policy-firing.test.js.map +1 -0
  159. package/dist/report/scope.d.ts +64 -0
  160. package/dist/report/scope.d.ts.map +1 -0
  161. package/dist/report/scope.js +146 -0
  162. package/dist/report/scope.js.map +1 -0
  163. package/dist/who.d.ts +9 -0
  164. package/dist/who.d.ts.map +1 -0
  165. package/dist/who.js +11 -0
  166. package/dist/who.js.map +1 -0
  167. package/package.json +55 -4
  168. 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=conformance.test.d.ts.map
@@ -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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"}