@cspeach/cli 0.6.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 +8 -0
- package/README.md +108 -0
- package/dist/agent/anthropic-provider.js +59 -0
- package/dist/agent/llm-provider.js +1 -0
- package/dist/agent/loop.js +709 -0
- package/dist/agent/maybe-build-project-context.js +126 -0
- package/dist/agent/providers/ai-hub-provider.js +58 -0
- package/dist/agent/providers/byok-provider.js +53 -0
- package/dist/agent/providers/factory.js +13 -0
- package/dist/agent/providers/local-provider.js +125 -0
- package/dist/agent/repair-partial.js +31 -0
- package/dist/agent/retry-key.js +58 -0
- package/dist/agent/retry.js +17 -0
- package/dist/agent/sap-connection-adapter.js +82 -0
- package/dist/agent/skill-checkpoint.js +119 -0
- package/dist/agent/tool-dispatch.js +47 -0
- package/dist/agent/turn-assistant-text.js +49 -0
- package/dist/agent/turn-error-ux.js +126 -0
- package/dist/agent/turn-stream.js +79 -0
- package/dist/agent/turn-watchdog.js +71 -0
- package/dist/approvals/advisory-prompt.js +40 -0
- package/dist/approvals/advisory-render.js +38 -0
- package/dist/approvals/approval-prompt.js +100 -0
- package/dist/approvals/jwt.js +33 -0
- package/dist/approvals/render.js +211 -0
- package/dist/approvals/risk-floor.js +26 -0
- package/dist/auth/api-key.js +40 -0
- package/dist/auth/auth-file.js +59 -0
- package/dist/auth/device.js +8 -0
- package/dist/auth/me.js +19 -0
- package/dist/classifier/client.js +58 -0
- package/dist/cli-args.js +38 -0
- package/dist/cli.js +148 -0
- package/dist/commands/config-set.js +245 -0
- package/dist/commands/config-show.js +159 -0
- package/dist/commands/help.js +93 -0
- package/dist/commands/login.js +122 -0
- package/dist/commands/logout.js +17 -0
- package/dist/commands/project-context-impact.js +215 -0
- package/dist/commands/reroute.js +60 -0
- package/dist/commands/spec-gap-status.js +52 -0
- package/dist/commands/whoami.js +35 -0
- package/dist/config/loader.js +67 -0
- package/dist/config/paths.js +20 -0
- package/dist/doctor/checks/_http-probe.js +56 -0
- package/dist/doctor/checks/auth.js +15 -0
- package/dist/doctor/checks/cert.js +24 -0
- package/dist/doctor/checks/forge-rules.js +102 -0
- package/dist/doctor/checks/keychain-fallback.js +14 -0
- package/dist/doctor/checks/keychain.js +23 -0
- package/dist/doctor/checks/llm-mode.js +27 -0
- package/dist/doctor/checks/proxy.js +13 -0
- package/dist/doctor/checks/sap.js +33 -0
- package/dist/doctor/checks/skill.js +24 -0
- package/dist/doctor/checks/write-mode.js +34 -0
- package/dist/doctor/checks/zcspeach.js +76 -0
- package/dist/doctor/run.js +46 -0
- package/dist/errors/codes.js +12 -0
- package/dist/index.js +6 -0
- package/dist/lock-contention.js +22 -0
- package/dist/one-shot.js +104 -0
- package/dist/project-context/conventions.js +309 -0
- package/dist/project-context/detect.js +250 -0
- package/dist/project-context/domain/abap-cloud.js +26 -0
- package/dist/project-context/domain/abapgit.js +177 -0
- package/dist/project-context/domain/cap.js +164 -0
- package/dist/project-context/domain/fiori.js +326 -0
- package/dist/project-context/git.js +115 -0
- package/dist/project-context/index-files.js +235 -0
- package/dist/project-context/index.js +117 -0
- package/dist/project-context/render.js +308 -0
- package/dist/project-context/types.js +14 -0
- package/dist/projects/build.js +20 -0
- package/dist/projects/canonicalize.js +39 -0
- package/dist/projects/email-template.js +54 -0
- package/dist/projects/extract-cca.js +139 -0
- package/dist/projects/extract-design.js +107 -0
- package/dist/projects/extract-estimate.js +93 -0
- package/dist/projects/extract-modernize.js +130 -0
- package/dist/projects/extract-spec-gap.js +101 -0
- package/dist/projects/extract-test-coverage.js +137 -0
- package/dist/projects/extract-upgrade.js +230 -0
- package/dist/projects/filename.js +18 -0
- package/dist/projects/index.js +8 -0
- package/dist/projects/migration.js +111 -0
- package/dist/projects/promote-command.js +96 -0
- package/dist/projects/promote.js +107 -0
- package/dist/projects/save-command.js +124 -0
- package/dist/projects/save.js +21 -0
- package/dist/projects/status.js +170 -0
- package/dist/projects/types.js +1 -0
- package/dist/projects/validate.js +146 -0
- package/dist/projects/workspace.js +478 -0
- package/dist/renderer/abap-inline.js +121 -0
- package/dist/renderer/banners.js +39 -0
- package/dist/renderer/highlighters/abap.js +126 -0
- package/dist/renderer/highlighters/bdef.js +81 -0
- package/dist/renderer/highlighters/cds.js +91 -0
- package/dist/renderer/markdown.js +291 -0
- package/dist/renderer/pipeline.js +201 -0
- package/dist/renderer/progress-chatter.js +237 -0
- package/dist/renderer/question-normalizer.js +306 -0
- package/dist/renderer/severity.js +61 -0
- package/dist/renderer/status-footer.js +50 -0
- package/dist/renderer/syntax.js +58 -0
- package/dist/renderer/tables.js +55 -0
- package/dist/renderer/thinking-heartbeat.js +70 -0
- package/dist/renderer/tool-widget.js +199 -0
- package/dist/renderer/tty.js +66 -0
- package/dist/renderer/widget-extractor.js +87 -0
- package/dist/renderer/widget-fallback.js +78 -0
- package/dist/renderer/widget-schemas.js +43 -0
- package/dist/repl/at-completer.js +64 -0
- package/dist/repl/at-picker.js +122 -0
- package/dist/repl/bracketed-paste.js +284 -0
- package/dist/repl/current-transport.js +46 -0
- package/dist/repl/diff-display.js +41 -0
- package/dist/repl/file-picker.js +219 -0
- package/dist/repl/inquirer-guard.js +130 -0
- package/dist/repl/inquirer-theme.js +41 -0
- package/dist/repl/rule8-detector.js +99 -0
- package/dist/repl/safety-confirm.js +106 -0
- package/dist/repl/safety-mode-state.js +36 -0
- package/dist/repl/slash-completer.js +59 -0
- package/dist/repl/slash-picker.js +124 -0
- package/dist/repl/update-method-preview-hook.js +45 -0
- package/dist/repl.js +1383 -0
- package/dist/router/classifier.js +38 -0
- package/dist/router/intent-extractor.js +140 -0
- package/dist/router/routing-decision.js +19 -0
- package/dist/sap/connection-manager.js +52 -0
- package/dist/sap/onboarding.js +178 -0
- package/dist/sap/system-info.js +515 -0
- package/dist/session/awaiting-answer.js +73 -0
- package/dist/session/gc.js +28 -0
- package/dist/session/pending.js +37 -0
- package/dist/session/resume.js +77 -0
- package/dist/session/schema.js +20 -0
- package/dist/session/store.js +147 -0
- package/dist/session/time-ago.js +41 -0
- package/dist/skill-catalog.js +222 -0
- package/dist/skills/bundled-skills.js +1 -0
- package/dist/skills/canonical.js +12 -0
- package/dist/skills/manifest-client.js +93 -0
- package/dist/skills/promotion-dispatch.js +24 -0
- package/dist/skills/signing-public-key.js +4 -0
- package/dist/skills/source-bundled.js +20 -0
- package/dist/skills/source-managed.js +26 -0
- package/dist/skills/source-manifest.js +26 -0
- package/dist/tools/_command-shared.js +110 -0
- package/dist/tools/_filesystem-shared.js +81 -0
- package/dist/tools/_flag.js +39 -0
- package/dist/tools/approval.js +228 -0
- package/dist/tools/ask-question.js +205 -0
- package/dist/tools/dispatch-skill.js +81 -0
- package/dist/tools/filesystem/file-edit.js +140 -0
- package/dist/tools/filesystem/file-read.js +89 -0
- package/dist/tools/filesystem/file-write.js +128 -0
- package/dist/tools/filesystem/glob.js +177 -0
- package/dist/tools/filesystem/grep.js +163 -0
- package/dist/tools/index.js +32 -0
- package/dist/tools/project/convention_get.js +91 -0
- package/dist/tools/project/playbook_get.js +132 -0
- package/dist/tools/project/project_context_get.js +101 -0
- package/dist/tools/sap-read.js +454 -0
- package/dist/tools/sap-write.js +746 -0
- package/dist/tools/shell/shell_exec.js +209 -0
- package/dist/tools/snapshot.js +107 -0
- package/dist/tools/subagent/_background-shared.js +133 -0
- package/dist/tools/subagent/agent_run.js +186 -0
- package/dist/tools/subagent/background_run.js +143 -0
- package/dist/tools/subagent/monitor_emit.js +65 -0
- package/dist/tools/subagent/schedule_create.js +131 -0
- package/dist/tools/transport.js +233 -0
- package/dist/tools/update-method-intercept.js +119 -0
- package/dist/tools/verify.js +39 -0
- package/dist/tools/web/_web-shared.js +251 -0
- package/dist/tools/web/web_fetch.js +257 -0
- package/dist/tools/web/web_search.js +195 -0
- package/dist/tools/write-mode.js +22 -0
- package/dist/ui/app.js +95 -0
- package/dist/ui/approval-emitter.js +10 -0
- package/dist/ui/approval-modal.js +53 -0
- package/dist/ui/ascii-chars.js +6 -0
- package/dist/ui/body.js +102 -0
- package/dist/ui/coaching-picker-classic.js +36 -0
- package/dist/ui/coaching-picker-emitter.js +27 -0
- package/dist/ui/command-palette.js +34 -0
- package/dist/ui/error-emitter.js +21 -0
- package/dist/ui/footer.js +103 -0
- package/dist/ui/header.js +17 -0
- package/dist/ui/ink-classifier-route.js +19 -0
- package/dist/ui/login-banner.js +72 -0
- package/dist/ui/rich-error-box.js +9 -0
- package/dist/ui/sap-state-store.js +65 -0
- package/dist/ui/session-timeline.js +31 -0
- package/dist/ui/sidebar.js +10 -0
- package/dist/ui/skill-picker.js +50 -0
- package/dist/ui/status-row.js +12 -0
- package/dist/ui/widget-control.js +4 -0
- package/dist/ui/widgets/bar-chart.js +15 -0
- package/dist/ui/widgets/coaching-picker.js +41 -0
- package/dist/ui/widgets/component-registry.js +12 -0
- package/dist/ui/widgets/dep-graph.js +9 -0
- package/dist/ui/widgets/diff-viewer.js +11 -0
- package/dist/ui/widgets/question-card.js +11 -0
- package/dist/ui/widgets/stack-frames.js +5 -0
- package/dist/upgrade-check.js +28 -0
- package/dist/upgrade.js +13 -0
- package/package.json +83 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* project_context_get — Phase 3 / Chunk 3D.
|
|
3
|
+
*
|
|
4
|
+
* On-demand refresh of the rendered <project_context> block. Wraps
|
|
5
|
+
* Phase 2's getProjectContext + Phase 2.5's resetProjectContextCache.
|
|
6
|
+
*
|
|
7
|
+
* Returns the rendered XML-flavored block (the same shape Phase 2
|
|
8
|
+
* splices into the first user message of a flag-on session). When
|
|
9
|
+
* force_refresh: true, the per-process cache is cleared first; the
|
|
10
|
+
* next render reflects whatever the project looks like NOW (post-file_write,
|
|
11
|
+
* post-checkout, post-SAP-state-change).
|
|
12
|
+
*
|
|
13
|
+
* Flag-gated: invisible to listTools() unless
|
|
14
|
+
* CSPEACH_TOOL_PROJECT_CONTEXT_GET=on. isMutating: false — reads only.
|
|
15
|
+
*
|
|
16
|
+
* Note on caching: this tool does NOT consult the
|
|
17
|
+
* CSPEACH_PROJECT_CONTEXT env flag — it always renders, regardless of
|
|
18
|
+
* whether the flag-gated Phase 2 enrichment is on. The flag gates
|
|
19
|
+
* AUTOMATIC injection; this tool is for EXPLICIT model-driven reads.
|
|
20
|
+
*/
|
|
21
|
+
import { registerTool } from '../index.js';
|
|
22
|
+
import { getProjectContext, renderProjectContext, } from '../../project-context/index.js';
|
|
23
|
+
import { resetProjectContextCache } from '../../agent/maybe-build-project-context.js';
|
|
24
|
+
// Tool-local one-shot cache so default (force_refresh: false) calls
|
|
25
|
+
// return the same render as the previous call in the same process.
|
|
26
|
+
// Cleared on force_refresh: true OR via __resetToolCacheForTests().
|
|
27
|
+
// Independent from the Phase 2 cachedBlock — that one is gated on
|
|
28
|
+
// the env flag; this one is always live for explicit tool calls.
|
|
29
|
+
let cachedRender = null;
|
|
30
|
+
/** Test-only: reset the tool-local cache between cases. */
|
|
31
|
+
export function __resetToolCacheForTests() {
|
|
32
|
+
cachedRender = null;
|
|
33
|
+
}
|
|
34
|
+
export async function projectContextGetHandler(args, ctx) {
|
|
35
|
+
if (args.force_refresh !== undefined && typeof args.force_refresh !== 'boolean') {
|
|
36
|
+
return {
|
|
37
|
+
content: `error: force_refresh must be a boolean (got ${typeof args.force_refresh}).`,
|
|
38
|
+
is_error: true,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
if (!ctx.cwd || typeof ctx.cwd !== 'string') {
|
|
42
|
+
return {
|
|
43
|
+
content: 'error: project_context_get requires a working directory (ctx.cwd).',
|
|
44
|
+
is_error: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (args.force_refresh === true) {
|
|
48
|
+
// Phase 2.5 public API. Also clears the one-shot warning latch.
|
|
49
|
+
resetProjectContextCache();
|
|
50
|
+
cachedRender = null;
|
|
51
|
+
}
|
|
52
|
+
else if (cachedRender !== null) {
|
|
53
|
+
return { content: cachedRender };
|
|
54
|
+
}
|
|
55
|
+
let pc;
|
|
56
|
+
try {
|
|
57
|
+
pc = await getProjectContext(ctx.cwd);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
return {
|
|
61
|
+
content: `error: project context computation failed — ${err instanceof Error ? err.message : String(err)}`,
|
|
62
|
+
is_error: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (pc === null) {
|
|
66
|
+
const empty = '<project_context>(no project detected for this working directory)</project_context>';
|
|
67
|
+
cachedRender = empty;
|
|
68
|
+
return { content: empty };
|
|
69
|
+
}
|
|
70
|
+
let rendered;
|
|
71
|
+
try {
|
|
72
|
+
rendered = renderProjectContext(pc);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
return {
|
|
76
|
+
content: `error: project context render failed — ${err instanceof Error ? err.message : String(err)}`,
|
|
77
|
+
is_error: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
cachedRender = rendered;
|
|
81
|
+
return { content: rendered };
|
|
82
|
+
}
|
|
83
|
+
registerTool({
|
|
84
|
+
name: 'project_context_get',
|
|
85
|
+
description: "Return the rendered <project_context> block for the current working directory. " +
|
|
86
|
+
"Useful when the model needs a fresh view of the project after a write, a checkout, or a SAP state change. " +
|
|
87
|
+
"Pass force_refresh: true to invalidate the per-process cache first; default false returns the cached render.",
|
|
88
|
+
isMutating: false,
|
|
89
|
+
category: 'project',
|
|
90
|
+
flagGated: true,
|
|
91
|
+
input_schema: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
properties: {
|
|
94
|
+
force_refresh: {
|
|
95
|
+
type: 'boolean',
|
|
96
|
+
description: "If true, clear the per-process project-context cache before rendering. Default false.",
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
handler: (args, ctx) => projectContextGetHandler(args, ctx),
|
|
101
|
+
});
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 18 read-only SAP tools wired to @cspeach/sap-client AdtClient.
|
|
3
|
+
*
|
|
4
|
+
* All method names verified against sap-client/src/adt-client.ts:
|
|
5
|
+
* getSource(type, name)
|
|
6
|
+
* objectStructure(type, name)
|
|
7
|
+
* searchObject(query, objType?, maxResults?)
|
|
8
|
+
* changeLog(type, name)
|
|
9
|
+
* sqlQuery(query, maxRows?, extraBlocked?)
|
|
10
|
+
* shortDump(dumpId?, user?)
|
|
11
|
+
* atcRun(type, name, variant?)
|
|
12
|
+
* usageReferences(objectType, objectName)
|
|
13
|
+
* apiState(objects)
|
|
14
|
+
* abapDocu(keyword)
|
|
15
|
+
* classIncludes(className, includeType?)
|
|
16
|
+
* inactiveObjects()
|
|
17
|
+
* syntaxCheck(type, name)
|
|
18
|
+
* diff(type, name, version1?, version2?)
|
|
19
|
+
* previewChange(type, name, newSource)
|
|
20
|
+
* runUnitTest(type, name)
|
|
21
|
+
* odataTest(servicePath, entity?, method?)
|
|
22
|
+
* badiList(query, enhancementSpot?, maxResults?)
|
|
23
|
+
*/
|
|
24
|
+
import { registerTool } from './index.js';
|
|
25
|
+
// -----------------------------------------------------------------------
|
|
26
|
+
// 1. sap_get_source
|
|
27
|
+
// -----------------------------------------------------------------------
|
|
28
|
+
registerTool({
|
|
29
|
+
name: 'sap_get_source',
|
|
30
|
+
description: 'Read the source code of an ABAP object by name and type.',
|
|
31
|
+
isMutating: false,
|
|
32
|
+
input_schema: {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: {
|
|
35
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
36
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF, DDLS' },
|
|
37
|
+
},
|
|
38
|
+
required: ['name', 'type'],
|
|
39
|
+
},
|
|
40
|
+
handler: async (args, ctx) => {
|
|
41
|
+
// AdtClient.getSource takes (type, name) — type first
|
|
42
|
+
const source = await ctx.adt.getSource(args.type, args.name);
|
|
43
|
+
return { content: source };
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
// -----------------------------------------------------------------------
|
|
47
|
+
// 2. sap_object_structure
|
|
48
|
+
// -----------------------------------------------------------------------
|
|
49
|
+
registerTool({
|
|
50
|
+
name: 'sap_object_structure',
|
|
51
|
+
description: 'Retrieve metadata and structural information for an ABAP repository object (package, description, lock state, etc.).',
|
|
52
|
+
isMutating: false,
|
|
53
|
+
input_schema: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
57
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF, DDLS' },
|
|
58
|
+
},
|
|
59
|
+
required: ['name', 'type'],
|
|
60
|
+
},
|
|
61
|
+
handler: async (args, ctx) => {
|
|
62
|
+
const result = await ctx.adt.objectStructure(args.type, args.name);
|
|
63
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
// -----------------------------------------------------------------------
|
|
67
|
+
// 3. sap_search_object
|
|
68
|
+
// -----------------------------------------------------------------------
|
|
69
|
+
registerTool({
|
|
70
|
+
name: 'sap_search_object',
|
|
71
|
+
description: 'Search the SAP repository by object name pattern. Supports wildcard * (e.g. ZCL_ORDER*).',
|
|
72
|
+
isMutating: false,
|
|
73
|
+
input_schema: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
query: { type: 'string', description: 'Name pattern, e.g. ZCL_ORDER* or ZHELLO*' },
|
|
77
|
+
type: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
description: 'Optional object type filter, e.g. PROG, CLAS, INTF, DDLS',
|
|
80
|
+
},
|
|
81
|
+
maxResults: {
|
|
82
|
+
type: 'number',
|
|
83
|
+
description: 'Maximum number of results (default 100)',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
required: ['query'],
|
|
87
|
+
},
|
|
88
|
+
handler: async (args, ctx) => {
|
|
89
|
+
const results = await ctx.adt.searchObject(args.query, args.type, args.maxResults ?? 100);
|
|
90
|
+
return { content: JSON.stringify(results, null, 2) };
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
// -----------------------------------------------------------------------
|
|
94
|
+
// 4. sap_change_log
|
|
95
|
+
// -----------------------------------------------------------------------
|
|
96
|
+
registerTool({
|
|
97
|
+
name: 'sap_change_log',
|
|
98
|
+
description: 'Retrieve the version history (change log) of an ABAP object — date, author, description per revision.',
|
|
99
|
+
isMutating: false,
|
|
100
|
+
input_schema: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {
|
|
103
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
104
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF, DDLS' },
|
|
105
|
+
},
|
|
106
|
+
required: ['name', 'type'],
|
|
107
|
+
},
|
|
108
|
+
handler: async (args, ctx) => {
|
|
109
|
+
const entries = await ctx.adt.changeLog(args.type, args.name);
|
|
110
|
+
return { content: JSON.stringify(entries, null, 2) };
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
// -----------------------------------------------------------------------
|
|
114
|
+
// 5. sap_sql_query
|
|
115
|
+
// -----------------------------------------------------------------------
|
|
116
|
+
registerTool({
|
|
117
|
+
name: 'sap_sql_query',
|
|
118
|
+
description: 'Execute a read-only SQL SELECT against the SAP database via ADT Data Preview. Security-sensitive tables are blocked automatically.',
|
|
119
|
+
isMutating: false,
|
|
120
|
+
input_schema: {
|
|
121
|
+
type: 'object',
|
|
122
|
+
properties: {
|
|
123
|
+
query: { type: 'string', description: 'SQL SELECT statement, e.g. SELECT * FROM mara WHERE matnr = \'MAT001\'' },
|
|
124
|
+
maxRows: { type: 'number', description: 'Maximum rows to return (default 100)' },
|
|
125
|
+
},
|
|
126
|
+
required: ['query'],
|
|
127
|
+
},
|
|
128
|
+
handler: async (args, ctx) => {
|
|
129
|
+
const result = await ctx.adt.sqlQuery(args.query, args.maxRows ?? 100);
|
|
130
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
// -----------------------------------------------------------------------
|
|
134
|
+
// 6. sap_short_dump
|
|
135
|
+
// -----------------------------------------------------------------------
|
|
136
|
+
registerTool({
|
|
137
|
+
name: 'sap_short_dump',
|
|
138
|
+
description: 'Read ABAP runtime errors (short dumps / ST22). Without dumpId returns a list of recent dumps; with dumpId returns the full diagnostic detail.',
|
|
139
|
+
isMutating: false,
|
|
140
|
+
input_schema: {
|
|
141
|
+
type: 'object',
|
|
142
|
+
properties: {
|
|
143
|
+
dumpId: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'Specific dump ID for detailed view (from a previous list call)',
|
|
146
|
+
},
|
|
147
|
+
user: {
|
|
148
|
+
type: 'string',
|
|
149
|
+
description: 'Filter dumps by SAP username (list mode only)',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
required: [],
|
|
153
|
+
},
|
|
154
|
+
handler: async (args, ctx) => {
|
|
155
|
+
const result = await ctx.adt.shortDump(args.dumpId, args.user);
|
|
156
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
// -----------------------------------------------------------------------
|
|
160
|
+
// 7. sap_atc_run
|
|
161
|
+
// -----------------------------------------------------------------------
|
|
162
|
+
registerTool({
|
|
163
|
+
name: 'sap_atc_run',
|
|
164
|
+
description: 'Run ABAP Test Cockpit (ATC) checks on a specific object and return all findings.',
|
|
165
|
+
isMutating: false,
|
|
166
|
+
input_schema: {
|
|
167
|
+
type: 'object',
|
|
168
|
+
properties: {
|
|
169
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
170
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF' },
|
|
171
|
+
variant: {
|
|
172
|
+
type: 'string',
|
|
173
|
+
description: 'ATC check variant (default: DEFAULT)',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
required: ['name', 'type'],
|
|
177
|
+
},
|
|
178
|
+
handler: async (args, ctx) => {
|
|
179
|
+
// atcRun(type, name, variant?) — type first
|
|
180
|
+
const result = await ctx.adt.atcRun(args.type, args.name, args.variant ?? 'DEFAULT');
|
|
181
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
// -----------------------------------------------------------------------
|
|
185
|
+
// 8. sap_usage_references
|
|
186
|
+
// -----------------------------------------------------------------------
|
|
187
|
+
registerTool({
|
|
188
|
+
name: 'sap_usage_references',
|
|
189
|
+
description: 'Find all places where a given ABAP object is referenced (where-used list).',
|
|
190
|
+
isMutating: false,
|
|
191
|
+
input_schema: {
|
|
192
|
+
type: 'object',
|
|
193
|
+
properties: {
|
|
194
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
195
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF, DDLS' },
|
|
196
|
+
},
|
|
197
|
+
required: ['name', 'type'],
|
|
198
|
+
},
|
|
199
|
+
handler: async (args, ctx) => {
|
|
200
|
+
// usageReferences(objectType, objectName) — type first
|
|
201
|
+
const refs = await ctx.adt.usageReferences(args.type, args.name);
|
|
202
|
+
return { content: JSON.stringify(refs, null, 2) };
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
// -----------------------------------------------------------------------
|
|
206
|
+
// 9. sap_api_state
|
|
207
|
+
// -----------------------------------------------------------------------
|
|
208
|
+
registerTool({
|
|
209
|
+
name: 'sap_api_state',
|
|
210
|
+
description: 'Check the ABAP Cloud / clean-core release state of SAP objects. Pass comma-separated TYPE:NAME pairs, e.g. "CLAS:CL_GUI_ALV_GRID,FUNC:BAPI_SALESORDER_GETLIST".',
|
|
211
|
+
isMutating: false,
|
|
212
|
+
input_schema: {
|
|
213
|
+
type: 'object',
|
|
214
|
+
properties: {
|
|
215
|
+
objects: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
description: 'Comma-separated TYPE:NAME pairs, e.g. "CLAS:CL_GUI_ALV_GRID,FUNC:BAPI_SALESORDER_GETLIST"',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
required: ['objects'],
|
|
221
|
+
},
|
|
222
|
+
handler: async (args, ctx) => {
|
|
223
|
+
// apiState(objects) — single comma-separated string
|
|
224
|
+
const result = await ctx.adt.apiState(args.objects);
|
|
225
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
// -----------------------------------------------------------------------
|
|
229
|
+
// 10. sap_abap_docu
|
|
230
|
+
// -----------------------------------------------------------------------
|
|
231
|
+
registerTool({
|
|
232
|
+
name: 'sap_abap_docu',
|
|
233
|
+
description: 'Retrieve official ABAP language documentation from the SAP system for a keyword, class, or function module.',
|
|
234
|
+
isMutating: false,
|
|
235
|
+
input_schema: {
|
|
236
|
+
type: 'object',
|
|
237
|
+
properties: {
|
|
238
|
+
keyword: {
|
|
239
|
+
type: 'string',
|
|
240
|
+
description: 'ABAP keyword, class name, or function module, e.g. SELECT, CL_ABAP_UNIT_ASSERT',
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
required: ['keyword'],
|
|
244
|
+
},
|
|
245
|
+
handler: async (args, ctx) => {
|
|
246
|
+
const docu = await ctx.adt.abapDocu(args.keyword);
|
|
247
|
+
return { content: docu };
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
// -----------------------------------------------------------------------
|
|
251
|
+
// 11. sap_class_includes
|
|
252
|
+
// -----------------------------------------------------------------------
|
|
253
|
+
registerTool({
|
|
254
|
+
name: 'sap_class_includes',
|
|
255
|
+
description: 'List the includes of an ABAP class, or read one specific include source (testclasses, locals_def, locals_imp, macros).',
|
|
256
|
+
isMutating: false,
|
|
257
|
+
input_schema: {
|
|
258
|
+
type: 'object',
|
|
259
|
+
properties: {
|
|
260
|
+
className: {
|
|
261
|
+
type: 'string',
|
|
262
|
+
description: 'Class name, e.g. ZCL_ORDER_HANDLER',
|
|
263
|
+
},
|
|
264
|
+
includeType: {
|
|
265
|
+
type: 'string',
|
|
266
|
+
enum: ['testclasses', 'locals_def', 'locals_imp', 'macros'],
|
|
267
|
+
description: 'Specific include to read; omit to list all includes',
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
required: ['className'],
|
|
271
|
+
},
|
|
272
|
+
handler: async (args, ctx) => {
|
|
273
|
+
const result = await ctx.adt.classIncludes(args.className, args.includeType);
|
|
274
|
+
// classIncludes returns string (source) when includeType is given, array otherwise
|
|
275
|
+
if (typeof result === 'string') {
|
|
276
|
+
return { content: result };
|
|
277
|
+
}
|
|
278
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
// -----------------------------------------------------------------------
|
|
282
|
+
// 12. sap_inactive_objects
|
|
283
|
+
// -----------------------------------------------------------------------
|
|
284
|
+
registerTool({
|
|
285
|
+
name: 'sap_inactive_objects',
|
|
286
|
+
description: 'List all ABAP objects that are currently inactive (not yet activated) in the system.',
|
|
287
|
+
isMutating: false,
|
|
288
|
+
input_schema: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
properties: {},
|
|
291
|
+
required: [],
|
|
292
|
+
},
|
|
293
|
+
handler: async (_args, ctx) => {
|
|
294
|
+
const result = await ctx.adt.inactiveObjects();
|
|
295
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
// -----------------------------------------------------------------------
|
|
299
|
+
// 13. sap_syntax_check
|
|
300
|
+
// -----------------------------------------------------------------------
|
|
301
|
+
registerTool({
|
|
302
|
+
name: 'sap_syntax_check',
|
|
303
|
+
description: 'Run a syntax check on an ABAP object and return any errors or warnings without activating it.',
|
|
304
|
+
isMutating: false,
|
|
305
|
+
input_schema: {
|
|
306
|
+
type: 'object',
|
|
307
|
+
properties: {
|
|
308
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
309
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF, DDLS' },
|
|
310
|
+
},
|
|
311
|
+
required: ['name', 'type'],
|
|
312
|
+
},
|
|
313
|
+
handler: async (args, ctx) => {
|
|
314
|
+
// syntaxCheck(type, name) — type first
|
|
315
|
+
const result = await ctx.adt.syntaxCheck(args.type, args.name);
|
|
316
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
// -----------------------------------------------------------------------
|
|
320
|
+
// 14. sap_diff
|
|
321
|
+
// -----------------------------------------------------------------------
|
|
322
|
+
registerTool({
|
|
323
|
+
name: 'sap_diff',
|
|
324
|
+
description: 'Compute a unified diff for an ABAP object between two optional source strings; if omitted, diffs the current version against the previous from the change log.',
|
|
325
|
+
isMutating: false,
|
|
326
|
+
input_schema: {
|
|
327
|
+
type: 'object',
|
|
328
|
+
properties: {
|
|
329
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
330
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF, DDLS' },
|
|
331
|
+
version1: {
|
|
332
|
+
type: 'string',
|
|
333
|
+
description: 'Optional "before" source text; omit to use the previous saved version',
|
|
334
|
+
},
|
|
335
|
+
version2: {
|
|
336
|
+
type: 'string',
|
|
337
|
+
description: 'Optional "after" source text; omit to use the current saved version',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
required: ['name', 'type'],
|
|
341
|
+
},
|
|
342
|
+
handler: async (args, ctx) => {
|
|
343
|
+
// diff(type, name, version1?, version2?) — type first
|
|
344
|
+
const result = await ctx.adt.diff(args.type, args.name, args.version1, args.version2);
|
|
345
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
// -----------------------------------------------------------------------
|
|
349
|
+
// 15. sap_preview_change
|
|
350
|
+
// -----------------------------------------------------------------------
|
|
351
|
+
registerTool({
|
|
352
|
+
name: 'sap_preview_change',
|
|
353
|
+
description: 'Preview a proposed source change for an ABAP object as a unified diff without writing anything to the system.',
|
|
354
|
+
isMutating: false,
|
|
355
|
+
input_schema: {
|
|
356
|
+
type: 'object',
|
|
357
|
+
properties: {
|
|
358
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
359
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG, INTF, DDLS' },
|
|
360
|
+
newSource: {
|
|
361
|
+
type: 'string',
|
|
362
|
+
description: 'The full proposed source code to compare against the current version',
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
required: ['name', 'type', 'newSource'],
|
|
366
|
+
},
|
|
367
|
+
handler: async (args, ctx) => {
|
|
368
|
+
// previewChange(type, name, newSource) — type first
|
|
369
|
+
const result = await ctx.adt.previewChange(args.type, args.name, args.newSource);
|
|
370
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
// -----------------------------------------------------------------------
|
|
374
|
+
// 16. sap_run_unit_test
|
|
375
|
+
// -----------------------------------------------------------------------
|
|
376
|
+
registerTool({
|
|
377
|
+
name: 'sap_run_unit_test',
|
|
378
|
+
description: 'Execute ABAP Unit tests for an object and return a structured pass/fail report with method-level results.',
|
|
379
|
+
isMutating: false,
|
|
380
|
+
input_schema: {
|
|
381
|
+
type: 'object',
|
|
382
|
+
properties: {
|
|
383
|
+
name: { type: 'string', description: 'Object name, e.g. ZCL_ORDER_HANDLER' },
|
|
384
|
+
type: { type: 'string', description: 'Object type token, e.g. CLAS, PROG' },
|
|
385
|
+
},
|
|
386
|
+
required: ['name', 'type'],
|
|
387
|
+
},
|
|
388
|
+
handler: async (args, ctx) => {
|
|
389
|
+
// runUnitTest(type, name) — type first
|
|
390
|
+
const result = await ctx.adt.runUnitTest(args.type, args.name);
|
|
391
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
// -----------------------------------------------------------------------
|
|
395
|
+
// 17. sap_odata_test
|
|
396
|
+
// -----------------------------------------------------------------------
|
|
397
|
+
registerTool({
|
|
398
|
+
name: 'sap_odata_test',
|
|
399
|
+
description: 'Test an OData service endpoint by issuing a GET or HEAD request and returning the HTTP status and response body.',
|
|
400
|
+
isMutating: false,
|
|
401
|
+
input_schema: {
|
|
402
|
+
type: 'object',
|
|
403
|
+
properties: {
|
|
404
|
+
servicePath: {
|
|
405
|
+
type: 'string',
|
|
406
|
+
description: 'Full service path, e.g. /sap/opu/odata/sap/ZSALESORDER_SD_SRV',
|
|
407
|
+
},
|
|
408
|
+
entity: {
|
|
409
|
+
type: 'string',
|
|
410
|
+
description: 'Optional entity set name to append, e.g. SalesOrder',
|
|
411
|
+
},
|
|
412
|
+
method: {
|
|
413
|
+
type: 'string',
|
|
414
|
+
enum: ['GET', 'HEAD'],
|
|
415
|
+
description: 'HTTP method to use (default: GET)',
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
required: ['servicePath'],
|
|
419
|
+
},
|
|
420
|
+
handler: async (args, ctx) => {
|
|
421
|
+
const result = await ctx.adt.odataTest(args.servicePath, args.entity, args.method ?? 'GET');
|
|
422
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
// -----------------------------------------------------------------------
|
|
426
|
+
// 18. sap_badi_list
|
|
427
|
+
// -----------------------------------------------------------------------
|
|
428
|
+
registerTool({
|
|
429
|
+
name: 'sap_badi_list',
|
|
430
|
+
description: 'Search for BAdI definitions and enhancement spots by name pattern (supports * wildcard), with optional enhancement-spot drill-down.',
|
|
431
|
+
isMutating: false,
|
|
432
|
+
input_schema: {
|
|
433
|
+
type: 'object',
|
|
434
|
+
properties: {
|
|
435
|
+
query: {
|
|
436
|
+
type: 'string',
|
|
437
|
+
description: 'BAdI name pattern with optional * wildcard, e.g. MD_PURCH* or BADI_SD*',
|
|
438
|
+
},
|
|
439
|
+
enhancementSpot: {
|
|
440
|
+
type: 'string',
|
|
441
|
+
description: 'Optional enhancement spot name to drill into for its BAdI definitions',
|
|
442
|
+
},
|
|
443
|
+
maxResults: {
|
|
444
|
+
type: 'number',
|
|
445
|
+
description: 'Maximum search results (default 50)',
|
|
446
|
+
},
|
|
447
|
+
},
|
|
448
|
+
required: ['query'],
|
|
449
|
+
},
|
|
450
|
+
handler: async (args, ctx) => {
|
|
451
|
+
const result = await ctx.adt.badiList(args.query, args.enhancementSpot, args.maxResults ?? 50);
|
|
452
|
+
return { content: JSON.stringify(result, null, 2) };
|
|
453
|
+
},
|
|
454
|
+
});
|