@sap/joule-studio-dev-cli 0.1.20-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +38 -0
  2. package/README.md +53 -0
  3. package/dist/bin/commands/a2a.js +12 -0
  4. package/dist/bin/commands/a2a.js.map +1 -0
  5. package/dist/bin/commands/asset.js +20 -0
  6. package/dist/bin/commands/asset.js.map +1 -0
  7. package/dist/bin/commands/auth.js +16 -0
  8. package/dist/bin/commands/auth.js.map +1 -0
  9. package/dist/bin/commands/init.js +20 -0
  10. package/dist/bin/commands/init.js.map +1 -0
  11. package/dist/bin/commands/mcp.js +42 -0
  12. package/dist/bin/commands/mcp.js.map +1 -0
  13. package/dist/bin/commands/pro-code.js +12 -0
  14. package/dist/bin/commands/pro-code.js.map +1 -0
  15. package/dist/bin/commands/skills.js +27 -0
  16. package/dist/bin/commands/skills.js.map +1 -0
  17. package/dist/bin/commands/solution.js +52 -0
  18. package/dist/bin/commands/solution.js.map +1 -0
  19. package/dist/bin/help.js +42 -0
  20. package/dist/bin/help.js.map +1 -0
  21. package/dist/bin/jl.js +59 -0
  22. package/dist/bin/jl.js.map +1 -0
  23. package/dist/bin/login.js +60 -0
  24. package/dist/bin/login.js.map +1 -0
  25. package/dist/bin/logout.js +21 -0
  26. package/dist/bin/logout.js.map +1 -0
  27. package/dist/lib/a2a/message.js +74 -0
  28. package/dist/lib/a2a/message.js.map +1 -0
  29. package/dist/lib/asset/create.js +38 -0
  30. package/dist/lib/asset/create.js.map +1 -0
  31. package/dist/lib/asset/delete.js +57 -0
  32. package/dist/lib/asset/delete.js.map +1 -0
  33. package/dist/lib/asset/discover.js +46 -0
  34. package/dist/lib/asset/discover.js.map +1 -0
  35. package/dist/lib/auth-crypto.js +146 -0
  36. package/dist/lib/auth-crypto.js.map +1 -0
  37. package/dist/lib/auth.js +488 -0
  38. package/dist/lib/auth.js.map +1 -0
  39. package/dist/lib/context.js +35 -0
  40. package/dist/lib/context.js.map +1 -0
  41. package/dist/lib/errors.js +47 -0
  42. package/dist/lib/errors.js.map +1 -0
  43. package/dist/lib/fs-utils.js +34 -0
  44. package/dist/lib/fs-utils.js.map +1 -0
  45. package/dist/lib/init/agents.js +55 -0
  46. package/dist/lib/init/agents.js.map +1 -0
  47. package/dist/lib/init/shared.js +172 -0
  48. package/dist/lib/init/shared.js.map +1 -0
  49. package/dist/lib/mcp/call.js +158 -0
  50. package/dist/lib/mcp/call.js.map +1 -0
  51. package/dist/lib/mcp/client.js +100 -0
  52. package/dist/lib/mcp/client.js.map +1 -0
  53. package/dist/lib/mcp/list.js +20 -0
  54. package/dist/lib/mcp/list.js.map +1 -0
  55. package/dist/lib/mcp/start.js +120 -0
  56. package/dist/lib/mcp/start.js.map +1 -0
  57. package/dist/lib/mcp/tools.js +162 -0
  58. package/dist/lib/mcp/tools.js.map +1 -0
  59. package/dist/lib/plugin.js +77 -0
  60. package/dist/lib/plugin.js.map +1 -0
  61. package/dist/lib/plugins/agent/index.js +32 -0
  62. package/dist/lib/plugins/agent/index.js.map +1 -0
  63. package/dist/lib/plugins/agent/templates/asset.yaml.hbs +31 -0
  64. package/dist/lib/plugins/agent-extension/index.js +32 -0
  65. package/dist/lib/plugins/agent-extension/index.js.map +1 -0
  66. package/dist/lib/plugins/agent-extension/templates/asset.yaml.hbs +15 -0
  67. package/dist/lib/plugins/base-ui/index.js +32 -0
  68. package/dist/lib/plugins/base-ui/index.js.map +1 -0
  69. package/dist/lib/plugins/base-ui/templates/asset.yaml.hbs +8 -0
  70. package/dist/lib/plugins/cap-app/index.js +32 -0
  71. package/dist/lib/plugins/cap-app/index.js.map +1 -0
  72. package/dist/lib/plugins/cap-app/templates/asset.yaml.hbs +37 -0
  73. package/dist/lib/plugins/data-product/index.js +32 -0
  74. package/dist/lib/plugins/data-product/index.js.map +1 -0
  75. package/dist/lib/plugins/data-product/templates/asset.yaml.hbs +9 -0
  76. package/dist/lib/plugins/domain-model-extension/index.js +37 -0
  77. package/dist/lib/plugins/domain-model-extension/index.js.map +1 -0
  78. package/dist/lib/plugins/domain-model-extension/templates/asset.yaml.hbs +15 -0
  79. package/dist/lib/plugins/mcp-server/index.js +36 -0
  80. package/dist/lib/plugins/mcp-server/index.js.map +1 -0
  81. package/dist/lib/plugins/mcp-server/templates/asset.yaml.hbs +9 -0
  82. package/dist/lib/plugins/n8n-workflow/index.js +52 -0
  83. package/dist/lib/plugins/n8n-workflow/index.js.map +1 -0
  84. package/dist/lib/plugins/n8n-workflow/templates/asset.yaml.hbs +18 -0
  85. package/dist/lib/plugins/n8n-workflow/validation/asset-validator.js +62 -0
  86. package/dist/lib/plugins/n8n-workflow/validation/asset-validator.js.map +1 -0
  87. package/dist/lib/plugins/n8n-workflow/validation/yaml-validator.js +51 -0
  88. package/dist/lib/plugins/n8n-workflow/validation/yaml-validator.js.map +1 -0
  89. package/dist/lib/plugins/vercel-app/index.js +32 -0
  90. package/dist/lib/plugins/vercel-app/index.js.map +1 -0
  91. package/dist/lib/plugins/vercel-app/templates/asset.yaml.hbs +12 -0
  92. package/dist/lib/rule.js +2 -0
  93. package/dist/lib/rule.js.map +1 -0
  94. package/dist/lib/schemas/solution-schema.json +178 -0
  95. package/dist/lib/solution/build.js +186 -0
  96. package/dist/lib/solution/build.js.map +1 -0
  97. package/dist/lib/solution/create.js +42 -0
  98. package/dist/lib/solution/create.js.map +1 -0
  99. package/dist/lib/solution/deploy.js +66 -0
  100. package/dist/lib/solution/deploy.js.map +1 -0
  101. package/dist/lib/solution/list.js +21 -0
  102. package/dist/lib/solution/list.js.map +1 -0
  103. package/dist/lib/solution/logs.js +130 -0
  104. package/dist/lib/solution/logs.js.map +1 -0
  105. package/dist/lib/solution/status.js +161 -0
  106. package/dist/lib/solution/status.js.map +1 -0
  107. package/dist/lib/solution/templates/solution.yaml.hbs +9 -0
  108. package/dist/lib/solution/util/build-file.js +4 -0
  109. package/dist/lib/solution/util/build-file.js.map +1 -0
  110. package/dist/lib/template.js +74 -0
  111. package/dist/lib/template.js.map +1 -0
  112. package/dist/lib/term.js +16 -0
  113. package/dist/lib/term.js.map +1 -0
  114. package/dist/lib/validate.js +287 -0
  115. package/dist/lib/validate.js.map +1 -0
  116. package/dist/lib/yaml.js +33 -0
  117. package/dist/lib/yaml.js.map +1 -0
  118. package/dist/package.json +77 -0
  119. package/package.json +77 -0
