@voxslopuli/openagentsy 0.0.0-stage → 0.2.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/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 +54 -4
- package/plugin/openagentsy.js +39478 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { main } from '../index.js';
|
|
3
|
+
import { formatScope, runScope } from './scope.js';
|
|
4
|
+
/** The seven first-party roles. */
|
|
5
|
+
const ROLES = ['lead', 'scout', 'researcher', 'builder', 'reviewer', 'advisor', 'archivist'];
|
|
6
|
+
/** What a command wrote, on either stream. */
|
|
7
|
+
let written;
|
|
8
|
+
let writtenErrors;
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
vi.restoreAllMocks();
|
|
11
|
+
written = [];
|
|
12
|
+
writtenErrors = [];
|
|
13
|
+
});
|
|
14
|
+
/** Watch both streams of the process. */
|
|
15
|
+
function watchOutput() {
|
|
16
|
+
written = [];
|
|
17
|
+
writtenErrors = [];
|
|
18
|
+
vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
|
|
19
|
+
written.push(String(chunk));
|
|
20
|
+
return true;
|
|
21
|
+
});
|
|
22
|
+
vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
|
|
23
|
+
writtenErrors.push(String(chunk));
|
|
24
|
+
return true;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
describe('the scope command', () => {
|
|
28
|
+
it('prints the declaration of one role', () => {
|
|
29
|
+
const report = runScope('builder');
|
|
30
|
+
expect(report.declarations).toHaveLength(1);
|
|
31
|
+
expect(report.declarations[0]?.role).toBe('builder');
|
|
32
|
+
const text = formatScope(report);
|
|
33
|
+
expect(text).toContain('builder (Builder):');
|
|
34
|
+
expect(text).toContain('Purpose:');
|
|
35
|
+
expect(text).toContain('In scope:');
|
|
36
|
+
expect(text).toContain('Out of scope:');
|
|
37
|
+
expect(text).toContain('Refusal:');
|
|
38
|
+
expect(text).toContain('Redirect:');
|
|
39
|
+
});
|
|
40
|
+
it('prints every declaration when no role is named', () => {
|
|
41
|
+
const report = runScope();
|
|
42
|
+
expect(report.declarations.map((declaration) => declaration.role)).toEqual(ROLES);
|
|
43
|
+
const text = formatScope(report);
|
|
44
|
+
for (const role of ROLES) {
|
|
45
|
+
expect(text).toContain(`${role} (`);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
it('says that a declaration is a proposal until two maintainers reviewed it', () => {
|
|
49
|
+
const text = formatScope(runScope('builder'));
|
|
50
|
+
expect(text).toContain('Review: proposed');
|
|
51
|
+
expect(text).toContain('0 of 2 maintainers');
|
|
52
|
+
});
|
|
53
|
+
it('reaches a role by its agent id and by the Lead agent name', () => {
|
|
54
|
+
expect(runScope('oa-builder').declarations[0]?.role).toBe('builder');
|
|
55
|
+
expect(runScope('agentsy').declarations[0]?.role).toBe('lead');
|
|
56
|
+
});
|
|
57
|
+
it('says so when the role has no declaration', () => {
|
|
58
|
+
const report = runScope('offload');
|
|
59
|
+
expect(report.declarations).toHaveLength(0);
|
|
60
|
+
expect(report.unknownRole).toBe('offload');
|
|
61
|
+
const text = formatScope(report);
|
|
62
|
+
expect(text).toContain('no scope declaration for offload');
|
|
63
|
+
expect(text).toContain('the roles that have one');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('oa scope, through the CLI', () => {
|
|
67
|
+
it('prints the declaration of the role that was named', async () => {
|
|
68
|
+
watchOutput();
|
|
69
|
+
const code = await main(['scope', 'builder']);
|
|
70
|
+
expect(code).toBe(0);
|
|
71
|
+
const output = written.join('');
|
|
72
|
+
expect(output).toContain('builder (Builder):');
|
|
73
|
+
expect(output).toContain('Implementing the assigned bean');
|
|
74
|
+
expect(output).not.toContain('lead (Lead):');
|
|
75
|
+
});
|
|
76
|
+
it('prints every declaration when no role is named', async () => {
|
|
77
|
+
watchOutput();
|
|
78
|
+
const code = await main(['scope']);
|
|
79
|
+
expect(code).toBe(0);
|
|
80
|
+
const output = written.join('');
|
|
81
|
+
for (const role of ROLES) {
|
|
82
|
+
expect(output).toContain(`${role} (`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
it('fails and says so when the role has no declaration', async () => {
|
|
86
|
+
watchOutput();
|
|
87
|
+
const code = await main(['scope', 'offload']);
|
|
88
|
+
expect(code).toBe(1);
|
|
89
|
+
expect(writtenErrors.join('')).toContain('no scope declaration for offload');
|
|
90
|
+
});
|
|
91
|
+
it('is named in the usage card', async () => {
|
|
92
|
+
watchOutput();
|
|
93
|
+
const code = await main(['--help']);
|
|
94
|
+
expect(code).toBe(0);
|
|
95
|
+
expect(written.join('')).toContain('scope [role]');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=scope.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.test.js","sourceRoot":"","sources":["../../src/commands/scope.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type SetupOptions = {
|
|
2
|
+
root: string;
|
|
3
|
+
configPath?: string;
|
|
4
|
+
dryRun?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Turn compaction off.
|
|
7
|
+
*
|
|
8
|
+
* Compaction is off for a memory integration that shrinks the context
|
|
9
|
+
* itself. There is no such integration yet, so the default is OpenCode's
|
|
10
|
+
* own compaction, and this flag is how a project that has one says so.
|
|
11
|
+
*/
|
|
12
|
+
magicContext?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type SetupResult = {
|
|
15
|
+
configPath: string;
|
|
16
|
+
content: string;
|
|
17
|
+
changed: string[];
|
|
18
|
+
pluginPath?: string;
|
|
19
|
+
dryRun: boolean;
|
|
20
|
+
/** The config files OpenCode merges with the one that was written. */
|
|
21
|
+
merged?: string[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Write the config shape OpenCode 2 needs for OpenAgentsy.
|
|
25
|
+
*
|
|
26
|
+
* The MCP server lives under `mcp.servers`, the enable flag is `disabled`,
|
|
27
|
+
* and OpenCode 2 turns Code Mode on by default, so the board tools have to
|
|
28
|
+
* be listed directly with `codemode: false`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function runSetup(options: SetupOptions): Promise<SetupResult>;
|
|
31
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AA+DF;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAoC1E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { readFile, stat, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { applyEdits, modify } from 'jsonc-parser';
|
|
4
|
+
import { PROJECT_CONFIG_NAMES } from '../opencode.js';
|
|
5
|
+
import { installPlugin } from '../plugin.js';
|
|
6
|
+
const FORMATTING = {
|
|
7
|
+
insertSpaces: true,
|
|
8
|
+
tabSize: 2,
|
|
9
|
+
eol: '\n',
|
|
10
|
+
};
|
|
11
|
+
function setPath(text, path, value) {
|
|
12
|
+
const edits = modify(text, path, value, { formattingOptions: FORMATTING });
|
|
13
|
+
return applyEdits(text, edits);
|
|
14
|
+
}
|
|
15
|
+
async function resolveMcpCommand(root) {
|
|
16
|
+
const dist = join(root, 'packages', 'mcp', 'dist', 'index.js');
|
|
17
|
+
const built = await stat(dist).then(() => true, () => false);
|
|
18
|
+
if (built) {
|
|
19
|
+
// A relative path keeps the config portable. The MCP server runs with the
|
|
20
|
+
// project directory as its working directory, so it resolves the same way
|
|
21
|
+
// on every machine. It runs under bun: the board's driver is bun:sqlite,
|
|
22
|
+
// and bun is the runtime OpenCode loads plugins with, so one runtime
|
|
23
|
+
// covers the plugin, the board and the tests.
|
|
24
|
+
return ['bun', join('packages', 'mcp', 'dist', 'index.js')];
|
|
25
|
+
}
|
|
26
|
+
return ['bunx', '@openagentsy/mcp'];
|
|
27
|
+
}
|
|
28
|
+
async function findConfigPath(root) {
|
|
29
|
+
for (const name of PROJECT_CONFIG_NAMES) {
|
|
30
|
+
const path = join(root, name);
|
|
31
|
+
const exists = await stat(path).then(() => true, () => false);
|
|
32
|
+
if (exists)
|
|
33
|
+
return path;
|
|
34
|
+
}
|
|
35
|
+
return join(root, 'opencode.json');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The config files that are already there, and would be merged with a new
|
|
39
|
+
* one.
|
|
40
|
+
*
|
|
41
|
+
* OpenCode reads a root config and a config in the config directory, and
|
|
42
|
+
* merges them. Writing a root config next to a config directory that was
|
|
43
|
+
* never read is how a split brain starts.
|
|
44
|
+
*/
|
|
45
|
+
async function mergedConfigs(root) {
|
|
46
|
+
const found = [];
|
|
47
|
+
for (const name of ['.opencode/opencode.json', '.opencode/opencode.jsonc']) {
|
|
48
|
+
const path = join(root, name);
|
|
49
|
+
const exists = await stat(path).then(() => true, () => false);
|
|
50
|
+
if (exists)
|
|
51
|
+
found.push(path);
|
|
52
|
+
}
|
|
53
|
+
return found;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Write the config shape OpenCode 2 needs for OpenAgentsy.
|
|
57
|
+
*
|
|
58
|
+
* The MCP server lives under `mcp.servers`, the enable flag is `disabled`,
|
|
59
|
+
* and OpenCode 2 turns Code Mode on by default, so the board tools have to
|
|
60
|
+
* be listed directly with `codemode: false`.
|
|
61
|
+
*/
|
|
62
|
+
export async function runSetup(options) {
|
|
63
|
+
const configPath = options.configPath ?? (await findConfigPath(options.root));
|
|
64
|
+
const command = await resolveMcpCommand(options.root);
|
|
65
|
+
const merged = await mergedConfigs(options.root);
|
|
66
|
+
const text = await readFile(configPath, 'utf8').catch(() => '');
|
|
67
|
+
const changed = [];
|
|
68
|
+
let content = text;
|
|
69
|
+
content = setPath(content, ['mcp', 'servers', 'openagentsy'], {
|
|
70
|
+
type: 'local',
|
|
71
|
+
command,
|
|
72
|
+
disabled: false,
|
|
73
|
+
codemode: false,
|
|
74
|
+
});
|
|
75
|
+
changed.push('mcp.servers.openagentsy');
|
|
76
|
+
if (options.magicContext === true) {
|
|
77
|
+
content = setPath(content, ['compaction', 'auto'], false);
|
|
78
|
+
changed.push('compaction.auto');
|
|
79
|
+
}
|
|
80
|
+
if (!options.dryRun) {
|
|
81
|
+
await writeFile(configPath, content.endsWith('\n') ? content : `${content}\n`, 'utf8');
|
|
82
|
+
}
|
|
83
|
+
const pluginPath = await installPlugin(options.root, options.dryRun ?? false);
|
|
84
|
+
return {
|
|
85
|
+
configPath,
|
|
86
|
+
content,
|
|
87
|
+
changed,
|
|
88
|
+
...(pluginPath !== undefined ? { pluginPath } : {}),
|
|
89
|
+
dryRun: options.dryRun ?? false,
|
|
90
|
+
...(merged.length > 0 ? { merged } : {}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAA0B,MAAM,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA0B7C,MAAM,UAAU,GAAsB;IACpC,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,CAAC;IACV,GAAG,EAAE,IAAI;CACV,CAAC;AAEF,SAAS,OAAO,CAAC,IAAY,EAAE,IAAyB,EAAE,KAAc;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3E,OAAO,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACjC,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC;IACF,IAAI,KAAK,EAAE,CAAC;QACV,0EAA0E;QAC1E,0EAA0E;QAC1E,yEAAyE;QACzE,qEAAqE;QACrE,8CAA8C;QAC9C,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAClC,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC;QACF,IAAI,MAAM;YAAE,OAAO,IAAI,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,aAAa,CAAC,IAAY;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,CAAC,yBAAyB,EAAE,0BAA0B,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAClC,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC;QACF,IAAI,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAqB;IAClD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,MAAM,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAEhE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE;QAC5D,IAAI,EAAE,OAAO;QACb,OAAO;QACP,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxC,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QAClC,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,EAAE,MAAM,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;IAE9E,OAAO;QACL,UAAU;QACV,OAAO;QACP,OAAO;QACP,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;QAC/B,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The waiver command.
|
|
3
|
+
*
|
|
4
|
+
* `/oa waive <ruleId> <path> "<reason>"` records a waiver. The person
|
|
5
|
+
* running the command is the decider, and the command is the way a waiver
|
|
6
|
+
* is recorded: the tool the board server registers is denied to every
|
|
7
|
+
* agent role, so an agent may propose a waiver in chat and never record
|
|
8
|
+
* one.
|
|
9
|
+
*
|
|
10
|
+
* The waivers are the state root's: a waiver is a decision about the
|
|
11
|
+
* project, and a worktree of the project has the same waivers as the
|
|
12
|
+
* project.
|
|
13
|
+
*/
|
|
14
|
+
/** What the command did. */
|
|
15
|
+
export type WaiverReport = {
|
|
16
|
+
/** Whether the waiver was recorded. */
|
|
17
|
+
ok: boolean;
|
|
18
|
+
/** The rule the waiver is for. */
|
|
19
|
+
ruleId: string;
|
|
20
|
+
/** The path the waiver covers. */
|
|
21
|
+
path: string;
|
|
22
|
+
/** The reason the waiver carries. */
|
|
23
|
+
reason: string;
|
|
24
|
+
/** How many waivers the project holds. */
|
|
25
|
+
count: number;
|
|
26
|
+
/** Why the command refused, when it refused. */
|
|
27
|
+
problem?: string | undefined;
|
|
28
|
+
/** What to do next, when the command refused. */
|
|
29
|
+
hint?: string | undefined;
|
|
30
|
+
};
|
|
31
|
+
/** What the caller knows about the decision. */
|
|
32
|
+
export type WaiverOptions = {
|
|
33
|
+
/** Who decided. The person running the command. */
|
|
34
|
+
decidedBy?: string | undefined;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Record a waiver.
|
|
38
|
+
*
|
|
39
|
+
* A rule that cannot be waived is refused, and the refusal says so: a floor
|
|
40
|
+
* rule is honesty, function or accessibility, and no reason waives it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function runWaiver(stateRoot: string, ruleId: string, path: string, reason: string, options?: WaiverOptions): Promise<WaiverReport>;
|
|
43
|
+
/**
|
|
44
|
+
* The decision, as it is read.
|
|
45
|
+
*/
|
|
46
|
+
export declare function formatWaiver(report: WaiverReport): string;
|
|
47
|
+
//# sourceMappingURL=waivers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.d.ts","sourceRoot":"","sources":["../../src/commands/waivers.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,4BAA4B;AAC5B,MAAM,MAAM,YAAY,GAAG;IACzB,uCAAuC;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,gDAAgD;AAChD,MAAM,MAAM,aAAa,GAAG;IAC1B,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA6BvB;AAkBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAQzD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { waive } from '@openagentsy/hooks/quality/waive';
|
|
2
|
+
import { createWaiverStore } from '@openagentsy/hooks/quality/waivers';
|
|
3
|
+
import { deciderBy } from '../who.js';
|
|
4
|
+
/**
|
|
5
|
+
* Record a waiver.
|
|
6
|
+
*
|
|
7
|
+
* A rule that cannot be waived is refused, and the refusal says so: a floor
|
|
8
|
+
* rule is honesty, function or accessibility, and no reason waives it.
|
|
9
|
+
*/
|
|
10
|
+
export async function runWaiver(stateRoot, ruleId, path, reason, options = {}) {
|
|
11
|
+
const store = createWaiverStore(stateRoot);
|
|
12
|
+
try {
|
|
13
|
+
const waiver = await waive({
|
|
14
|
+
stateRoot,
|
|
15
|
+
ruleId,
|
|
16
|
+
path,
|
|
17
|
+
reason,
|
|
18
|
+
decidedBy: deciderBy(options.decidedBy),
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
ok: true,
|
|
22
|
+
ruleId: waiver.ruleId,
|
|
23
|
+
path: waiver.path,
|
|
24
|
+
reason: waiver.reason,
|
|
25
|
+
count: await store.count(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
const problem = error instanceof Error ? error.message : String(error);
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
ruleId,
|
|
33
|
+
path,
|
|
34
|
+
reason,
|
|
35
|
+
count: await store.count(),
|
|
36
|
+
problem,
|
|
37
|
+
hint: hintOf(problem),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* What to do next, for the refusal that happened.
|
|
43
|
+
*
|
|
44
|
+
* The three refusals are three different mistakes, and each of them has its
|
|
45
|
+
* own next step: a floor rule is not a mistake at all.
|
|
46
|
+
*/
|
|
47
|
+
function hintOf(problem) {
|
|
48
|
+
if (problem.includes('cannot be waived')) {
|
|
49
|
+
return 'a floor rule cannot be waived: fix the finding, or turn the rule off for the project';
|
|
50
|
+
}
|
|
51
|
+
if (problem.includes('ten characters')) {
|
|
52
|
+
return 'say why the rule does not apply here, in ten characters at least';
|
|
53
|
+
}
|
|
54
|
+
return 'the rule has to be one the registry knows: the quality check names the ids';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The decision, as it is read.
|
|
58
|
+
*/
|
|
59
|
+
export function formatWaiver(report) {
|
|
60
|
+
if (!report.ok) {
|
|
61
|
+
const hint = report.hint === undefined ? '' : `\nNext: ${report.hint}`;
|
|
62
|
+
return `${report.problem ?? 'the waiver was refused'}${hint}\n`;
|
|
63
|
+
}
|
|
64
|
+
const count = report.count;
|
|
65
|
+
const waivers = count === 1 ? 'waiver' : 'waivers';
|
|
66
|
+
return `${report.ruleId} is waived for ${report.path} (${count} ${waivers} in all)\n`;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=waivers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.js","sourceRoot":"","sources":["../../src/commands/waivers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAwCtC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,SAAiB,EACjB,MAAc,EACd,IAAY,EACZ,MAAc,EACd,UAAyB,EAAE;IAE3B,MAAM,KAAK,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;YACzB,SAAS;YACT,MAAM;YACN,IAAI;YACJ,MAAM;YACN,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC;SACxC,CAAC,CAAC;QACH,OAAO;YACL,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE;SAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM;YACN,IAAI;YACJ,MAAM;YACN,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE;YAC1B,OAAO;YACP,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC;SACtB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,MAAM,CAAC,OAAe;IAC7B,IAAI,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACzC,OAAO,sFAAsF,CAAC;IAChG,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACvC,OAAO,kEAAkE,CAAC;IAC5E,CAAC;IACD,OAAO,4EAA4E,CAAC;AACtF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,MAAM,CAAC,IAAI,EAAE,CAAC;QACvE,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,wBAAwB,GAAG,IAAI,IAAI,CAAC;IAClE,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,MAAM,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACnD,OAAO,GAAG,MAAM,CAAC,MAAM,kBAAkB,MAAM,CAAC,IAAI,KAAK,KAAK,IAAI,OAAO,YAAY,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.test.d.ts","sourceRoot":"","sources":["../../src/commands/waivers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { createWaiverStore } from '@openagentsy/hooks/quality/waivers';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { formatWaiver, runWaiver } from './waivers.js';
|
|
7
|
+
async function stateRoot() {
|
|
8
|
+
const root = await mkdtemp(join(tmpdir(), 'openagentsy-cli-waivers-'));
|
|
9
|
+
return { root, remove: () => rm(root, { recursive: true, force: true }) };
|
|
10
|
+
}
|
|
11
|
+
describe('the waiver command', () => {
|
|
12
|
+
it('records the waiver a person decided', async () => {
|
|
13
|
+
const { root, remove } = await stateRoot();
|
|
14
|
+
try {
|
|
15
|
+
const report = await runWaiver(root, 'css/no-transition-all', 'src/app.css', 'The file is a fixture, not a page.');
|
|
16
|
+
expect(report.ok).toBe(true);
|
|
17
|
+
expect(report.count).toBe(1);
|
|
18
|
+
expect(await createWaiverStore(root).count()).toBe(1);
|
|
19
|
+
expect(formatWaiver(report)).toContain('css/no-transition-all');
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
await remove();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
it('refuses a floor rule and says why', async () => {
|
|
26
|
+
const { root, remove } = await stateRoot();
|
|
27
|
+
try {
|
|
28
|
+
const report = await runWaiver(root, 'css/contrast', 'src/app.css', 'The contrast is fine, I have looked at it.');
|
|
29
|
+
expect(report.ok).toBe(false);
|
|
30
|
+
expect(report.problem).toContain('cannot be waived');
|
|
31
|
+
expect(report.hint).toContain('floor rule');
|
|
32
|
+
expect(await createWaiverStore(root).count()).toBe(0);
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
await remove();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
it('refuses a reason that is too short', async () => {
|
|
39
|
+
const { root, remove } = await stateRoot();
|
|
40
|
+
try {
|
|
41
|
+
const report = await runWaiver(root, 'css/no-transition-all', 'src/app.css', 'because');
|
|
42
|
+
expect(report.ok).toBe(false);
|
|
43
|
+
expect(report.problem).toContain('ten characters');
|
|
44
|
+
expect(report.hint).toContain('ten characters');
|
|
45
|
+
expect(await createWaiverStore(root).count()).toBe(0);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await remove();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
it('names the person who decided', async () => {
|
|
52
|
+
const { root, remove } = await stateRoot();
|
|
53
|
+
try {
|
|
54
|
+
const report = await runWaiver(root, 'css/no-transition-all', 'src/app.css', 'The file is a fixture, not a page.', { decidedBy: 'daniel' });
|
|
55
|
+
expect(report.ok).toBe(true);
|
|
56
|
+
const waivers = await createWaiverStore(root).all();
|
|
57
|
+
expect(waivers[0]?.decidedBy).toBe('daniel');
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
await remove();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=waivers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waivers.test.js","sourceRoot":"","sources":["../../src/commands/waivers.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type RoleDefinition, type RolesFile } from '@openagentsy/core';
|
|
2
|
+
export type AgentRenderOptions = {
|
|
3
|
+
model?: string;
|
|
4
|
+
modelVariant?: string;
|
|
5
|
+
effort?: {
|
|
6
|
+
start?: string;
|
|
7
|
+
ceiling?: string;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Render one agent file for OpenCode 2.
|
|
12
|
+
*
|
|
13
|
+
* The frontmatter takes an ordered `permissions` list and calls the spawn
|
|
14
|
+
* tool `subagent`. The role definition carries the vocabulary of the
|
|
15
|
+
* project, and the mapping onto the host lives in `@openagentsy/core`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function renderAgent(role: RoleDefinition, roles: RolesFile, options: AgentRenderOptions): string;
|
|
18
|
+
export declare function agentFileName(role: RoleDefinition): string;
|
|
19
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/generate/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAI3B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C,CAAC;AAyBF;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,kBAAkB,GAC1B,MAAM,CAWR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAE1D"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { agentId, toV2Permissions, withProtectedPaths, } from '@openagentsy/core';
|
|
2
|
+
import { stringify } from 'yaml';
|
|
3
|
+
import { renderPrompt } from './prompt.js';
|
|
4
|
+
function v2Frontmatter(role, permissions, model, modelVariant) {
|
|
5
|
+
const frontmatter = {
|
|
6
|
+
description: role.description,
|
|
7
|
+
mode: role.mode,
|
|
8
|
+
};
|
|
9
|
+
if (model)
|
|
10
|
+
frontmatter.model = modelVariant ? `${model}#${modelVariant}` : model;
|
|
11
|
+
frontmatter.steps = role.steps;
|
|
12
|
+
if (role.hidden)
|
|
13
|
+
frontmatter.hidden = true;
|
|
14
|
+
frontmatter.permissions = permissions;
|
|
15
|
+
return frontmatter;
|
|
16
|
+
}
|
|
17
|
+
function renderFrontmatter(frontmatter) {
|
|
18
|
+
return stringify(frontmatter, { lineWidth: 0 }).trimEnd();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Render one agent file for OpenCode 2.
|
|
22
|
+
*
|
|
23
|
+
* The frontmatter takes an ordered `permissions` list and calls the spawn
|
|
24
|
+
* tool `subagent`. The role definition carries the vocabulary of the
|
|
25
|
+
* project, and the mapping onto the host lives in `@openagentsy/core`.
|
|
26
|
+
*/
|
|
27
|
+
export function renderAgent(role, roles, options) {
|
|
28
|
+
const permissions = withProtectedPaths(role, roles.protectedPaths);
|
|
29
|
+
const frontmatter = v2Frontmatter(role, toV2Permissions(permissions), options.model, options.modelVariant);
|
|
30
|
+
return `---\n${renderFrontmatter(frontmatter)}\n---\n\n${renderPrompt(role, options.effort ?? {})}`;
|
|
31
|
+
}
|
|
32
|
+
export function agentFileName(role) {
|
|
33
|
+
return `${role.agentName ?? agentId(role.name)}.md`;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/generate/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAGP,eAAe,EACf,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAU3C,SAAS,aAAa,CACpB,IAAoB,EACpB,WAA+C,EAC/C,KAAyB,EACzB,YAAgC;IAEhC,MAAM,WAAW,GAAgB;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC;IACF,IAAI,KAAK;QAAE,WAAW,CAAC,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACjF,WAAW,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM;QAAE,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC;IAC3C,WAAW,CAAC,WAAW,GAAG,WAAW,CAAC;IACtC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,iBAAiB,CAAC,WAAwB;IACjD,OAAO,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,IAAoB,EACpB,KAAgB,EAChB,OAA2B;IAE3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAEnE,MAAM,WAAW,GAAG,aAAa,CAC/B,IAAI,EACJ,eAAe,CAAC,WAAW,CAAC,EAC5B,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,YAAY,CACrB,CAAC;IAEF,OAAO,QAAQ,iBAAiB,CAAC,WAAW,CAAC,YAAY,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;AACtG,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAoB;IAChD,OAAO,GAAG,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.test.d.ts","sourceRoot":"","sources":["../../src/generate/agent.test.ts"],"names":[],"mappings":""}
|