@bluefly/openstandardagents 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.version.json +3 -3
- package/CHANGELOG.md +43 -12
- package/README.md +31 -26
- package/bin/postinstall +0 -0
- package/dist/.version.json +3 -3
- package/dist/adapters/a2a/a2a-protocol.js +4 -2
- package/dist/adapters/a2a/a2a-tool.js +4 -2
- package/dist/adapters/a2a/mcp-integration.d.ts +2 -1
- package/dist/adapters/a2a/mcp-integration.js +6 -3
- package/dist/adapters/browser/browser-exporter.d.ts +26 -0
- package/dist/adapters/browser/browser-exporter.js +73 -0
- package/dist/adapters/browser/browser-runner.d.ts +23 -0
- package/dist/adapters/browser/browser-runner.js +46 -0
- package/dist/adapters/browser/index.d.ts +9 -0
- package/dist/adapters/browser/index.js +9 -0
- package/dist/adapters/docker/index.d.ts +2 -0
- package/dist/adapters/docker/index.js +2 -0
- package/dist/adapters/docker/openclaw-bridge.d.ts +57 -0
- package/dist/adapters/docker/openclaw-bridge.js +173 -0
- package/dist/adapters/drupal/index.d.ts +1 -0
- package/dist/adapters/drupal/index.js +2 -0
- package/dist/adapters/drupal/twig-renderer.d.ts +23 -0
- package/dist/adapters/drupal/twig-renderer.js +99 -0
- package/dist/adapters/gitlab/agent-generator.js +2 -1
- package/dist/api/index.js +2 -1
- package/dist/api/routes/mcp.router.js +3 -1
- package/dist/api/routes/wizard.router.js +3 -1
- package/dist/cli/commands/agent/discover-type.command.js +1 -1
- package/dist/cli/commands/agent-card.command.js +37 -10
- package/dist/cli/commands/agents-sync.command.d.ts +2 -2
- package/dist/cli/commands/agents-sync.command.js +27 -17
- package/dist/cli/commands/catalog/config.js +1 -1
- package/dist/cli/commands/catalog/validate.command.js +2 -2
- package/dist/cli/commands/config.command.js +2 -2
- package/dist/cli/commands/daemon.command.js +32 -8
- package/dist/cli/commands/discover.d.ts +1 -1
- package/dist/cli/commands/discover.js +16 -8
- package/dist/cli/commands/economics.command.d.ts +9 -0
- package/dist/cli/commands/economics.command.js +113 -0
- package/dist/cli/commands/export.command.js +6 -3
- package/dist/cli/commands/mcp.command.js +3 -1
- package/dist/cli/commands/memory.command.d.ts +18 -0
- package/dist/cli/commands/memory.command.js +168 -0
- package/dist/cli/commands/publish.command.js +7 -4
- package/dist/cli/commands/serve-builder-routes.js +1 -1
- package/dist/cli/commands/usie-skills.command.d.ts +24 -0
- package/dist/cli/commands/usie-skills.command.js +297 -0
- package/dist/cli/commands/validate.command.js +8 -1
- package/dist/cli/commands/verify.d.ts +3 -3
- package/dist/cli/commands/verify.js +12 -6
- package/dist/cli/commands/workspace.command.d.ts +1 -0
- package/dist/cli/commands/workspace.command.js +28 -4
- package/dist/cli/index.js +12 -0
- package/dist/cli/workspace-validate.d.ts +23 -0
- package/dist/cli/workspace-validate.js +117 -0
- package/dist/data/platform-matrix.js +1 -4
- package/dist/generated/types.d.ts +97 -97
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mcp-server/index.js +658 -982
- package/dist/mesh/discovery-gkg.d.ts +26 -0
- package/dist/mesh/discovery-gkg.js +92 -0
- package/dist/messenger/Handler/AgentBatchHandler.js +3 -2
- package/dist/messenger/Handler/AgentExecutionHandler.js +6 -1
- package/dist/package.json +20 -4
- package/dist/sdks/shared/types.d.ts +1 -1
- package/dist/services/agent-card-generator.js +6 -2
- package/dist/services/daemon/audit-log.service.js +3 -1
- package/dist/services/daemon/execution.service.js +8 -4
- package/dist/services/daemon/fs-watcher.service.js +6 -7
- package/dist/services/daemon/pairing.service.js +2 -1
- package/dist/services/daemon/skill-aggregator.service.js +105 -21
- package/dist/services/daemon/sse-endpoints.js +1 -1
- package/dist/services/daemon/ws-server.js +10 -3
- package/dist/services/governance/cedar-provider.js +12 -8
- package/dist/services/governance/cedar-validator.service.js +1 -1
- package/dist/services/mcp/bridge.service.js +40 -9
- package/dist/services/openapi-extensions-validation.d.ts +20 -0
- package/dist/services/openapi-extensions-validation.js +193 -0
- package/dist/services/release-automation/merge-request.service.d.ts +4 -4
- package/dist/services/release-automation/release-buttons.js +3 -3
- package/dist/services/release-automation/schemas/release.schema.d.ts +3 -3
- package/dist/services/runtime/openai.adapter.d.ts +46 -13
- package/dist/services/runtime/openai.adapter.js +169 -131
- package/dist/services/skill-registry.service.d.ts +1 -1
- package/dist/services/skills-pipeline/skills-research.service.js +47 -7
- package/dist/services/trust/trust.service.js +6 -4
- package/dist/services/validation-zod.service.js +3 -22
- package/dist/services/validators/index.d.ts +1 -0
- package/dist/services/validators/index.js +1 -0
- package/dist/services/validators/registry.d.ts +21 -0
- package/dist/services/validators/registry.js +42 -0
- package/dist/skills/test-skill/package.json +1 -1
- package/dist/spec/extensions/cognition.schema.json +87 -0
- package/dist/spec/layer4-economics/duadp-examples.json +44 -0
- package/dist/spec/v0.4/agent.schema.json +14 -0
- package/dist/spec/v0.5/agent-builder-openapi.yaml +230 -0
- package/dist/spec/v0.5/agent.schema.json +32 -1
- package/dist/spec/v0.5/extensions/cognition/cognition.schema.json +78 -1
- package/dist/spec/v0.5/extensions/economics/context-pack.schema.json +91 -0
- package/dist/spec/v0.5/extensions/economics/execution-profile.schema.json +148 -0
- package/dist/spec/v0.5/extensions/economics/failure-semantics.schema.json +32 -0
- package/dist/spec/v0.5/extensions/economics/replay-packet.schema.json +120 -0
- package/dist/spec/v0.5/extensions/mcp/README.md +1 -1
- package/dist/spec/v0.5/memory-hierarchy.yaml +120 -0
- package/dist/spec/v1/agent-card.schema.json +254 -0
- package/dist/types/cognition.zod.d.ts +312 -0
- package/dist/types/cognition.zod.js +223 -0
- package/dist/types/identity.zod.d.ts +5 -5
- package/dist/types/index.d.ts +53 -7
- package/dist/types/index.js +4 -2
- package/dist/types/personality.zod.d.ts +3 -3
- package/dist/utils/http-client.d.ts +22 -0
- package/dist/utils/http-client.js +51 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/proxy-resolver.d.ts +36 -0
- package/dist/utils/proxy-resolver.js +59 -0
- package/dist/utils/user-agent.d.ts +11 -0
- package/dist/utils/user-agent.js +17 -0
- package/dist/validation/version-compliance.js +1 -1
- package/examples/agentscope/react-assistant/README.md +1 -1
- package/examples/agentscope/react-assistant/agent.ossa.yaml +1 -1
- package/examples/drupal/drupal-contributor-agent/.eslintrc.json +58 -0
- package/examples/drupal/drupal-contributor-agent/.prettierrc.json +10 -0
- package/examples/drupal/drupal-contributor-agent/package.json +55 -0
- package/examples/drupal/drupal-contributor-agent/src/core/index.ts +10 -0
- package/examples/drupal/drupal-contributor-agent/src/index.ts +17 -0
- package/examples/drupal/drupal-contributor-agent/src/types/index.ts +180 -0
- package/examples/drupal/drupal-contributor-agent/tsconfig.json +36 -0
- package/examples/getting-started/01-minimal-agent.ossa.yaml +1 -1
- package/examples/getting-started/02-agent-with-tools.ossa.yaml +1 -1
- package/examples/getting-started/03-agent-with-safety.ossa.yaml +1 -1
- package/examples/getting-started/04-agent-with-messaging.ossa.yaml +1 -1
- package/examples/getting-started/05-workflow-composition.ossa.yaml +1 -1
- package/examples/getting-started/hello-world-complete.ossa.yaml +1 -1
- package/examples/reference-implementations/python-client/examples/basic_usage.py +0 -0
- package/examples/reference-implementations/python-client/examples/publish_agent.py +0 -0
- package/openapi/agent-cognition-sessions.yaml +580 -0
- package/openapi/agent-crud.yaml +20 -20
- package/openapi/core/ossa-registry-api.openapi.yaml +1 -1
- package/openapi/ossa-cli-enhancements.openapi.yaml +1 -1
- package/openapi/release-automation.openapi.yaml +1 -1
- package/openapi/schemas/common/economics.yaml +98 -0
- package/openapi/uadp-asyncapi.yaml +1 -1
- package/openapi/uadp-openapi.yaml +2 -2
- package/package.json +114 -96
- package/spec/extensions/cognition.schema.json +87 -0
- package/spec/layer4-economics/duadp-examples.json +44 -0
- package/spec/v0.4/agent.schema.json +14 -0
- package/spec/v0.5/agent-builder-openapi.yaml +230 -0
- package/spec/v0.5/agent.schema.json +32 -1
- package/spec/v0.5/extensions/cognition/cognition.schema.json +78 -1
- package/spec/v0.5/extensions/economics/context-pack.schema.json +91 -0
- package/spec/v0.5/extensions/economics/execution-profile.schema.json +148 -0
- package/spec/v0.5/extensions/economics/failure-semantics.schema.json +32 -0
- package/spec/v0.5/extensions/economics/replay-packet.schema.json +120 -0
- package/spec/v0.5/extensions/mcp/README.md +1 -1
- package/spec/v0.5/memory-hierarchy.yaml +120 -0
- package/spec/v1/agent-card.schema.json +254 -0
- package/dist/adapters/a2a/__tests__/mcp-integration.spec.d.ts +0 -5
- package/dist/adapters/a2a/__tests__/mcp-integration.spec.js +0 -268
- package/dist/adapters/a2a/__tests__/mcp-transport.spec.d.ts +0 -5
- package/dist/adapters/a2a/__tests__/mcp-transport.spec.js +0 -203
- package/dist/mcp-server/__tests__/mcp-server.spec.d.ts +0 -8
- package/dist/mcp-server/__tests__/mcp-server.spec.js +0 -566
- package/dist/validation/__tests__/error-codes.test.d.ts +0 -5
- package/dist/validation/__tests__/error-codes.test.js +0 -252
- package/dist/version-management/core/version-manager.test.d.ts +0 -2
- package/dist/version-management/core/version-manager.test.js +0 -210
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// @ts-nocheck — openclaw's strict union types need exact enum literals; runtime works correctly
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw Bridge — OSSA manifest → Docker Compose via @better-openclaw/core
|
|
4
|
+
*
|
|
5
|
+
* Delegates ALL Docker stack generation to openclaw (201 services, 44 skill packs,
|
|
6
|
+
* 21 presets). Eliminates custom Dockerfile/compose generation.
|
|
7
|
+
*
|
|
8
|
+
* @better-openclaw/core handles: service resolution, port conflict detection,
|
|
9
|
+
* env files, health checks, Caddy/Traefik proxy, Grafana dashboards, scripts.
|
|
10
|
+
*/
|
|
11
|
+
import { compose, generate, resolve, getAllPresets, getAllServices, getAllSkillPacks, } from '@better-openclaw/core';
|
|
12
|
+
import * as yaml from 'yaml';
|
|
13
|
+
/**
|
|
14
|
+
* Infer the best openclaw preset from OSSA manifest content.
|
|
15
|
+
*/
|
|
16
|
+
function inferPreset(manifest) {
|
|
17
|
+
const role = manifest.spec?.role || '';
|
|
18
|
+
const instructions = manifest.spec?.instructions || '';
|
|
19
|
+
const combined = (role + ' ' + instructions).toLowerCase();
|
|
20
|
+
if (combined.includes('research'))
|
|
21
|
+
return 'researcher';
|
|
22
|
+
if (combined.includes('devops') || combined.includes('deploy') || combined.includes('ci/cd'))
|
|
23
|
+
return 'devops';
|
|
24
|
+
if (combined.includes('content') || combined.includes('write'))
|
|
25
|
+
return 'content-creator';
|
|
26
|
+
if (combined.includes('code') || combined.includes('develop'))
|
|
27
|
+
return 'coding-team';
|
|
28
|
+
if (combined.includes('rag') || combined.includes('knowledge'))
|
|
29
|
+
return 'rag-platform';
|
|
30
|
+
if (combined.includes('security') || combined.includes('audit'))
|
|
31
|
+
return 'zero-trust';
|
|
32
|
+
if (combined.includes('orchestrat'))
|
|
33
|
+
return 'ai-orchestrator';
|
|
34
|
+
return 'minimal';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Infer openclaw service IDs from OSSA manifest tools/capabilities.
|
|
38
|
+
*/
|
|
39
|
+
function inferServices(manifest) {
|
|
40
|
+
const services = [];
|
|
41
|
+
const tools = manifest.spec?.tools || [];
|
|
42
|
+
const toolNames = tools.map((t) => typeof t === 'string' ? t : typeof t === 'object' && t !== null ? t.name || '' : '').join(' ').toLowerCase();
|
|
43
|
+
const combined = (manifest.spec?.role || '') + ' ' + (manifest.spec?.instructions || '') + ' ' + toolNames;
|
|
44
|
+
const lc = combined.toLowerCase();
|
|
45
|
+
if (lc.includes('vector') || lc.includes('embed') || lc.includes('rag'))
|
|
46
|
+
services.push('qdrant');
|
|
47
|
+
if (lc.includes('workflow') || lc.includes('automat'))
|
|
48
|
+
services.push('n8n');
|
|
49
|
+
if (lc.includes('search') || lc.includes('crawl'))
|
|
50
|
+
services.push('searxng');
|
|
51
|
+
if (lc.includes('browser') || lc.includes('playwright'))
|
|
52
|
+
services.push('browserless');
|
|
53
|
+
if (lc.includes('llm') || lc.includes('model') || lc.includes('ollama'))
|
|
54
|
+
services.push('ollama');
|
|
55
|
+
if (lc.includes('monitor') || lc.includes('metric') || lc.includes('grafana'))
|
|
56
|
+
services.push('grafana', 'prometheus');
|
|
57
|
+
if (lc.includes('storage') || lc.includes('s3') || lc.includes('minio'))
|
|
58
|
+
services.push('minio');
|
|
59
|
+
if (lc.includes('redis') || lc.includes('cache'))
|
|
60
|
+
services.push('redis');
|
|
61
|
+
if (lc.includes('postgres') || lc.includes('database'))
|
|
62
|
+
services.push('postgresql');
|
|
63
|
+
return Array.from(new Set(services));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Convert an OSSA manifest into a full Docker Compose stack using openclaw.
|
|
67
|
+
*/
|
|
68
|
+
export async function ossaToOpenclawStack(manifest, options = {}) {
|
|
69
|
+
const startTime = Date.now();
|
|
70
|
+
const files = [];
|
|
71
|
+
const warnings = [];
|
|
72
|
+
const presetId = options.preset || inferPreset(manifest);
|
|
73
|
+
const inferredServices = inferServices(manifest);
|
|
74
|
+
const allServiceIds = Array.from(new Set(inferredServices.concat(options.additionalServices || [])));
|
|
75
|
+
const projectName = (manifest.metadata?.name || 'ossa-agent').replace(/[^a-z0-9-]/gi, '-').toLowerCase();
|
|
76
|
+
// Resolve services via openclaw — type casts needed due to strict union enums in openclaw
|
|
77
|
+
// @ts-expect-error openclaw's ResolverInput has strict union types for aiProviders/deployment
|
|
78
|
+
const resolved = resolve({
|
|
79
|
+
services: allServiceIds,
|
|
80
|
+
skillPacks: options.skillPacks || [],
|
|
81
|
+
proxy: options.proxy || 'caddy',
|
|
82
|
+
gpu: options.gpu || false,
|
|
83
|
+
platform: options.platform || 'linux/amd64',
|
|
84
|
+
deployment: 'local',
|
|
85
|
+
projectName,
|
|
86
|
+
aiProviders: [],
|
|
87
|
+
outputFormat: 'single-file',
|
|
88
|
+
imageTag: 'latest',
|
|
89
|
+
restartPolicy: 'unless-stopped',
|
|
90
|
+
includeHealthchecks: true,
|
|
91
|
+
includeResourceLimits: true,
|
|
92
|
+
domain: '',
|
|
93
|
+
});
|
|
94
|
+
// Generate docker-compose.yml via openclaw
|
|
95
|
+
const composeOpts = {
|
|
96
|
+
projectName,
|
|
97
|
+
proxy: options.proxy || 'caddy',
|
|
98
|
+
gpu: options.gpu || false,
|
|
99
|
+
platform: options.platform || 'linux/amd64',
|
|
100
|
+
deployment: 'local',
|
|
101
|
+
imageTag: 'latest',
|
|
102
|
+
restartPolicy: 'unless-stopped',
|
|
103
|
+
includeHealthchecks: true,
|
|
104
|
+
includeResourceLimits: true,
|
|
105
|
+
domain: '',
|
|
106
|
+
};
|
|
107
|
+
const composeResult = compose(resolved, composeOpts);
|
|
108
|
+
files.push({
|
|
109
|
+
path: 'docker-compose.yml',
|
|
110
|
+
content: typeof composeResult === 'string' ? composeResult : yaml.stringify(composeResult),
|
|
111
|
+
type: 'yaml',
|
|
112
|
+
});
|
|
113
|
+
// Generate supporting files (env, scripts, health checks, docs)
|
|
114
|
+
const genInput = {
|
|
115
|
+
projectName,
|
|
116
|
+
services: allServiceIds,
|
|
117
|
+
skillPacks: options.skillPacks || [],
|
|
118
|
+
proxy: options.proxy || 'caddy',
|
|
119
|
+
gpu: options.gpu || false,
|
|
120
|
+
platform: options.platform || 'linux/amd64',
|
|
121
|
+
deployment: 'local',
|
|
122
|
+
aiProviders: [],
|
|
123
|
+
outputFormat: 'single-file',
|
|
124
|
+
imageTag: 'latest',
|
|
125
|
+
restartPolicy: 'unless-stopped',
|
|
126
|
+
includeHealthchecks: true,
|
|
127
|
+
includeResourceLimits: true,
|
|
128
|
+
domain: '',
|
|
129
|
+
};
|
|
130
|
+
// generate() expects GenerationInput — cast through unknown for strict union compat
|
|
131
|
+
// @ts-expect-error openclaw's GenerationInput has strict union types
|
|
132
|
+
const generated = generate(genInput, genInput);
|
|
133
|
+
if (generated && typeof generated === 'object') {
|
|
134
|
+
for (const [filename, content] of Object.entries(generated)) {
|
|
135
|
+
if (typeof content === 'string' && content.trim()) {
|
|
136
|
+
const ext = filename.endsWith('.yml') || filename.endsWith('.yaml') ? 'yaml'
|
|
137
|
+
: filename.endsWith('.env') ? 'env'
|
|
138
|
+
: filename.endsWith('.sh') ? 'shell'
|
|
139
|
+
: filename.endsWith('.md') ? 'markdown'
|
|
140
|
+
: 'text';
|
|
141
|
+
files.push({ path: filename, content, type: ext });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Include the OSSA manifest
|
|
146
|
+
files.push({
|
|
147
|
+
path: 'agent.ossa.yaml',
|
|
148
|
+
content: yaml.stringify(manifest),
|
|
149
|
+
type: 'yaml',
|
|
150
|
+
});
|
|
151
|
+
return {
|
|
152
|
+
files,
|
|
153
|
+
warnings,
|
|
154
|
+
metadata: {
|
|
155
|
+
duration: Date.now() - startTime,
|
|
156
|
+
preset: presetId,
|
|
157
|
+
serviceCount: allServiceIds.length,
|
|
158
|
+
openclawVersion: '1.0.30',
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* List available openclaw catalog for wizard/UI.
|
|
164
|
+
*/
|
|
165
|
+
export function getOpenclawCatalog() {
|
|
166
|
+
return {
|
|
167
|
+
presets: getAllPresets().map(p => ({ id: p.id, name: p.name })),
|
|
168
|
+
services: getAllServices().map(s => ({ id: s.id, name: s.name })),
|
|
169
|
+
skillPacks: getAllSkillPacks().map(s => ({ id: s.id, name: s.name })),
|
|
170
|
+
totalServices: getAllServices().length,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=openclaw-bridge.js.map
|
|
@@ -109,5 +109,6 @@ export default DrupalAdapter;
|
|
|
109
109
|
export { DrupalModuleGenerator, type DrupalModuleGeneratorOptions, } from './generator.js';
|
|
110
110
|
export { DrupalAdapter as DrupalRuntimeAdapter } from './adapter.js';
|
|
111
111
|
export { DrupalManifestExporter, type DrupalManifestExportOptions, } from './manifest-exporter.js';
|
|
112
|
+
export { renderTwigTemplate, generateAgentTemplate, generateConfigSchema, } from './twig-renderer.js';
|
|
112
113
|
export { sanitizeModuleName, toClassName, toLabel, validateDrupalCompatibility, buildValidationResult, buildComposerJson, generateBaseInfoYml, extractCapabilities, extractTools, mapOssaToolToDrupalTool, mapAllOssaToolsToDrupal, type DrupalModuleOptions, type DrupalToolDefinition, type DrupalComposerJson, type OssaToolEntry, } from './drupal-utils.js';
|
|
113
114
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -294,6 +294,8 @@ export { DrupalModuleGenerator, } from './generator.js';
|
|
|
294
294
|
export { DrupalAdapter as DrupalRuntimeAdapter } from './adapter.js';
|
|
295
295
|
// Export manifest exporter (minimal package - separation of duties)
|
|
296
296
|
export { DrupalManifestExporter, } from './manifest-exporter.js';
|
|
297
|
+
// Export Twig renderer (uses twig-drupal-filters for proper Drupal template generation)
|
|
298
|
+
export { renderTwigTemplate, generateAgentTemplate, generateConfigSchema, } from './twig-renderer.js';
|
|
297
299
|
// Export shared Drupal utilities
|
|
298
300
|
export { sanitizeModuleName, toClassName, toLabel, validateDrupalCompatibility, buildValidationResult, buildComposerJson, generateBaseInfoYml, extractCapabilities, extractTools, mapOssaToolToDrupalTool, mapAllOssaToolsToDrupal, } from './drupal-utils.js';
|
|
299
301
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twig Renderer — Render Drupal templates with proper Twig filters.
|
|
3
|
+
*
|
|
4
|
+
* Uses twig-drupal-filters to provide Drupal's custom Twig filters:
|
|
5
|
+
* |t, |trans, |clean_class, |safe_join, |render, |without, |placeholder, etc.
|
|
6
|
+
*
|
|
7
|
+
* This replaces string concatenation for generating .html.twig files,
|
|
8
|
+
* producing templates that Drupal developers will recognize as correct.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Render a Twig template string with Drupal filters available.
|
|
12
|
+
*/
|
|
13
|
+
export declare function renderTwigTemplate(template: string, context?: Record<string, unknown>): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generate a Drupal module's default template file.
|
|
16
|
+
* Uses real Twig syntax with Drupal filters.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateAgentTemplate(agentName: string, machineName: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Generate a Drupal config schema YAML for an agent settings form.
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateConfigSchema(machineName: string): string;
|
|
23
|
+
//# sourceMappingURL=twig-renderer.d.ts.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twig Renderer — Render Drupal templates with proper Twig filters.
|
|
3
|
+
*
|
|
4
|
+
* Uses twig-drupal-filters to provide Drupal's custom Twig filters:
|
|
5
|
+
* |t, |trans, |clean_class, |safe_join, |render, |without, |placeholder, etc.
|
|
6
|
+
*
|
|
7
|
+
* This replaces string concatenation for generating .html.twig files,
|
|
8
|
+
* producing templates that Drupal developers will recognize as correct.
|
|
9
|
+
*/
|
|
10
|
+
import Twig from 'twig';
|
|
11
|
+
// Register Drupal filters
|
|
12
|
+
let filtersRegistered = false;
|
|
13
|
+
function ensureFiltersRegistered() {
|
|
14
|
+
if (filtersRegistered)
|
|
15
|
+
return;
|
|
16
|
+
try {
|
|
17
|
+
// twig-drupal-filters registers itself onto the Twig instance
|
|
18
|
+
require('twig-drupal-filters')(Twig);
|
|
19
|
+
filtersRegistered = true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Fallback: register minimal filters if twig-drupal-filters fails
|
|
23
|
+
const twigInstance = Twig;
|
|
24
|
+
if (twigInstance.extendFilter) {
|
|
25
|
+
twigInstance.extendFilter('t', (val) => val);
|
|
26
|
+
twigInstance.extendFilter('trans', (val) => val);
|
|
27
|
+
twigInstance.extendFilter('clean_class', (val) => val.replace(/[^a-zA-Z0-9-_]/g, '-').toLowerCase());
|
|
28
|
+
twigInstance.extendFilter('render', (val) => val);
|
|
29
|
+
filtersRegistered = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Render a Twig template string with Drupal filters available.
|
|
35
|
+
*/
|
|
36
|
+
export function renderTwigTemplate(template, context = {}) {
|
|
37
|
+
ensureFiltersRegistered();
|
|
38
|
+
const twigTemplate = Twig.twig({ data: template });
|
|
39
|
+
return twigTemplate.render(context);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generate a Drupal module's default template file.
|
|
43
|
+
* Uses real Twig syntax with Drupal filters.
|
|
44
|
+
*/
|
|
45
|
+
export function generateAgentTemplate(agentName, machineName) {
|
|
46
|
+
return `{#
|
|
47
|
+
/**
|
|
48
|
+
* @file
|
|
49
|
+
* Default theme implementation for ${agentName} agent display.
|
|
50
|
+
*
|
|
51
|
+
* Available variables:
|
|
52
|
+
* - agent: The OSSA agent entity.
|
|
53
|
+
* - content: The rendered content fields.
|
|
54
|
+
* - attributes: HTML attributes for the containing element.
|
|
55
|
+
*
|
|
56
|
+
* @see template_preprocess_${machineName}()
|
|
57
|
+
*
|
|
58
|
+
* @ingroup themeable
|
|
59
|
+
*/
|
|
60
|
+
#}
|
|
61
|
+
<article{{ attributes.addClass('${machineName}') }}>
|
|
62
|
+
{% if label %}
|
|
63
|
+
<h2{{ title_attributes }}>
|
|
64
|
+
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
|
|
65
|
+
</h2>
|
|
66
|
+
{% endif %}
|
|
67
|
+
|
|
68
|
+
<div{{ content_attributes.addClass('${machineName}__content') }}>
|
|
69
|
+
{% if content.field_trust_tier %}
|
|
70
|
+
<div class="{{ '${machineName}__trust-tier'|clean_class }}">
|
|
71
|
+
{{ content.field_trust_tier }}
|
|
72
|
+
</div>
|
|
73
|
+
{% endif %}
|
|
74
|
+
|
|
75
|
+
{{ content|without('field_trust_tier') }}
|
|
76
|
+
</div>
|
|
77
|
+
</article>
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Generate a Drupal config schema YAML for an agent settings form.
|
|
82
|
+
*/
|
|
83
|
+
export function generateConfigSchema(machineName) {
|
|
84
|
+
return `${machineName}.settings:
|
|
85
|
+
type: config_object
|
|
86
|
+
label: '${machineName} settings'
|
|
87
|
+
mapping:
|
|
88
|
+
enabled:
|
|
89
|
+
type: boolean
|
|
90
|
+
label: 'Enable agent'
|
|
91
|
+
trust_tier:
|
|
92
|
+
type: string
|
|
93
|
+
label: 'Trust tier'
|
|
94
|
+
api_endpoint:
|
|
95
|
+
type: string
|
|
96
|
+
label: 'API endpoint URL'
|
|
97
|
+
`;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=twig-renderer.js.map
|
|
@@ -604,7 +604,8 @@ export interface WorkflowContext {
|
|
|
604
604
|
const extensions = manifest.extensions?.gitlab;
|
|
605
605
|
return JSON.stringify({
|
|
606
606
|
url: extensions?.webhook?.url ||
|
|
607
|
-
extensions?.webhook?.url ||
|
|
607
|
+
extensions?.webhook?.url ||
|
|
608
|
+
`http://localhost:8080/webhook/${agentName}`,
|
|
608
609
|
token: '${WEBHOOK_SECRET}',
|
|
609
610
|
enable_ssl_verification: extensions?.webhook?.ssl_verification ?? false,
|
|
610
611
|
push_events: false,
|
package/dist/api/index.js
CHANGED
|
@@ -29,7 +29,8 @@ export function createApp(opts) {
|
|
|
29
29
|
// Routes
|
|
30
30
|
app.use('/', healthRouter());
|
|
31
31
|
app.use('/api/v1/manifests', manifestsRouter());
|
|
32
|
-
|
|
32
|
+
// Agent builder routes (canonical path per OWNERSHIP.md + BIBLE_OSSA_AGENT_BUILDER.md)
|
|
33
|
+
app.use('/api/agent-builder', wizardRouter());
|
|
33
34
|
app.use('/api/v1/export', exportRouter());
|
|
34
35
|
app.use('/api/v1/convert', convertRouter());
|
|
35
36
|
app.use('/api/v1/skills', skillsRouter());
|
|
@@ -18,7 +18,9 @@ export function mcpRouter() {
|
|
|
18
18
|
try {
|
|
19
19
|
const { source, directory = '.' } = req.body;
|
|
20
20
|
if (!source) {
|
|
21
|
-
res
|
|
21
|
+
res
|
|
22
|
+
.status(400)
|
|
23
|
+
.json({ error: 'source is required (e.g. claude-desktop, cursor)' });
|
|
22
24
|
return;
|
|
23
25
|
}
|
|
24
26
|
const result = await service.sync(source, directory);
|
|
@@ -23,7 +23,9 @@ export function wizardRouter() {
|
|
|
23
23
|
router.get('/definitions', (req, res) => {
|
|
24
24
|
const parsed = DefinitionsQuerySchema.safeParse(req.query);
|
|
25
25
|
if (!parsed.success) {
|
|
26
|
-
res
|
|
26
|
+
res
|
|
27
|
+
.status(400)
|
|
28
|
+
.json({ error: 'Invalid query', details: parsed.error.flatten() });
|
|
27
29
|
return;
|
|
28
30
|
}
|
|
29
31
|
const steps = service.getStepDefinitions(parsed.data.kind, parsed.data.mode);
|
|
@@ -288,7 +288,7 @@ let DiscoverTypeCommand = class DiscoverTypeCommand {
|
|
|
288
288
|
createManifestFromContext(name, type, context) {
|
|
289
289
|
const capabilities = this.typeDetector.suggestCapabilitiesForType(type);
|
|
290
290
|
return {
|
|
291
|
-
apiVersion: 'ossa.
|
|
291
|
+
apiVersion: 'ossa/v0.5.1',
|
|
292
292
|
kind: 'Agent',
|
|
293
293
|
metadata: {
|
|
294
294
|
name,
|
|
@@ -108,8 +108,10 @@ agentCardCommand
|
|
|
108
108
|
agentCardCommand
|
|
109
109
|
.command('validate')
|
|
110
110
|
.argument('<file>', 'Path to agent-card.json to validate')
|
|
111
|
-
.
|
|
112
|
-
.
|
|
111
|
+
.option('--schema-version <version>', 'Schema version to validate against: "v0.4" (OSSA legacy) or "1.0" (Agent Card v1.0 spec)', 'v0.4')
|
|
112
|
+
.description('Validate an agent-card.json against the OSSA schema or Agent Card v1.0 spec.\n' +
|
|
113
|
+
'Use --schema-version 1.0 to validate against the interoperability Agent Card v1.0 spec.')
|
|
114
|
+
.action(async (filePath, opts) => {
|
|
113
115
|
try {
|
|
114
116
|
const fullPath = path.resolve(filePath);
|
|
115
117
|
if (!fs.existsSync(fullPath)) {
|
|
@@ -125,10 +127,19 @@ agentCardCommand
|
|
|
125
127
|
console.error(chalk.red('✗ Invalid JSON'));
|
|
126
128
|
process.exit(1);
|
|
127
129
|
}
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
+
// Resolve schema path based on --schema-version
|
|
131
|
+
let schemaPath;
|
|
132
|
+
let schemaLabel;
|
|
133
|
+
if (opts.schemaVersion === '1.0') {
|
|
134
|
+
schemaPath = path.resolve(__dirname, '../../../spec/v1/agent-card.schema.json');
|
|
135
|
+
schemaLabel = 'Agent Card v1.0';
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
schemaPath = path.resolve(__dirname, '../../../spec/v0.4/agent-card.schema.json');
|
|
139
|
+
schemaLabel = 'OSSA Agent Card v0.4';
|
|
140
|
+
}
|
|
130
141
|
if (!fs.existsSync(schemaPath)) {
|
|
131
|
-
console.error(chalk.red(
|
|
142
|
+
console.error(chalk.red(`✗ Schema not found: ${schemaPath}`));
|
|
132
143
|
process.exit(1);
|
|
133
144
|
}
|
|
134
145
|
const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
|
|
@@ -136,14 +147,30 @@ agentCardCommand
|
|
|
136
147
|
addFormats(ajv);
|
|
137
148
|
const validate = ajv.compile(schema);
|
|
138
149
|
if (validate(card)) {
|
|
139
|
-
console.log(chalk.green(
|
|
150
|
+
console.log(chalk.green(`✓ Agent card is valid (${schemaLabel})`));
|
|
140
151
|
const c = card;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
152
|
+
if (opts.schemaVersion === '1.0') {
|
|
153
|
+
// Agent Card v1.0 fields
|
|
154
|
+
console.log(chalk.gray(` Name: ${c.name}`));
|
|
155
|
+
console.log(chalk.gray(` humanReadableId: ${c.humanReadableId}`));
|
|
156
|
+
console.log(chalk.gray(` agentVersion: ${c.agentVersion}`));
|
|
157
|
+
console.log(chalk.gray(` url: ${c.url}`));
|
|
158
|
+
const schemes = Array.isArray(c.authSchemes)
|
|
159
|
+
? c.authSchemes.map((s) => s.scheme).join(', ')
|
|
160
|
+
: '—';
|
|
161
|
+
console.log(chalk.gray(` authSchemes: ${schemes}`));
|
|
162
|
+
const skillCount = Array.isArray(c.skills) ? c.skills.length : 0;
|
|
163
|
+
console.log(chalk.gray(` skills: ${skillCount} defined`));
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Legacy OSSA v0.4 fields
|
|
167
|
+
console.log(chalk.gray(` Name: ${c.name}`));
|
|
168
|
+
console.log(chalk.gray(` URI: ${c.uri}`));
|
|
169
|
+
console.log(chalk.gray(` Version: ${c.version} (OSSA ${c.ossaVersion})`));
|
|
170
|
+
}
|
|
144
171
|
}
|
|
145
172
|
else {
|
|
146
|
-
console.error(chalk.red(
|
|
173
|
+
console.error(chalk.red(`✗ Agent card validation failed (${schemaLabel}):`));
|
|
147
174
|
for (const error of validate.errors || []) {
|
|
148
175
|
console.error(chalk.red(` ${error.instancePath} ${error.message}`));
|
|
149
176
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* OSSA Agents Sync Command
|
|
3
3
|
*
|
|
4
4
|
* Syncs platform agents between locations:
|
|
5
|
-
* NAS
|
|
5
|
+
* Remote: $OSSA_AGENTS_SOURCE (e.g. a NAS or network share)
|
|
6
6
|
* Local: ~/.agents/platform-agents/
|
|
7
|
-
*
|
|
7
|
+
* Server: $OSSA_ORACLE_HOST (any remote host, via SSH)
|
|
8
8
|
*
|
|
9
9
|
* Also scans project .agents/ folders and builds a unified registry.
|
|
10
10
|
*
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* OSSA Agents Sync Command
|
|
3
3
|
*
|
|
4
4
|
* Syncs platform agents between locations:
|
|
5
|
-
* NAS
|
|
5
|
+
* Remote: $OSSA_AGENTS_SOURCE (e.g. a NAS or network share)
|
|
6
6
|
* Local: ~/.agents/platform-agents/
|
|
7
|
-
*
|
|
7
|
+
* Server: $OSSA_ORACLE_HOST (any remote host, via SSH)
|
|
8
8
|
*
|
|
9
9
|
* Also scans project .agents/ folders and builds a unified registry.
|
|
10
10
|
*
|
|
@@ -19,9 +19,11 @@ import chalk from 'chalk';
|
|
|
19
19
|
import * as fs from 'fs';
|
|
20
20
|
import * as path from 'path';
|
|
21
21
|
import * as os from 'os';
|
|
22
|
-
const NAS_AGENTS_PATH =
|
|
22
|
+
const NAS_AGENTS_PATH = process.env.OSSA_AGENTS_SOURCE ||
|
|
23
|
+
path.join(os.homedir(), '.agents', 'remote');
|
|
23
24
|
const LOCAL_AGENTS_PATH = path.join(os.homedir(), '.agents', 'platform-agents');
|
|
24
|
-
const
|
|
25
|
+
const ORACLE_HOST = process.env.OSSA_ORACLE_HOST || '';
|
|
26
|
+
const ORACLE_AGENTS_PATH = process.env.OSSA_ORACLE_PATH || '/opt/ossa/.agents/platform-agents';
|
|
25
27
|
function copyDirRecursive(src, dest, stats) {
|
|
26
28
|
if (!fs.existsSync(src))
|
|
27
29
|
return;
|
|
@@ -87,26 +89,28 @@ function scanAgentsDir(agentsPath) {
|
|
|
87
89
|
}
|
|
88
90
|
export const agentsSyncCommand = new Command('agents-sync')
|
|
89
91
|
.description('Sync platform agents between NAS, local, and Oracle')
|
|
90
|
-
.option('--source <path>', 'Source agents directory', NAS_AGENTS_PATH)
|
|
91
|
-
.option('--target <target>', 'Target: "local" (default), "
|
|
92
|
-
.option('--scan', 'Scan all
|
|
92
|
+
.option('--source <path>', 'Source agents directory (overrides OSSA_AGENTS_SOURCE env var)', NAS_AGENTS_PATH)
|
|
93
|
+
.option('--target <target>', 'Target: "local" (default), "server", or a path', 'local')
|
|
94
|
+
.option('--scan', 'Scan all $OSSA_PROJECTS_DIR projects for .agents/ folders')
|
|
93
95
|
.option('--publish <url>', 'Publish all agents to a DUADP node')
|
|
94
96
|
.option('--dry-run', 'Show what would be synced without doing it')
|
|
95
97
|
.option('--json', 'Output as JSON')
|
|
96
98
|
.action(async (options) => {
|
|
97
99
|
// Scan mode — find all .agents/ across projects
|
|
98
100
|
if (options.scan) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
const projectsDir = process.env.OSSA_PROJECTS_DIR ||
|
|
102
|
+
path.join(os.homedir(), '.agents', 'projects');
|
|
103
|
+
if (!fs.existsSync(projectsDir)) {
|
|
104
|
+
console.error(chalk.red(`Projects directory not found: ${projectsDir}`));
|
|
105
|
+
console.error(chalk.yellow('Set OSSA_PROJECTS_DIR to your projects root directory.'));
|
|
102
106
|
process.exit(1);
|
|
103
107
|
}
|
|
104
|
-
const projects = fs.readdirSync(
|
|
108
|
+
const projects = fs.readdirSync(projectsDir, { withFileTypes: true });
|
|
105
109
|
const allAgents = {};
|
|
106
110
|
for (const project of projects) {
|
|
107
111
|
if (!project.isDirectory())
|
|
108
112
|
continue;
|
|
109
|
-
const projectPath = path.join(
|
|
113
|
+
const projectPath = path.join(projectsDir, project.name);
|
|
110
114
|
// Check .agents/
|
|
111
115
|
const dotAgents = path.join(projectPath, '.agents');
|
|
112
116
|
if (fs.existsSync(dotAgents)) {
|
|
@@ -167,18 +171,24 @@ export const agentsSyncCommand = new Command('agents-sync')
|
|
|
167
171
|
case 'local':
|
|
168
172
|
destPath = LOCAL_AGENTS_PATH;
|
|
169
173
|
break;
|
|
170
|
-
case '
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
case 'server':
|
|
175
|
+
case 'oracle': {
|
|
176
|
+
// For remote servers, show the rsync command instead of executing it
|
|
177
|
+
if (!ORACLE_HOST) {
|
|
178
|
+
console.error(chalk.red('Set OSSA_ORACLE_HOST to your remote server hostname.'));
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
console.log(chalk.cyan('Remote server sync via rsync over SSH:'));
|
|
182
|
+
console.log(chalk.white(` rsync -avz --delete ${sourcePath}/ ${ORACLE_HOST}:${ORACLE_AGENTS_PATH}/`));
|
|
174
183
|
process.exit(0);
|
|
175
184
|
break;
|
|
185
|
+
}
|
|
176
186
|
default:
|
|
177
187
|
destPath = options.target;
|
|
178
188
|
}
|
|
179
189
|
if (!fs.existsSync(sourcePath)) {
|
|
180
190
|
console.error(chalk.red(`Source not found: ${sourcePath}`));
|
|
181
|
-
console.error(chalk.yellow('Is the
|
|
191
|
+
console.error(chalk.yellow('Is the remote source directory accessible? Set OSSA_AGENTS_SOURCE to override.'));
|
|
182
192
|
process.exit(1);
|
|
183
193
|
}
|
|
184
194
|
if (options.dryRun) {
|
|
@@ -19,7 +19,7 @@ export class CatalogConfig {
|
|
|
19
19
|
this.duoOutputPath =
|
|
20
20
|
process.env.GITLAB_DUO_OUTPUT_PATH || './.gitlab/duo/agents';
|
|
21
21
|
this.gitlabTokenPath =
|
|
22
|
-
process.env.GITLAB_TOKEN_PATH || path.join(home, '.
|
|
22
|
+
process.env.GITLAB_TOKEN_PATH || path.join(home, '.config', 'gitlab', 'token');
|
|
23
23
|
this.ossaNamespace = process.env.OSSA_NAMESPACE || 'bluefly';
|
|
24
24
|
this.gitlabApiUrl =
|
|
25
25
|
process.env.GITLAB_API_URL || 'https://gitlab.com/api/v4';
|
|
@@ -10,9 +10,9 @@ import * as yaml from 'yaml';
|
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import { ValidateOptionsSchema } from './schemas.js';
|
|
12
12
|
import { CatalogConfig } from './config.js';
|
|
13
|
-
// OSSA v0.3.x
|
|
13
|
+
// OSSA manifest schema — accepts v0.3.x through v0.5.x (use API_VERSION from version.ts for generation)
|
|
14
14
|
const OssaManifestSchema = z.object({
|
|
15
|
-
apiVersion: z.string().regex(/^ossa\/v0\.3/),
|
|
15
|
+
apiVersion: z.string().regex(/^ossa\/v0\.[3-9]/),
|
|
16
16
|
kind: z.enum(['Agent', 'Worker', 'Orchestrator']),
|
|
17
17
|
metadata: z.object({
|
|
18
18
|
name: z.string().min(1),
|
|
@@ -73,7 +73,7 @@ configCommand
|
|
|
73
73
|
});
|
|
74
74
|
configCommand.addHelpText('after', `
|
|
75
75
|
Known keys (you can set any key; these are commonly used):
|
|
76
|
-
SKILLS_PATH Directory for skills add/list (e.g. /
|
|
76
|
+
SKILLS_PATH Directory for skills add/list (e.g. /path/to/your/skills)
|
|
77
77
|
BLUEFLY_SKILLS_MARKETPLACE Set to 1 to prefer marketplace skills path in MCP
|
|
78
78
|
BLUEFLY_SKILLS_CATALOG Path to marketplace-skills-catalog.json
|
|
79
79
|
BLUEFLY_SKILLS_PATH Alias for skills path
|
|
@@ -84,7 +84,7 @@ Known keys (you can set any key; these are commonly used):
|
|
|
84
84
|
GITLAB_TOKEN GitLab token (prefer env for secrets)
|
|
85
85
|
|
|
86
86
|
Examples:
|
|
87
|
-
ossa config set SKILLS_PATH /
|
|
87
|
+
ossa config set SKILLS_PATH /path/to/your/skills
|
|
88
88
|
ossa config get SKILLS_PATH
|
|
89
89
|
ossa config list
|
|
90
90
|
ossa config unset SKILLS_PATH
|