sf-agentpmd 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +26 -0
- package/README.md +204 -0
- package/bin/dev.js +5 -0
- package/bin/run.js +3 -0
- package/dist/analyzer/action-references.d.ts +21 -0
- package/dist/analyzer/action-references.js +130 -0
- package/dist/analyzer/action-references.js.map +1 -0
- package/dist/analyzer/analyze.d.ts +43 -0
- package/dist/analyzer/analyze.js +222 -0
- package/dist/analyzer/analyze.js.map +1 -0
- package/dist/analyzer/apex-analyze.d.ts +14 -0
- package/dist/analyzer/apex-analyze.js +60 -0
- package/dist/analyzer/apex-analyze.js.map +1 -0
- package/dist/analyzer/apex-complexity.d.ts +27 -0
- package/dist/analyzer/apex-complexity.js +133 -0
- package/dist/analyzer/apex-complexity.js.map +1 -0
- package/dist/analyzer/apex-parse.d.ts +39 -0
- package/dist/analyzer/apex-parse.js +32 -0
- package/dist/analyzer/apex-parse.js.map +1 -0
- package/dist/analyzer/apex-resolve.d.ts +32 -0
- package/dist/analyzer/apex-resolve.js +59 -0
- package/dist/analyzer/apex-resolve.js.map +1 -0
- package/dist/analyzer/complexity.d.ts +30 -0
- package/dist/analyzer/complexity.js +126 -0
- package/dist/analyzer/complexity.js.map +1 -0
- package/dist/analyzer/parse.d.ts +51 -0
- package/dist/analyzer/parse.js +143 -0
- package/dist/analyzer/parse.js.map +1 -0
- package/dist/analyzer/project.d.ts +12 -0
- package/dist/analyzer/project.js +51 -0
- package/dist/analyzer/project.js.map +1 -0
- package/dist/analyzer/types.d.ts +76 -0
- package/dist/analyzer/types.js +2 -0
- package/dist/analyzer/types.js.map +1 -0
- package/dist/commands/agentpmd/analyze.d.ts +20 -0
- package/dist/commands/agentpmd/analyze.js +122 -0
- package/dist/commands/agentpmd/analyze.js.map +1 -0
- package/dist/commands/agentpmd/install-skill.d.ts +11 -0
- package/dist/commands/agentpmd/install-skill.js +33 -0
- package/dist/commands/agentpmd/install-skill.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/renderers/csv.d.ts +6 -0
- package/dist/renderers/csv.js +78 -0
- package/dist/renderers/csv.js.map +1 -0
- package/dist/renderers/index.d.ts +8 -0
- package/dist/renderers/index.js +25 -0
- package/dist/renderers/index.js.map +1 -0
- package/dist/renderers/markdown.d.ts +12 -0
- package/dist/renderers/markdown.js +233 -0
- package/dist/renderers/markdown.js.map +1 -0
- package/dist/renderers/options.d.ts +20 -0
- package/dist/renderers/options.js +2 -0
- package/dist/renderers/options.js.map +1 -0
- package/dist/renderers/sarif.d.ts +3 -0
- package/dist/renderers/sarif.js +131 -0
- package/dist/renderers/sarif.js.map +1 -0
- package/dist/renderers/text.d.ts +3 -0
- package/dist/renderers/text.js +243 -0
- package/dist/renderers/text.js.map +1 -0
- package/oclif.manifest.json +168 -0
- package/package.json +97 -0
- package/skill/SKILL.md +103 -0
- package/skill/references/command-structure.md +89 -0
- package/skill/references/install.md +112 -0
- package/skill/references/output-formats.md +205 -0
- package/skill/references/upgrade.md +112 -0
- package/vendor/agentscript-parser-javascript/dist/cst-node.d.ts +83 -0
- package/vendor/agentscript-parser-javascript/dist/cst-node.js +238 -0
- package/vendor/agentscript-parser-javascript/dist/errors.d.ts +34 -0
- package/vendor/agentscript-parser-javascript/dist/errors.js +74 -0
- package/vendor/agentscript-parser-javascript/dist/expressions.d.ts +36 -0
- package/vendor/agentscript-parser-javascript/dist/expressions.js +682 -0
- package/vendor/agentscript-parser-javascript/dist/highlighter.d.ts +24 -0
- package/vendor/agentscript-parser-javascript/dist/highlighter.js +260 -0
- package/vendor/agentscript-parser-javascript/dist/index.d.ts +29 -0
- package/vendor/agentscript-parser-javascript/dist/index.js +35 -0
- package/vendor/agentscript-parser-javascript/dist/lexer.d.ts +60 -0
- package/vendor/agentscript-parser-javascript/dist/lexer.js +630 -0
- package/vendor/agentscript-parser-javascript/dist/parse-mapping.d.ts +46 -0
- package/vendor/agentscript-parser-javascript/dist/parse-mapping.js +549 -0
- package/vendor/agentscript-parser-javascript/dist/parse-sequence.d.ts +10 -0
- package/vendor/agentscript-parser-javascript/dist/parse-sequence.js +118 -0
- package/vendor/agentscript-parser-javascript/dist/parse-statements.d.ts +15 -0
- package/vendor/agentscript-parser-javascript/dist/parse-statements.js +519 -0
- package/vendor/agentscript-parser-javascript/dist/parse-templates.d.ts +15 -0
- package/vendor/agentscript-parser-javascript/dist/parse-templates.js +323 -0
- package/vendor/agentscript-parser-javascript/dist/parser.d.ts +65 -0
- package/vendor/agentscript-parser-javascript/dist/parser.js +163 -0
- package/vendor/agentscript-parser-javascript/dist/recovery.d.ts +51 -0
- package/vendor/agentscript-parser-javascript/dist/recovery.js +199 -0
- package/vendor/agentscript-parser-javascript/dist/token.d.ts +58 -0
- package/vendor/agentscript-parser-javascript/dist/token.js +62 -0
- package/vendor/agentscript-parser-javascript/package.json +19 -0
- package/vendor/agentscript-types/dist/comment.d.ts +11 -0
- package/vendor/agentscript-types/dist/comment.js +10 -0
- package/vendor/agentscript-types/dist/cst.d.ts +7 -0
- package/vendor/agentscript-types/dist/cst.js +8 -0
- package/vendor/agentscript-types/dist/diagnostic.d.ts +34 -0
- package/vendor/agentscript-types/dist/diagnostic.js +23 -0
- package/vendor/agentscript-types/dist/index.d.ts +9 -0
- package/vendor/agentscript-types/dist/index.js +10 -0
- package/vendor/agentscript-types/dist/position.d.ts +11 -0
- package/vendor/agentscript-types/dist/position.js +16 -0
- package/vendor/agentscript-types/dist/syntax-node.d.ts +39 -0
- package/vendor/agentscript-types/dist/syntax-node.js +8 -0
- package/vendor/agentscript-types/package.json +15 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { analyzeSource } from '../../analyzer/analyze.js';
|
|
3
|
+
import { discoverSfdxProject } from '../../analyzer/project.js';
|
|
4
|
+
import { render } from '../../renderers/index.js';
|
|
5
|
+
const FORMATS = ['text', 'markdown', 'sarif', 'csv'];
|
|
6
|
+
export default class AgentpmdAnalyze extends SfCommand {
|
|
7
|
+
static description = `Walks .agent source files under --source-dir and emits per-procedure
|
|
8
|
+
cyclomatic complexity totals (before_reasoning, after_reasoning, and
|
|
9
|
+
reasoning.instructions blocks), plus an inventory of declared and used
|
|
10
|
+
@actions.X targets. For every apex:// target, resolves the .cls file
|
|
11
|
+
and computes per-method Apex CC.
|
|
12
|
+
|
|
13
|
+
Default output is human-readable text. --json emits the SF CLI envelope
|
|
14
|
+
with the full structured report. --format <markdown|sarif|csv> emits the
|
|
15
|
+
named format on stdout for piping into PR comments, GitHub Code Scanning,
|
|
16
|
+
or spreadsheet pivots.`;
|
|
17
|
+
static examples = [
|
|
18
|
+
'<%= config.bin %> <%= command.id %> --source-dir force-app/main/default',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> --source-dir force-app/main/default --json',
|
|
20
|
+
'<%= config.bin %> <%= command.id %> --source-dir force-app/main/default --format markdown > report.md',
|
|
21
|
+
'<%= config.bin %> <%= command.id %> --source-dir force-app/main/default --format sarif > report.sarif',
|
|
22
|
+
];
|
|
23
|
+
static flags = {
|
|
24
|
+
'apex-source': Flags.string({
|
|
25
|
+
summary: 'Override directory to look up apex:// targets. By default we walk up from each .agent file looking for a sibling classes/ folder.',
|
|
26
|
+
}),
|
|
27
|
+
'api-name': Flags.string({
|
|
28
|
+
char: 'n',
|
|
29
|
+
multiple: true,
|
|
30
|
+
summary: 'Filter to specific agent bundles. Matched against the bundle directory name and the config.developer_name field. Repeatable.',
|
|
31
|
+
}),
|
|
32
|
+
ascii: Flags.boolean({
|
|
33
|
+
default: false,
|
|
34
|
+
summary: 'Force ASCII-only output in the text renderer (no Unicode box chars, no emoji).',
|
|
35
|
+
}),
|
|
36
|
+
'fail-on': Flags.integer({
|
|
37
|
+
min: 1,
|
|
38
|
+
summary: 'Exit non-zero if combined agent+Apex CC meets or exceeds this threshold.',
|
|
39
|
+
}),
|
|
40
|
+
format: Flags.string({
|
|
41
|
+
default: 'text',
|
|
42
|
+
options: [...FORMATS],
|
|
43
|
+
summary: 'Non-JSON output format. --json takes precedence per SF CLI convention.',
|
|
44
|
+
}),
|
|
45
|
+
'no-color': Flags.boolean({
|
|
46
|
+
default: false,
|
|
47
|
+
summary: 'Disable ANSI color in the text renderer. NO_COLOR env also disables.',
|
|
48
|
+
}),
|
|
49
|
+
'sarif-error': Flags.integer({
|
|
50
|
+
min: 1,
|
|
51
|
+
summary: 'SARIF "error" level threshold. Default 20.',
|
|
52
|
+
}),
|
|
53
|
+
'sarif-warning': Flags.integer({
|
|
54
|
+
min: 1,
|
|
55
|
+
summary: 'SARIF "warning" level threshold. Default 10.',
|
|
56
|
+
}),
|
|
57
|
+
'source-dir': Flags.string({
|
|
58
|
+
char: 'd',
|
|
59
|
+
summary: 'Directory or single .agent file to analyze. Defaults to the packageDirectories of the nearest sfdx-project.json.',
|
|
60
|
+
}),
|
|
61
|
+
width: Flags.integer({
|
|
62
|
+
default: 60,
|
|
63
|
+
min: 20,
|
|
64
|
+
summary: 'Rule width for the text renderer.',
|
|
65
|
+
}),
|
|
66
|
+
};
|
|
67
|
+
static summary = 'Compute McCabe cyclomatic complexity and action-reference inventory for AgentScript bundles and their Apex backing logic.';
|
|
68
|
+
async run() {
|
|
69
|
+
const { flags } = await this.parse(AgentpmdAnalyze);
|
|
70
|
+
const { reportBase, roots, sourceDescription } = await resolveSources(flags['source-dir']);
|
|
71
|
+
if (!this.jsonEnabled() && sourceDescription) {
|
|
72
|
+
this.log(sourceDescription);
|
|
73
|
+
}
|
|
74
|
+
const report = await analyzeSource(roots, {
|
|
75
|
+
apexSourceOverride: flags['apex-source'],
|
|
76
|
+
apiNames: flags['api-name'],
|
|
77
|
+
reportBase,
|
|
78
|
+
});
|
|
79
|
+
if (!this.jsonEnabled()) {
|
|
80
|
+
const format = flags.format;
|
|
81
|
+
const text = render(format, report, {
|
|
82
|
+
ascii: flags.ascii || undefined,
|
|
83
|
+
color: flags['no-color'] ? false : undefined,
|
|
84
|
+
sarifErrorThreshold: flags['sarif-error'],
|
|
85
|
+
sarifWarningThreshold: flags['sarif-warning'],
|
|
86
|
+
width: flags.width,
|
|
87
|
+
});
|
|
88
|
+
this.log(text);
|
|
89
|
+
}
|
|
90
|
+
const combined = report.totalComplexity + report.totalApexComplexity;
|
|
91
|
+
if (flags['fail-on'] !== undefined && combined >= flags['fail-on']) {
|
|
92
|
+
this.error(`Combined cyclomatic complexity ${combined} (agent ${report.totalComplexity} + apex ${report.totalApexComplexity}) ≥ threshold ${flags['fail-on']}`, { exit: 2 });
|
|
93
|
+
}
|
|
94
|
+
return report;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Resolve the directories we should scan. Explicit `--source-dir` wins.
|
|
99
|
+
* Otherwise, walk up from cwd looking for `sfdx-project.json` and use its
|
|
100
|
+
* `packageDirectories`. If neither is available, fail with a clear message.
|
|
101
|
+
*/
|
|
102
|
+
async function resolveSources(sourceDirFlag) {
|
|
103
|
+
if (sourceDirFlag) {
|
|
104
|
+
return { reportBase: undefined, roots: [sourceDirFlag] };
|
|
105
|
+
}
|
|
106
|
+
const project = await discoverSfdxProject(process.cwd());
|
|
107
|
+
if (!project) {
|
|
108
|
+
throw new Error('No --source-dir was provided and no sfdx-project.json was found in the ' +
|
|
109
|
+
'current directory or any ancestor. Pass --source-dir <path> or run from ' +
|
|
110
|
+
'inside an sfdx project.');
|
|
111
|
+
}
|
|
112
|
+
if (project.packageDirectories.length === 0) {
|
|
113
|
+
throw new Error(`sfdx-project.json at ${project.root} declares no packageDirectories. ` +
|
|
114
|
+
'Pass --source-dir <path> explicitly.');
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
reportBase: project.root,
|
|
118
|
+
roots: project.packageDirectories,
|
|
119
|
+
sourceDescription: `Analyzing sfdx project ${project.root} (${project.packageDirectories.length} package director${project.packageDirectories.length === 1 ? 'y' : 'ies'}).`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../../src/commands/agentpmd/analyze.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
export default class AgentpmdInstallSkill extends SfCommand<{
|
|
3
|
+
installed: string;
|
|
4
|
+
}> {
|
|
5
|
+
static readonly description = "Recursively copies the bundled skill tree (SKILL.md plus its references/\npages) to ~/.claude/skills/agentforcepmd/ so Claude Code can use it as a\nskill. Restart Claude Code (or reload skills) afterward to activate it.";
|
|
6
|
+
static readonly examples: string[];
|
|
7
|
+
static readonly summary = "Install the agentforcepmd Claude Code skill to ~/.claude/skills/.";
|
|
8
|
+
run(): Promise<{
|
|
9
|
+
installed: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
// `cp` is stable since Node 16.7; the plugin runtime targets Node >= 20.
|
|
4
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
5
|
+
import { cp } from 'node:fs/promises';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
const SKILL_DEST = join(homedir(), '.claude', 'skills', 'agentforcepmd');
|
|
10
|
+
export default class AgentpmdInstallSkill extends SfCommand {
|
|
11
|
+
static description = `Recursively copies the bundled skill tree (SKILL.md plus its references/
|
|
12
|
+
pages) to ~/.claude/skills/agentforcepmd/ so Claude Code can use it as a
|
|
13
|
+
skill. Restart Claude Code (or reload skills) afterward to activate it.`;
|
|
14
|
+
static examples = ['$ sf agentpmd install-skill'];
|
|
15
|
+
static summary = 'Install the agentforcepmd Claude Code skill to ~/.claude/skills/.';
|
|
16
|
+
async run() {
|
|
17
|
+
// Resolve the skill source relative to this package's installed location.
|
|
18
|
+
// Compiled file lives at dist/commands/agentpmd/install-skill.js. Joining
|
|
19
|
+
// '..' from the file path strips the filename first, so reaching the
|
|
20
|
+
// package root (above dist/) takes four hops: install-skill.js → agentpmd
|
|
21
|
+
// → commands → dist → <pkgRoot>.
|
|
22
|
+
const pkgRoot = join(fileURLToPath(import.meta.url), '..', '..', '..', '..');
|
|
23
|
+
const skillSrc = join(pkgRoot, 'skill');
|
|
24
|
+
if (!existsSync(skillSrc)) {
|
|
25
|
+
this.error(`Skill source not found at ${skillSrc} — is the package installed correctly?`);
|
|
26
|
+
}
|
|
27
|
+
await cp(skillSrc, SKILL_DEST, { recursive: true });
|
|
28
|
+
this.log(`Skill installed to ${SKILL_DEST}`);
|
|
29
|
+
this.log('Restart Claude Code (or reload skills) to activate.');
|
|
30
|
+
return { installed: SKILL_DEST };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=install-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../../../src/commands/agentpmd/install-skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,yEAAyE;AACzE,mEAAmE;AACnE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;AAEzE,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,SAAgC;IACzE,MAAM,CAAU,WAAW,GAAG;;wEAEiC,CAAC;IAChE,MAAM,CAAU,QAAQ,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3D,MAAM,CAAU,OAAO,GAAG,mEAAmE,CAAC;IAE9F,KAAK,CAAC,GAAG;QACd,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,0EAA0E;QAC1E,iCAAiC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAExC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,6BAA6B,QAAQ,wCAAwC,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpD,IAAI,CAAC,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QAEhE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IACnC,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AnalysisReport } from '../analyzer/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Single CSV with all per-procedure and per-method rows so a spreadsheet
|
|
4
|
+
* can pivot on `type` and `file`. RFC 4180-quoted; first row is the header.
|
|
5
|
+
*/
|
|
6
|
+
export declare function renderCsv(report: AnalysisReport): string;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single CSV with all per-procedure and per-method rows so a spreadsheet
|
|
3
|
+
* can pivot on `type` and `file`. RFC 4180-quoted; first row is the header.
|
|
4
|
+
*/
|
|
5
|
+
export function renderCsv(report) {
|
|
6
|
+
const lines = [];
|
|
7
|
+
lines.push([
|
|
8
|
+
'type',
|
|
9
|
+
'file',
|
|
10
|
+
'scope_or_class',
|
|
11
|
+
'name',
|
|
12
|
+
'complexity',
|
|
13
|
+
'start_row',
|
|
14
|
+
'start_col',
|
|
15
|
+
'contributors',
|
|
16
|
+
]
|
|
17
|
+
.map((c) => csvCell(c))
|
|
18
|
+
.join(','));
|
|
19
|
+
for (const f of report.files) {
|
|
20
|
+
for (const p of f.procedures) {
|
|
21
|
+
lines.push([
|
|
22
|
+
'agent_procedure',
|
|
23
|
+
f.path,
|
|
24
|
+
p.scope,
|
|
25
|
+
p.kind,
|
|
26
|
+
String(p.complexity),
|
|
27
|
+
String(p.location.startRow),
|
|
28
|
+
String(p.location.startCol),
|
|
29
|
+
breakdownProc(p.contributors),
|
|
30
|
+
]
|
|
31
|
+
.map((c) => csvCell(c))
|
|
32
|
+
.join(','));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
for (const cls of report.apexClasses) {
|
|
36
|
+
for (const m of cls.methods) {
|
|
37
|
+
lines.push([
|
|
38
|
+
'apex_method',
|
|
39
|
+
cls.path,
|
|
40
|
+
cls.className,
|
|
41
|
+
m.signature,
|
|
42
|
+
String(m.complexity),
|
|
43
|
+
String(m.location.startRow),
|
|
44
|
+
String(m.location.startCol),
|
|
45
|
+
breakdownApex(m.contributors),
|
|
46
|
+
]
|
|
47
|
+
.map((c) => csvCell(c))
|
|
48
|
+
.join(','));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return lines.join('\n');
|
|
52
|
+
}
|
|
53
|
+
function csvCell(v) {
|
|
54
|
+
// Always quote — keeps the output uniform and lets cells contain
|
|
55
|
+
// commas, quotes, and newlines without per-cell branching.
|
|
56
|
+
return `"${v.replaceAll('"', '""')}"`;
|
|
57
|
+
}
|
|
58
|
+
function breakdownProc(contributors) {
|
|
59
|
+
if (contributors.length === 0)
|
|
60
|
+
return 'base';
|
|
61
|
+
const counts = {};
|
|
62
|
+
for (const c of contributors)
|
|
63
|
+
counts[c.kind] = (counts[c.kind] ?? 0) + 1;
|
|
64
|
+
return Object.entries(counts)
|
|
65
|
+
.map(([k, n]) => `${k}=${n}`)
|
|
66
|
+
.join(';');
|
|
67
|
+
}
|
|
68
|
+
function breakdownApex(contributors) {
|
|
69
|
+
if (contributors.length === 0)
|
|
70
|
+
return 'base';
|
|
71
|
+
const counts = {};
|
|
72
|
+
for (const c of contributors)
|
|
73
|
+
counts[c.kind] = (counts[c.kind] ?? 0) + 1;
|
|
74
|
+
return Object.entries(counts)
|
|
75
|
+
.map(([k, n]) => `${k}=${n}`)
|
|
76
|
+
.join(';');
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=csv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/renderers/csv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AnalysisReport } from '../analyzer/types.js';
|
|
2
|
+
import type { RenderFormat, RenderOptions } from './options.js';
|
|
3
|
+
export declare function render(format: RenderFormat, report: AnalysisReport, options?: RenderOptions): string;
|
|
4
|
+
export { renderCsv } from './csv.js';
|
|
5
|
+
export { renderMarkdown } from './markdown.js';
|
|
6
|
+
export type { RenderFormat, RenderOptions } from './options.js';
|
|
7
|
+
export { renderSarif } from './sarif.js';
|
|
8
|
+
export { renderText } from './text.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { renderCsv } from './csv.js';
|
|
2
|
+
import { renderMarkdown } from './markdown.js';
|
|
3
|
+
import { renderSarif } from './sarif.js';
|
|
4
|
+
import { renderText } from './text.js';
|
|
5
|
+
export function render(format, report, options) {
|
|
6
|
+
switch (format) {
|
|
7
|
+
case 'csv': {
|
|
8
|
+
return renderCsv(report);
|
|
9
|
+
}
|
|
10
|
+
case 'markdown': {
|
|
11
|
+
return renderMarkdown(report);
|
|
12
|
+
}
|
|
13
|
+
case 'sarif': {
|
|
14
|
+
return renderSarif(report, options);
|
|
15
|
+
}
|
|
16
|
+
case 'text': {
|
|
17
|
+
return renderText(report, options);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export { renderCsv } from './csv.js';
|
|
22
|
+
export { renderMarkdown } from './markdown.js';
|
|
23
|
+
export { renderSarif } from './sarif.js';
|
|
24
|
+
export { renderText } from './text.js';
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderers/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,UAAU,MAAM,CACpB,MAAoB,EACpB,MAAsB,EACtB,OAAuB;IAEvB,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAED,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QAED,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,OAAO,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;AACH,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AnalysisReport } from '../analyzer/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Renders a GFM Markdown report with a Mermaid bar chart at the top
|
|
4
|
+
* (agent CC vs Apex CC per bundle) followed by per-bundle and per-class
|
|
5
|
+
* drilldown tables. Designed to be portable into PR descriptions, gists,
|
|
6
|
+
* Slack snippets, and whitepaper appendices.
|
|
7
|
+
*
|
|
8
|
+
* Palette is whitepaper § 1: Reasoning hot (#a82820), Conversation amber
|
|
9
|
+
* (#c4942a), Deterministic green (#6b8c52), Scaffolding cool gray (#9aa5ad).
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderMarkdown(report: AnalysisReport): string;
|
|
12
|
+
export { type ApexClassReport } from '../analyzer/types.js';
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
const KIND_LABEL = {
|
|
2
|
+
after_reasoning: 'after_reasoning',
|
|
3
|
+
available_when: 'available_when',
|
|
4
|
+
before_reasoning: 'before_reasoning',
|
|
5
|
+
other: 'other',
|
|
6
|
+
reasoning_instructions: 'reasoning.instructions',
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Renders a GFM Markdown report with a Mermaid bar chart at the top
|
|
10
|
+
* (agent CC vs Apex CC per bundle) followed by per-bundle and per-class
|
|
11
|
+
* drilldown tables. Designed to be portable into PR descriptions, gists,
|
|
12
|
+
* Slack snippets, and whitepaper appendices.
|
|
13
|
+
*
|
|
14
|
+
* Palette is whitepaper § 1: Reasoning hot (#a82820), Conversation amber
|
|
15
|
+
* (#c4942a), Deterministic green (#6b8c52), Scaffolding cool gray (#9aa5ad).
|
|
16
|
+
*/
|
|
17
|
+
export function renderMarkdown(report) {
|
|
18
|
+
const lines = [];
|
|
19
|
+
lines.push('# AgentForce PMD — Cyclomatic Complexity (McCabe)', '', 'Per the categorization rule § 7, CC is reported by the standard ' +
|
|
20
|
+
'McCabe convention used in SonarQube / PMD / Checkstyle for the ' +
|
|
21
|
+
'relevant language.', '');
|
|
22
|
+
if (report.files.length === 0) {
|
|
23
|
+
lines.push('_(no `.agent` files found)_');
|
|
24
|
+
return lines.join('\n');
|
|
25
|
+
}
|
|
26
|
+
// ── CC by location chart ──────────────────────────────────────────
|
|
27
|
+
lines.push('## CC by location', '', renderMermaid(report), '', `| | AgentScript | Apex | Combined |\n` +
|
|
28
|
+
`| --- | ---: | ---: | ---: |\n` +
|
|
29
|
+
`| **Totals** | ${report.totalComplexity} | ${report.totalApexComplexity} | ${report.totalComplexity + report.totalApexComplexity} |`, '', '## Per-bundle (`.agent` files)', '');
|
|
30
|
+
for (const f of report.files) {
|
|
31
|
+
lines.push(`### \`${f.path}\` — CC = ${f.fileComplexity}`, '');
|
|
32
|
+
if (f.procedures.length === 0) {
|
|
33
|
+
lines.push('_(no procedure-bearing scopes)_');
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
lines.push('| Scope | Procedure | CC | Contributors |', '| --- | --- | ---: | --- |');
|
|
37
|
+
for (const p of f.procedures) {
|
|
38
|
+
lines.push(`| ${escapeCell(p.scope)} | ${KIND_LABEL[p.kind]} | ${p.complexity} | ${escapeCell(breakdownProc(p.contributors))} |`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
lines.push('');
|
|
42
|
+
if (f.declarations.length > 0) {
|
|
43
|
+
lines.push('**Action references**', '', '| Action | Target kind | Target | Uses |', '| --- | --- | --- | ---: |');
|
|
44
|
+
const usage = countReferences(f);
|
|
45
|
+
for (const d of f.declarations) {
|
|
46
|
+
const used = usage.get(d.name) ?? 0;
|
|
47
|
+
lines.push(`| \`${d.name}\` | ${d.targetKind} | ${d.target ?? '_n/a_'} | ${used} |`);
|
|
48
|
+
}
|
|
49
|
+
const undeclared = listUndeclaredRefs(f);
|
|
50
|
+
if (undeclared.length > 0) {
|
|
51
|
+
lines.push('', 'Referenced but not declared in-file: ' + undeclared.map(u => `\`${u}\``).join(', '));
|
|
52
|
+
}
|
|
53
|
+
lines.push('');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// ── Apex backing logic ────────────────────────────────────────────
|
|
57
|
+
if (report.apexClasses.length > 0 || report.unresolvedApexTargets.length > 0) {
|
|
58
|
+
lines.push('## Apex backing logic', '');
|
|
59
|
+
for (const cls of report.apexClasses) {
|
|
60
|
+
lines.push(`### \`${cls.path}\` — class CC = ${cls.classComplexity}`, '', `Referenced by: ${cls.referencedBy.map(r => `\`${r}\``).join(', ') || '_none_'}`, '');
|
|
61
|
+
if (cls.methods.length === 0) {
|
|
62
|
+
lines.push('_(no methods with bodies)_');
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
lines.push('| Method | CC | Contributors |', '| --- | ---: | --- |');
|
|
66
|
+
for (const m of cls.methods) {
|
|
67
|
+
lines.push(`| \`${escapeCell(m.signature)}\` | ${m.complexity} | ${escapeCell(breakdownApex(m.contributors))} |`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
lines.push('');
|
|
71
|
+
}
|
|
72
|
+
if (report.unresolvedApexTargets.length > 0) {
|
|
73
|
+
lines.push('### Unresolved `apex://` targets', '');
|
|
74
|
+
for (const u of report.unresolvedApexTargets) {
|
|
75
|
+
lines.push(`- \`${u}\` — no matching \`.cls\` under \`--source-dir\` or \`--apex-source\``);
|
|
76
|
+
}
|
|
77
|
+
lines.push('');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// ── Footer ────────────────────────────────────────────────────────
|
|
81
|
+
lines.push('---', '', `Action declarations: **${report.totalDeclarations}** ` +
|
|
82
|
+
`(apex ${report.byTargetKind.apex}, flow ${report.byTargetKind.flow}, ` +
|
|
83
|
+
`prompt ${report.byTargetKind.prompt}, unknown ${report.byTargetKind.unknown}). ` +
|
|
84
|
+
`Action references: **${report.totalReferences}**.`);
|
|
85
|
+
return lines.join('\n');
|
|
86
|
+
}
|
|
87
|
+
function renderMermaid(report) {
|
|
88
|
+
// Per-bundle agent CC + the sum of Apex CC for classes that bundle
|
|
89
|
+
// references. We compute that mapping rather than counting classes
|
|
90
|
+
// globally so each bundle's bar reflects its full "implementation
|
|
91
|
+
// CC" footprint.
|
|
92
|
+
const apexByBundle = new Map();
|
|
93
|
+
for (const cls of report.apexClasses) {
|
|
94
|
+
for (const ref of cls.referencedBy) {
|
|
95
|
+
apexByBundle.set(ref, (apexByBundle.get(ref) ?? 0) + cls.classComplexity);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const labels = [];
|
|
99
|
+
const agentVals = [];
|
|
100
|
+
const apexVals = [];
|
|
101
|
+
for (const f of report.files) {
|
|
102
|
+
labels.push(shortBundleLabel(f.path));
|
|
103
|
+
agentVals.push(f.fileComplexity);
|
|
104
|
+
apexVals.push(apexByBundle.get(f.path) ?? 0);
|
|
105
|
+
}
|
|
106
|
+
// Mermaid xychart-beta supports stacked-bar style via two series.
|
|
107
|
+
// Palette: AgentScript = Reasoning red (#a82820); Apex = Deterministic green (#6b8c52).
|
|
108
|
+
return [
|
|
109
|
+
'```mermaid',
|
|
110
|
+
'%%{init: {"theme":"base","themeVariables":{"xyChart":{"plotColorPalette":"#a82820, #6b8c52"}}}}%%',
|
|
111
|
+
'xychart-beta',
|
|
112
|
+
' title "CC by location, per .agent bundle"',
|
|
113
|
+
` x-axis [${labels.map(l => `"${l}"`).join(', ')}]`,
|
|
114
|
+
` y-axis "Cyclomatic complexity"`,
|
|
115
|
+
` bar [${agentVals.join(', ')}]`,
|
|
116
|
+
` bar [${apexVals.join(', ')}]`,
|
|
117
|
+
'```',
|
|
118
|
+
'',
|
|
119
|
+
'<sub>Series: **AgentScript CC** (red, whitepaper "Reasoning Logic") · **Apex CC** (green, whitepaper "Deterministic Logic"). Apex CC per bundle is the sum of the CC of every `apex://` class that bundle references; classes referenced by multiple bundles contribute to each.</sub>',
|
|
120
|
+
].join('\n');
|
|
121
|
+
}
|
|
122
|
+
function shortBundleLabel(path) {
|
|
123
|
+
// Strip "aiAuthoringBundles/" and the trailing ".agent" to keep x-axis tight.
|
|
124
|
+
const stripped = path
|
|
125
|
+
.replace(/^.*aiAuthoringBundles\//, '')
|
|
126
|
+
.replace(/\.agent$/, '');
|
|
127
|
+
// Use only the basename if it appears twice (Bundle/Bundle.agent → Bundle).
|
|
128
|
+
const parts = stripped.split('/');
|
|
129
|
+
if (parts.length === 2 && parts[0] === parts[1])
|
|
130
|
+
return parts[0];
|
|
131
|
+
return parts.join('/');
|
|
132
|
+
}
|
|
133
|
+
function breakdownProc(contributors) {
|
|
134
|
+
if (contributors.length === 0)
|
|
135
|
+
return '(base only)';
|
|
136
|
+
const counts = {};
|
|
137
|
+
for (const c of contributors)
|
|
138
|
+
counts[c.kind] = (counts[c.kind] ?? 0) + 1;
|
|
139
|
+
return Object.entries(counts)
|
|
140
|
+
.map(([k, n]) => `${shortKind(k)}=${n}`)
|
|
141
|
+
.join(' ');
|
|
142
|
+
}
|
|
143
|
+
function breakdownApex(contributors) {
|
|
144
|
+
if (contributors.length === 0)
|
|
145
|
+
return '(base only)';
|
|
146
|
+
const counts = {};
|
|
147
|
+
for (const c of contributors)
|
|
148
|
+
counts[c.kind] = (counts[c.kind] ?? 0) + 1;
|
|
149
|
+
return Object.entries(counts)
|
|
150
|
+
.map(([k, n]) => `${shortApexKind(k)}=${n}`)
|
|
151
|
+
.join(' ');
|
|
152
|
+
}
|
|
153
|
+
function shortKind(k) {
|
|
154
|
+
switch (k) {
|
|
155
|
+
case 'elif_clause': {
|
|
156
|
+
return 'elif';
|
|
157
|
+
}
|
|
158
|
+
case 'if_statement': {
|
|
159
|
+
return 'if';
|
|
160
|
+
}
|
|
161
|
+
case 'short_circuit_and': {
|
|
162
|
+
return 'and';
|
|
163
|
+
}
|
|
164
|
+
case 'short_circuit_or': {
|
|
165
|
+
return 'or';
|
|
166
|
+
}
|
|
167
|
+
case 'ternary_expression': {
|
|
168
|
+
return 'ternary';
|
|
169
|
+
}
|
|
170
|
+
default: {
|
|
171
|
+
return k;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function shortApexKind(k) {
|
|
176
|
+
switch (k) {
|
|
177
|
+
case 'catch_clause': {
|
|
178
|
+
return 'catch';
|
|
179
|
+
}
|
|
180
|
+
case 'do_while_statement': {
|
|
181
|
+
return 'do-while';
|
|
182
|
+
}
|
|
183
|
+
case 'for_statement': {
|
|
184
|
+
return 'for';
|
|
185
|
+
}
|
|
186
|
+
case 'if_statement': {
|
|
187
|
+
return 'if';
|
|
188
|
+
}
|
|
189
|
+
case 'short_circuit_and': {
|
|
190
|
+
return '&&';
|
|
191
|
+
}
|
|
192
|
+
case 'short_circuit_or': {
|
|
193
|
+
return '||';
|
|
194
|
+
}
|
|
195
|
+
case 'ternary': {
|
|
196
|
+
return 'ternary';
|
|
197
|
+
}
|
|
198
|
+
case 'when_arm': {
|
|
199
|
+
return 'when';
|
|
200
|
+
}
|
|
201
|
+
case 'while_statement': {
|
|
202
|
+
return 'while';
|
|
203
|
+
}
|
|
204
|
+
default: {
|
|
205
|
+
return k;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function countReferences(f) {
|
|
210
|
+
const m = new Map();
|
|
211
|
+
for (const r of f.references)
|
|
212
|
+
m.set(r.name, (m.get(r.name) ?? 0) + 1);
|
|
213
|
+
return m;
|
|
214
|
+
}
|
|
215
|
+
function listUndeclaredRefs(f) {
|
|
216
|
+
const declared = new Set(f.declarations.map(d => d.name));
|
|
217
|
+
const seen = new Set();
|
|
218
|
+
const out = [];
|
|
219
|
+
for (const r of f.references) {
|
|
220
|
+
if (declared.has(r.name))
|
|
221
|
+
continue;
|
|
222
|
+
if (seen.has(r.name))
|
|
223
|
+
continue;
|
|
224
|
+
seen.add(r.name);
|
|
225
|
+
out.push(r.name);
|
|
226
|
+
}
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
function escapeCell(s) {
|
|
230
|
+
// GFM table cells: escape pipes and turn embedded newlines into <br>.
|
|
231
|
+
return s.replaceAll('|', String.raw `\|`).replaceAll('\n', '<br>');
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/renderers/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AnalysisReport } from '../analyzer/types.js';
|
|
2
|
+
export type RenderFormat = 'csv' | 'markdown' | 'sarif' | 'text';
|
|
3
|
+
export interface RenderOptions {
|
|
4
|
+
/** Force ASCII-only output (no Unicode box chars, no emoji). Default: auto. */
|
|
5
|
+
ascii?: boolean;
|
|
6
|
+
/** Force/disable color in text output. Default: auto (TTY + no NO_COLOR). */
|
|
7
|
+
color?: boolean;
|
|
8
|
+
sarifErrorThreshold?: number;
|
|
9
|
+
/**
|
|
10
|
+
* SARIF severity thresholds. Methods/procedures with complexity at or above
|
|
11
|
+
* `warning` are flagged `level: warning`; at or above `error` → `level: error`.
|
|
12
|
+
* Default: warning=10, error=20 (matches PMD's methodReportLevel default).
|
|
13
|
+
*/
|
|
14
|
+
sarifWarningThreshold?: number;
|
|
15
|
+
/** Rule width for the text renderer. Default: 60. */
|
|
16
|
+
width?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface Renderer {
|
|
19
|
+
render(report: AnalysisReport, options?: RenderOptions): string;
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/renderers/options.ts"],"names":[],"mappings":""}
|