@@ -0,0 +1,120 @@
1
+ import readline from 'node:readline';
2
+ import { getAuthHeaders, isSessionExpired, loadCredentials } from '../auth.js';
3
+ import { CliError } from '../errors.js';
4
+ import term from '../term.js';
5
+ import { fetchMcpServers, mcpInit, mcpListTools, mcpRequest } from './client.js';
6
+ const SEP = '__';
7
+ let toolRegistry = new Map();
8
+ let cachedTools = [];
9
+ export async function mcpStart(_args) {
10
+ const store = await fetchMcpServers();
11
+ for (const [serverName, cfg] of Object.entries(store)) {
12
+ if (!loadCredentials(cfg.backend)) {
13
+ process.stderr.write(`${term.yellow('!')} ${term.bold(serverName)}: not logged in — run: jl login ${cfg.backend}\n`);
14
+ }
15
+ else if (isSessionExpired(cfg.backend)) {
16
+ process.stderr.write(`${term.yellow('!')} ${term.bold(serverName)}: session expired — run: jl login ${cfg.backend}\n`);
17
+ }
18
+ }
19
+ await refreshTools(store);
20
+ if (cachedTools.length === 0) {
21
+ throw new CliError('MCP_NO_TOOLS', 'No tools available from any synced MCP server.');
22
+ }
23
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
24
+ rl.on('line', async (line) => {
25
+ const trimmed = line.trim();
26
+ if (!trimmed) {
27
+ return;
28
+ }
29
+ let parsed;
30
+ try {
31
+ parsed = JSON.parse(trimmed);
32
+ }
33
+ catch {
34
+ send({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' } });
35
+ return;
36
+ }
37
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
38
+ send({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' } });
39
+ return;
40
+ }
41
+ const obj = parsed;
42
+ if (typeof obj.method !== 'string') {
43
+ send({ jsonrpc: '2.0', id: obj.id ?? null, error: { code: -32600, message: 'Invalid Request' } });
44
+ return;
45
+ }
46
+ const rpc = obj;
47
+ const { method, id, params } = rpc;
48
+ if (!Object.prototype.hasOwnProperty.call(rpc, 'id')) {
49
+ return;
50
+ }
51
+ try {
52
+ if (method === 'initialize') {
53
+ send({
54
+ jsonrpc: '2.0',
55
+ id,
56
+ result: {
57
+ protocolVersion: '2024-11-05',
58
+ capabilities: { tools: {} },
59
+ serverInfo: { name: 'joule-mcp-proxy', version: '1.0' },
60
+ },
61
+ });
62
+ }
63
+ else if (method === 'tools/list') {
64
+ send({ jsonrpc: '2.0', id, result: { tools: cachedTools } });
65
+ }
66
+ else if (method === 'tools/call') {
67
+ const result = await routeToolCall(params);
68
+ send({ jsonrpc: '2.0', id, result });
69
+ }
70
+ else {
71
+ send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Method not found: ${method}` } });
72
+ }
73
+ }
74
+ catch (err) {
75
+ send({ jsonrpc: '2.0', id, error: { code: -32603, message: String(err.message ?? err) } });
76
+ }
77
+ });
78
+ }
79
+ async function refreshTools(store) {
80
+ toolRegistry = new Map();
81
+ cachedTools = [];
82
+ for (const [serverName, cfg] of Object.entries(store)) {
83
+ try {
84
+ const headers = getAuthHeaders(cfg.backend);
85
+ await mcpInit(cfg.url, headers);
86
+ const tools = await mcpListTools(cfg.url, headers);
87
+ const displayName = serverName.replace(/-server$/, '');
88
+ for (const tool of tools) {
89
+ const proxyName = `${displayName}${SEP}${tool.name}`;
90
+ toolRegistry.set(proxyName, { originalName: tool.name, cfg });
91
+ cachedTools.push({
92
+ ...tool,
93
+ name: proxyName,
94
+ description: tool.description ? `[${displayName}] ${tool.description}` : `[${displayName}]`,
95
+ });
96
+ }
97
+ }
98
+ catch (err) {
99
+ process.stderr.write(` ${term.yellow('!')} ${term.bold(serverName)}: ${err.message ?? err}\n`);
100
+ }
101
+ }
102
+ }
103
+ async function routeToolCall(params) {
104
+ if (!params) {
105
+ throw new Error('Invalid params');
106
+ }
107
+ const { name, arguments: args } = params;
108
+ const entry = toolRegistry.get(name);
109
+ if (!entry) {
110
+ throw new Error(`Tool not found: ${name}`);
111
+ }
112
+ const { originalName, cfg } = entry;
113
+ const headers = getAuthHeaders(cfg.backend);
114
+ await mcpInit(cfg.url, headers);
115
+ return mcpRequest(cfg.url, headers, 'tools/call', Date.now(), { name: originalName, arguments: args });
116
+ }
117
+ function send(msg) {
118
+ process.stdout.write(`${JSON.stringify(msg)}\n`);
119
+ }
120
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../lib/mcp/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ import { getAuthHeaders } from '../auth.js';
2
+ import { fetchMcpServers, mcpInit, mcpListTools, pickFromList } from './client.js';
3
+ import term from '../term.js';
4
+ function collapseDescription(text) {
5
+ return text
6
+ .split('\n')
7
+ .map(s => s.trim())
8
+ .join(' ')
9
+ .trim();
10
+ }
11
+ function renderParamType(prop) {
12
+ if (Array.isArray(prop.anyOf)) {
13
+ const nonNull = prop.anyOf.filter(s => s.type !== 'null').map(s => s.type);
14
+ return nonNull.length === 1 ? `${nonNull[0] ?? 'any'}?` : 'any?';
15
+ }
16
+ if (prop.type === 'array') {
17
+ const items = prop.items;
18
+ const itemType = items?.type ?? (items?.enum ? 'enum' : 'any');
19
+ return `${itemType}[]`;
20
+ }
21
+ return prop.type ?? 'any';
22
+ }
23
+ function renderParamDescription(prop) {
24
+ const parts = [];
25
+ if (prop.description)
26
+ parts.push(collapseDescription(prop.description));
27
+ const anyOfEnum = Array.isArray(prop.anyOf)
28
+ ? prop.anyOf.find(s => s.enum)?.enum
29
+ : null;
30
+ const enumVals = prop.enum ??
31
+ prop.items?.enum ??
32
+ anyOfEnum ??
33
+ null;
34
+ if (enumVals?.length)
35
+ parts.push(`[${enumVals.join('|')}]`);
36
+ if ('default' in prop && prop.default !== null)
37
+ parts.push(`(default: ${prop.default})`);
38
+ return parts.join(' ');
39
+ }
40
+ function wrapText(text, firstLineWidth, contIndent) {
41
+ if (text.length <= firstLineWidth)
42
+ return text;
43
+ const contWidth = Math.max(20, (process.stdout.columns ?? 120) - contIndent);
44
+ const words = text.split(' ');
45
+ const lines = [];
46
+ let current = '';
47
+ let isFirst = true;
48
+ for (const word of words) {
49
+ const maxWidth = isFirst ? firstLineWidth : contWidth;
50
+ if (current.length === 0) {
51
+ current = word;
52
+ }
53
+ else if (current.length + 1 + word.length <= maxWidth) {
54
+ current += ' ' + word;
55
+ }
56
+ else {
57
+ lines.push(current);
58
+ current = word;
59
+ isFirst = false;
60
+ }
61
+ }
62
+ if (current)
63
+ lines.push(current);
64
+ return lines.join('\n' + ' '.repeat(contIndent));
65
+ }
66
+ function renderObjectExample(prop) {
67
+ const examples = prop.examples;
68
+ const isObject = prop.type === 'object' ||
69
+ (Array.isArray(prop.anyOf) && prop.anyOf.some(s => s.type === 'object'));
70
+ return isObject && Array.isArray(examples) && examples.length > 0 ? 'e.g. ' + JSON.stringify(examples[0]) : '';
71
+ }
72
+ function printParamRow(name, prop, nameWidth) {
73
+ const type = renderParamType(prop).padEnd(10);
74
+ const description = renderParamDescription(prop);
75
+ const descStart = 6 + nameWidth + 2 + 10 + 2;
76
+ const firstWidth = Math.max(20, (process.stdout.columns ?? 120) - descStart);
77
+ const wrappedDesc = wrapText(description, firstWidth, descStart);
78
+ console.log(` ${term.dim(name.padEnd(nameWidth) + ' ' + type + ' ' + wrappedDesc)}`);
79
+ const subProps = prop.properties;
80
+ if (subProps && Object.keys(subProps).length > 0) {
81
+ const subRequired = prop.required ?? [];
82
+ const subWidth = Math.max(...Object.keys(subProps).map(n => n.length));
83
+ for (const [subName, subProp] of Object.entries(subProps)) {
84
+ const req = subRequired.includes(subName) ? 'required' : 'optional';
85
+ const subType = renderParamType(subProp).padEnd(10);
86
+ const subDesc = renderParamDescription(subProp);
87
+ const subDescStart = 8 + 2 + subWidth + 2 + 10 + 2 + req.length + 2;
88
+ const wrappedSubDesc = wrapText(subDesc, Math.max(20, (process.stdout.columns ?? 120) - subDescStart), subDescStart);
89
+ console.log(` ${term.dim('↳ ' + subName.padEnd(subWidth) + ' ' + subType + ' ' + req + ' ' + wrappedSubDesc)}`);
90
+ }
91
+ }
92
+ else {
93
+ const example = renderObjectExample(prop);
94
+ if (example) {
95
+ const indent = ' '.repeat(descStart);
96
+ console.log(indent + term.dim(example));
97
+ }
98
+ }
99
+ }
100
+ function printParams(properties, required, nameWidth) {
101
+ const reqNames = required.filter(n => n in properties);
102
+ const optNames = Object.keys(properties).filter(n => !required.includes(n));
103
+ if (reqNames.length > 0) {
104
+ console.log(` ${term.dim('Required Parameters:')}`);
105
+ for (const name of reqNames) {
106
+ printParamRow(name, properties[name], nameWidth);
107
+ }
108
+ }
109
+ if (optNames.length > 0) {
110
+ console.log(` ${term.dim('Optional Parameters:')}`);
111
+ for (const name of optNames) {
112
+ printParamRow(name, properties[name], nameWidth);
113
+ }
114
+ }
115
+ }
116
+ export async function mcpTools(args, options = {}) {
117
+ const store = await fetchMcpServers();
118
+ let name, cfg;
119
+ if (args[0]) {
120
+ name = args[0];
121
+ cfg = store[name];
122
+ if (!cfg) {
123
+ throw `Unknown MCP server '${name}'. Available: ${Object.keys(store).join(', ')}`;
124
+ }
125
+ }
126
+ else {
127
+ if (!process.stdin.isTTY) {
128
+ throw 'Usage: joule mcp tools <server-name>';
129
+ }
130
+ const entries = Object.entries(store);
131
+ [name, cfg] = await pickFromList(entries, 'server', ([n]) => term.bold(n));
132
+ console.log();
133
+ }
134
+ const headers = getAuthHeaders(cfg.backend);
135
+ await mcpInit(cfg.url, headers);
136
+ const tools = await mcpListTools(cfg.url, headers);
137
+ if (options.json) {
138
+ console.log(JSON.stringify(tools, null, 2));
139
+ return;
140
+ }
141
+ if (tools.length === 0) {
142
+ console.log(term.dim('No tools available.'));
143
+ return;
144
+ }
145
+ console.log(`\n${term.bold(name)} ${term.dim(`${tools.length} tool${tools.length !== 1 ? 's' : ''}`)}\n`);
146
+ for (const tool of tools) {
147
+ const title = tool.title && tool.title !== tool.name ? term.dim(` (${tool.title})`) : '';
148
+ console.log(` ${term.bold(tool.name)}${title}`);
149
+ if (tool.description) {
150
+ console.log(` ${collapseDescription(tool.description)}`);
151
+ }
152
+ const schema = tool.inputSchema;
153
+ const properties = schema?.properties;
154
+ if (properties && Object.keys(properties).length > 0) {
155
+ const required = schema?.required ?? [];
156
+ const nameWidth = Math.max(...Object.keys(properties).map(n => n.length));
157
+ printParams(properties, required, nameWidth);
158
+ }
159
+ console.log();
160
+ }
161
+ }
162
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../lib/mcp/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import yaml from './yaml.js';
4
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
+ export const NAME_PATTERN = /^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$/;
6
+ export default class Plugin {
7
+ assetType() {
8
+ return '';
9
+ }
10
+ sourceRoot() {
11
+ return '';
12
+ }
13
+ provides() {
14
+ return {};
15
+ }
16
+ templateDir() {
17
+ return path.join(__dirname, 'templates');
18
+ }
19
+ static help() {
20
+ return '';
21
+ }
22
+ options() {
23
+ return [];
24
+ }
25
+ requires() {
26
+ return [];
27
+ }
28
+ async canRun() {
29
+ return true;
30
+ }
31
+ async run(_name, _options, _assetsDir) { }
32
+ async delete(_name, _solutionDir) { }
33
+ async checkAssetYaml(assetYaml, assetDir) {
34
+ const issues = [];
35
+ const metadata = assetYaml.metadata;
36
+ if (assetYaml.apiVersion !== 'asset.sap/v1') {
37
+ issues.push(`apiVersion must be 'asset.sap/v1' (got '${assetYaml.apiVersion}')`);
38
+ }
39
+ if (assetYaml.kind !== 'Asset') {
40
+ issues.push(`kind must be 'Asset' (got '${assetYaml.kind}')`);
41
+ }
42
+ if (!metadata?.name) {
43
+ issues.push('metadata.name is missing');
44
+ }
45
+ else if (!NAME_PATTERN.test(metadata.name)) {
46
+ issues.push(`metadata.name '${metadata.name}' is not DNS-compatible`);
47
+ }
48
+ if (!assetYaml.type) {
49
+ issues.push('type is missing');
50
+ }
51
+ const extra = await this.checkAssetYamlExtra(assetYaml, assetDir);
52
+ issues.push(...extra);
53
+ return issues;
54
+ }
55
+ /** Override in subclasses to add plugin-specific asset.yaml validation. */
56
+ async checkAssetYamlExtra(_assetYaml, _assetDir) {
57
+ return [];
58
+ }
59
+ async checkAsset(_assetYaml, _assetDir) {
60
+ return [];
61
+ }
62
+ async combine(solutionDir, name) {
63
+ const solutionYamlPath = path.join(solutionDir, 'solution.yaml');
64
+ yaml.updateYAML(solutionYamlPath, doc => {
65
+ if (!Array.isArray(doc.assets)) {
66
+ doc.assets = [];
67
+ }
68
+ const ref = `./assets/${name}/asset.yaml`;
69
+ const assets = doc.assets;
70
+ if (!assets.some(a => a && a.ref === ref)) {
71
+ assets.push({ ref });
72
+ }
73
+ });
74
+ }
75
+ async finalize() { }
76
+ }
77
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../lib/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import Plugin from '../../plugin.js';
4
+ import { render } from '../../template.js';
5
+ import fsUtils from '../../fs-utils.js';
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ class AgentPlugin extends Plugin {
8
+ assetType() {
9
+ return 'agent';
10
+ }
11
+ sourceRoot() {
12
+ return 'agent';
13
+ }
14
+ provides() {
15
+ return {};
16
+ }
17
+ templateDir() {
18
+ return path.join(__dirname, 'templates');
19
+ }
20
+ static help() {
21
+ return 'Agent asset — AI agent with container and health probe configuration';
22
+ }
23
+ async run(name, _options, assetsDir) {
24
+ const assetDir = path.join(assetsDir, name);
25
+ fsUtils.mkdirp(assetDir);
26
+ const templatePath = path.join(this.templateDir(), 'asset.yaml.hbs');
27
+ const content = render(templatePath, { name });
28
+ fsUtils.writeFile(path.join(assetDir, 'asset.yaml'), content);
29
+ }
30
+ }
31
+ export default AgentPlugin;
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/plugins/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,OAAO,MAAM,mBAAmB,CAAA;AAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D,MAAM,WAAY,SAAQ,MAAM;IAC5B,SAAS;QACL,OAAO,OAAO,CAAA;IAClB,CAAC;IACD,UAAU;QACN,OAAO,OAAO,CAAA;IAClB,CAAC;IACD,QAAQ;QACJ,OAAO,EAAE,CAAA;IACb,CAAC;IACD,WAAW;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,CAAC,IAAI;QACP,OAAO,sEAAsE,CAAA;IACjF,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,QAAiC,EAAE,SAAiB;QACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAExB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAA;QACpE,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC9C,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAA;IACjE,CAAC;CACJ;AAED,eAAe,WAAW,CAAA"}
@@ -0,0 +1,31 @@
1
+ apiVersion: asset.sap/v1
2
+ kind: Asset
3
+
4
+ metadata:
5
+ name: {{name}}
6
+ version: 1.0.0
7
+
8
+ type: agent
9
+
10
+ container:
11
+ buildPath: .
12
+ port: 5000
13
+
14
+ probes:
15
+ startup:
16
+ path: /.well-known/agent.json
17
+ periodSeconds: 5
18
+ timeoutSeconds: 3
19
+ failureThreshold: 18
20
+ liveness:
21
+ path: /.well-known/agent.json
22
+ initialDelaySeconds: 15
23
+ periodSeconds: 10
24
+ timeoutSeconds: 5
25
+ failureThreshold: 3
26
+ readiness:
27
+ path: /.well-known/agent.json
28
+ initialDelaySeconds: 5
29
+ periodSeconds: 5
30
+ timeoutSeconds: 3
31
+ failureThreshold: 3
@@ -0,0 +1,32 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import Plugin from '../../plugin.js';
4
+ import { render } from '../../template.js';
5
+ import fsUtils from '../../fs-utils.js';
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ class AgentExtensionPlugin extends Plugin {
8
+ assetType() {
9
+ return 'agent-extension';
10
+ }
11
+ sourceRoot() {
12
+ return 'agent-extensions';
13
+ }
14
+ provides() {
15
+ return { extensions: [] };
16
+ }
17
+ templateDir() {
18
+ return path.join(__dirname, 'templates');
19
+ }
20
+ static help() {
21
+ return 'Agent extension asset — extends a base agent with additional capabilities';
22
+ }
23
+ async run(name, _options, assetsDir) {
24
+ const assetDir = path.join(assetsDir, name);
25
+ fsUtils.mkdirp(assetDir);
26
+ const templatePath = path.join(this.templateDir(), 'asset.yaml.hbs');
27
+ const content = render(templatePath, { name });
28
+ fsUtils.writeFile(path.join(assetDir, 'asset.yaml'), content);
29
+ }
30
+ }
31
+ export default AgentExtensionPlugin;
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/plugins/agent-extension/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,OAAO,MAAM,mBAAmB,CAAA;AAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D,MAAM,oBAAqB,SAAQ,MAAM;IACrC,SAAS;QACL,OAAO,iBAAiB,CAAA;IAC5B,CAAC;IACD,UAAU;QACN,OAAO,kBAAkB,CAAA;IAC7B,CAAC;IACD,QAAQ;QACJ,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAA;IAC7B,CAAC;IACD,WAAW;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,CAAC,IAAI;QACP,OAAO,2EAA2E,CAAA;IACtF,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,QAAiC,EAAE,SAAiB;QACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAExB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAA;QACpE,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC9C,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAA;IACjE,CAAC;CACJ;AAED,eAAe,oBAAoB,CAAA"}
@@ -0,0 +1,15 @@
1
+ apiVersion: asset.sap/v1
2
+ kind: Asset
3
+
4
+ metadata:
5
+ name: {{name}}
6
+ version: 1.0.0
7
+
8
+ type: agent-extension
9
+
10
+ sourceRoot: agent-extensions
11
+
12
+ provides:
13
+ extensions:
14
+ - name: my-extension
15
+ descriptorFile: extension.yaml
@@ -0,0 +1,32 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import Plugin from '../../plugin.js';
4
+ import { render } from '../../template.js';
5
+ import fsUtils from '../../fs-utils.js';
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ class BaseUiPlugin extends Plugin {
8
+ assetType() {
9
+ return 'base-ui';
10
+ }
11
+ sourceRoot() {
12
+ return '.';
13
+ }
14
+ provides() {
15
+ return {};
16
+ }
17
+ templateDir() {
18
+ return path.join(__dirname, 'templates');
19
+ }
20
+ static help() {
21
+ return 'Base UI asset — AppRouter-based frontend web application (Next.js, React, etc.)';
22
+ }
23
+ async run(name, _options, assetsDir) {
24
+ const assetDir = path.join(assetsDir, name);
25
+ fsUtils.mkdirp(assetDir);
26
+ const templatePath = path.join(this.templateDir(), 'asset.yaml.hbs');
27
+ const content = render(templatePath, { name });
28
+ fsUtils.writeFile(path.join(assetDir, 'asset.yaml'), content);
29
+ }
30
+ }
31
+ export default BaseUiPlugin;
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/plugins/base-ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,OAAO,MAAM,mBAAmB,CAAA;AAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D,MAAM,YAAa,SAAQ,MAAM;IAC7B,SAAS;QACL,OAAO,SAAS,CAAA;IACpB,CAAC;IACD,UAAU;QACN,OAAO,GAAG,CAAA;IACd,CAAC;IACD,QAAQ;QACJ,OAAO,EAAE,CAAA;IACb,CAAC;IACD,WAAW;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,CAAC,IAAI;QACP,OAAO,iFAAiF,CAAA;IAC5F,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,QAAiC,EAAE,SAAiB;QACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAExB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAA;QACpE,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC9C,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAA;IACjE,CAAC;CACJ;AAED,eAAe,YAAY,CAAA"}
@@ -0,0 +1,8 @@
1
+ apiVersion: asset.sap/v1
2
+ kind: Asset
3
+
4
+ metadata:
5
+ name: {{name}}
6
+ version: 1.0.0
7
+
8
+ type: base-ui
@@ -0,0 +1,32 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import Plugin from '../../plugin.js';
4
+ import { render } from '../../template.js';
5
+ import fsUtils from '../../fs-utils.js';
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ class CapAppPlugin extends Plugin {
8
+ assetType() {
9
+ return 'cap-app';
10
+ }
11
+ sourceRoot() {
12
+ return '.';
13
+ }
14
+ provides() {
15
+ return {};
16
+ }
17
+ templateDir() {
18
+ return path.join(__dirname, 'templates');
19
+ }
20
+ static help() {
21
+ return 'CAP application asset — Node.js CAP service with container and health probe configuration';
22
+ }
23
+ async run(name, _options, assetsDir) {
24
+ const assetDir = path.join(assetsDir, name);
25
+ fsUtils.mkdirp(assetDir);
26
+ const templatePath = path.join(this.templateDir(), 'asset.yaml.hbs');
27
+ const content = render(templatePath, { name });
28
+ fsUtils.writeFile(path.join(assetDir, 'asset.yaml'), content);
29
+ }
30
+ }
31
+ export default CapAppPlugin;
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/plugins/cap-app/index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,OAAO,MAAM,mBAAmB,CAAA;AAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D,MAAM,YAAa,SAAQ,MAAM;IAC7B,SAAS;QACL,OAAO,SAAS,CAAA;IACpB,CAAC;IACD,UAAU;QACN,OAAO,GAAG,CAAA;IACd,CAAC;IACD,QAAQ;QACJ,OAAO,EAAE,CAAA;IACb,CAAC;IACD,WAAW;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,CAAC,IAAI;QACP,OAAO,2FAA2F,CAAA;IACtG,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,QAAiC,EAAE,SAAiB;QACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAExB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAA;QACpE,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QAC9C,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAA;IACjE,CAAC;CACJ;AAED,eAAe,YAAY,CAAA"}
@@ -0,0 +1,37 @@
1
+ apiVersion: asset.sap/v1
2
+ kind: Asset
3
+
4
+ metadata:
5
+ name: {{name}}
6
+ version: 1.0.0
7
+
8
+ type: cap-app
9
+
10
+ container:
11
+ buildPath: gen/srv
12
+ port: 4004
13
+ env:
14
+ PORT: "4004"
15
+
16
+ provides:
17
+ protocols:
18
+ - odata-v4
19
+
20
+ probes:
21
+ startup:
22
+ path: /health
23
+ periodSeconds: 5
24
+ timeoutSeconds: 3
25
+ failureThreshold: 18
26
+ liveness:
27
+ path: /health
28
+ initialDelaySeconds: 15
29
+ periodSeconds: 10
30
+ timeoutSeconds: 5
31
+ failureThreshold: 3
32
+ readiness:
33
+ path: /health
34
+ initialDelaySeconds: 5
35
+ periodSeconds: 5
36
+ timeoutSeconds: 3
37
+ failureThreshold: 3