@bluefly/openstandardagents 0.2.5-RC → 0.2.7
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/.github/ISSUE_TEMPLATE/bug_report.yml +63 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +40 -0
- package/.github/workflows/dependabot-comment.yml +34 -0
- package/.github/workflows/pr-comment.yml +33 -0
- package/.husky/pre-commit +5 -0
- package/.kiro/config.json +21 -0
- package/.kiro/settings/mcp.json +61 -0
- package/.kiro/specs/scripts-migration-api-first/design.md +883 -0
- package/.kiro/specs/scripts-migration-api-first/requirements.md +165 -0
- package/.kiro/specs/scripts-migration-api-first/tasks.md +539 -0
- package/.kiro/specs/{website-design-audit → website-brand-identity}/design.md +381 -0
- package/.kiro/specs/{website-design-audit → website-brand-identity}/requirements.md +88 -0
- package/.kiro/specs/website-brand-identity/tasks.md +981 -0
- package/CHANGELOG.md +23 -0
- package/README.md +12 -3
- package/bin/ossa-dev +42 -0
- package/bin/ossa-export +32 -0
- package/bin/ossa-generate +60 -0
- package/bin/ossa-health +40 -0
- package/bin/ossa-init +26 -0
- package/dist/repositories/schema.repository.d.ts.map +1 -1
- package/dist/repositories/schema.repository.js +15 -10
- package/dist/repositories/schema.repository.js.map +1 -1
- package/dist/services/github-sync/github-client.d.ts +14 -0
- package/dist/services/github-sync/github-client.d.ts.map +1 -0
- package/dist/services/github-sync/github-client.js +41 -0
- package/dist/services/github-sync/github-client.js.map +1 -0
- package/dist/services/github-sync/gitlab-client.d.ts +17 -0
- package/dist/services/github-sync/gitlab-client.d.ts.map +1 -0
- package/dist/services/github-sync/gitlab-client.js +42 -0
- package/dist/services/github-sync/gitlab-client.js.map +1 -0
- package/dist/services/github-sync/schemas.d.ts +46 -0
- package/dist/services/github-sync/schemas.d.ts.map +1 -0
- package/dist/services/github-sync/schemas.js +36 -0
- package/dist/services/github-sync/schemas.js.map +1 -0
- package/dist/services/github-sync/sync.service.d.ts +27 -0
- package/dist/services/github-sync/sync.service.d.ts.map +1 -0
- package/dist/services/github-sync/sync.service.js +99 -0
- package/dist/services/github-sync/sync.service.js.map +1 -0
- package/dist/services/runtime/claude/capability-mapper.d.ts +84 -0
- package/dist/services/runtime/claude/capability-mapper.d.ts.map +1 -0
- package/dist/services/runtime/claude/capability-mapper.js +245 -0
- package/dist/services/runtime/claude/capability-mapper.js.map +1 -0
- package/dist/services/runtime/claude/claude-adapter.d.ts +80 -0
- package/dist/services/runtime/claude/claude-adapter.d.ts.map +1 -0
- package/dist/services/runtime/claude/claude-adapter.js +287 -0
- package/dist/services/runtime/claude/claude-adapter.js.map +1 -0
- package/dist/services/runtime/claude/manifest-parser.d.ts +77 -0
- package/dist/services/runtime/claude/manifest-parser.d.ts.map +1 -0
- package/dist/services/runtime/claude/manifest-parser.js +169 -0
- package/dist/services/runtime/claude/manifest-parser.js.map +1 -0
- package/dist/services/runtime/claude/types.d.ts +115 -0
- package/dist/services/runtime/claude/types.d.ts.map +1 -0
- package/dist/services/runtime/claude/types.js +6 -0
- package/dist/services/runtime/claude/types.js.map +1 -0
- package/dist/services/validation.service.d.ts.map +1 -1
- package/dist/services/validation.service.js +12 -1
- package/dist/services/validation.service.js.map +1 -1
- package/dist/spec/v0.2.4/ossa-0.2.4.schema.json +85 -208
- package/dist/spec/v0.2.6/CHANGELOG.md +401 -0
- package/dist/spec/v0.2.6/README.md +72 -0
- package/dist/spec/v0.2.6/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/dist/spec/v0.2.6/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
- package/dist/spec/v0.2.6/ossa-0.2.6.schema.json +1786 -0
- package/dist/spec/v0.2.6/ossa-0.2.6.yaml +581 -0
- package/dist/spec/v0.2.6-dev/CHANGELOG.md +164 -0
- package/dist/spec/v0.2.6-dev/README.md +75 -0
- package/dist/spec/v0.2.6-dev/migrations/v0.2.2-to-v0.2.3.md +343 -0
- package/dist/spec/v0.2.6-dev/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/dist/spec/{v0.2.4/ossa-0.2.4-dev.schema.json → v0.2.6-dev/ossa-0.2.5.schema.json} +9 -9
- package/dist/spec/v0.2.6-dev/ossa-0.2.5.yaml +581 -0
- package/{spec/v0.2.4/ossa-0.2.4-dev.schema.json → dist/spec/v0.2.6-dev/ossa-0.2.6-dev.schema.json} +9 -9
- package/dist/spec/v0.2.6-dev/ossa-0.2.6-dev.yaml +448 -0
- package/dist/spec/v0.2.7/core/agentgraph.md +324 -0
- package/dist/spec/v0.2.7/resources/agentgraph.yaml +135 -0
- package/docs/brand-guide/01-brand-overview.md +37 -0
- package/docs/brand-guide/02-logo-usage.md +43 -0
- package/docs/brand-guide/03-color-palette.md +70 -0
- package/docs/brand-guide/04-typography.md +82 -0
- package/docs/brand-guide/05-voice-and-tone.md +108 -0
- package/docs/brand-guide/06-visual-elements.md +137 -0
- package/docs/brand-guide/07-application-examples.md +153 -0
- package/docs/brand-guide/OssaLogo/OssA_Logo.svg +21 -0
- package/docs/brand-guide/OssaLogo/brand.af +0 -0
- package/docs/brand-guide/README.md +107 -0
- package/docs/comparison.md +315 -0
- package/docs/operations/automation-roadmap.md +245 -0
- package/docs/operations/github-sync-strategy.md +357 -0
- package/examples/anthropic/claude-assistant.ossa.json +5 -4
- package/examples/autogen/multi-agent.ossa.json +6 -4
- package/examples/crewai/research-team.ossa.json +14 -5
- package/examples/cursor/code-review-agent.ossa.json +21 -6
- package/examples/langchain/chain-agent.ossa.json +21 -5
- package/examples/langflow/workflow-agent.ossa.json +2 -3
- package/examples/langgraph/state-machine-agent.ossa.json +2 -3
- package/examples/llamaindex/rag-agent.ossa.json +2 -3
- package/examples/openai/multi-tool-agent.ossa.json +32 -9
- package/examples/openai/swarm-agent.ossa.json +18 -5
- package/examples/vercel/edge-agent.ossa.json +5 -4
- package/openapi/github-sync.yaml +115 -0
- package/package.json +25 -4
- package/scripts/README.md +103 -0
- package/scripts/auto-rebase-mrs.ts +106 -0
- package/scripts/batch-dependabot.sh +57 -0
- package/scripts/configure-gitlab-branch-protection.ts +95 -0
- package/scripts/create-issue-helper.ts +238 -0
- package/scripts/create-milestone-issue.ts +73 -0
- package/scripts/fix-schema-formats.js +82 -0
- package/scripts/generate-agents-catalog.ts +77 -0
- package/scripts/generate-api-docs.ts +218 -0
- package/scripts/generate-cli-docs.ts +410 -0
- package/scripts/generate-config-docs.ts +109 -0
- package/scripts/generate-errors-docs.ts +76 -0
- package/scripts/generate-examples-docs.ts +99 -0
- package/scripts/generate-schema-docs.ts +296 -0
- package/scripts/generate-types-docs.ts +48 -0
- package/scripts/lowercase-docs.ts +43 -0
- package/scripts/manage-milestone-mrs.ts +279 -0
- package/scripts/rebase-all-mrs.sh +75 -0
- package/scripts/sync-github-pr.sh +48 -0
- package/scripts/sync-version.js +40 -0
- package/scripts/sync-wiki.sh +50 -0
- package/scripts/validate-all.js +127 -0
- package/spec/v0.2.4/ossa-0.2.4.schema.json +85 -208
- package/spec/v0.2.6/CHANGELOG.md +401 -0
- package/spec/v0.2.6/README.md +72 -0
- package/spec/v0.2.6/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/spec/v0.2.6/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
- package/spec/v0.2.6/ossa-0.2.6.schema.json +1786 -0
- package/spec/v0.2.6/ossa-0.2.6.yaml +581 -0
- package/spec/v0.2.6-dev/CHANGELOG.md +164 -0
- package/spec/v0.2.6-dev/README.md +75 -0
- package/spec/v0.2.6-dev/migrations/v0.2.2-to-v0.2.3.md +343 -0
- package/spec/v0.2.6-dev/migrations/v0.2.3-to-v0.2.4.md +599 -0
- package/spec/v0.2.6-dev/ossa-0.2.5.schema.json +1696 -0
- package/spec/v0.2.6-dev/ossa-0.2.5.yaml +581 -0
- package/spec/v0.2.6-dev/ossa-0.2.6-dev.schema.json +1696 -0
- package/spec/v0.2.6-dev/ossa-0.2.6-dev.yaml +448 -0
- package/spec/v0.2.7/core/agentgraph.md +324 -0
- package/spec/v0.2.7/resources/agentgraph.yaml +135 -0
- package/website/DESIGN_SYSTEM_IMPLEMENTATION.md +445 -0
- package/website/app/about/page.tsx +53 -44
- package/website/app/ecosystem/page.tsx +146 -111
- package/website/app/globals.scss +256 -21
- package/website/app/page.tsx +394 -182
- package/website/app/page.tsx.bak +679 -0
- package/website/app/page.tsx.bak2 +649 -0
- package/website/app/schema/page.tsx +3 -3
- package/website/app/specification/page.tsx +1 -1
- package/website/components/layout/Header.tsx +27 -23
- package/website/components/ui/Badge.tsx +82 -0
- package/website/components/ui/Button.tsx +116 -0
- package/website/components/ui/Card.tsx +167 -0
- package/website/components/ui/Checkbox.tsx +141 -0
- package/website/components/ui/Input.tsx +169 -0
- package/website/components/ui/Radio.tsx +141 -0
- package/website/components/ui/Select.tsx +182 -0
- package/website/components/ui/Tag.tsx +158 -0
- package/website/components/ui/Textarea.tsx +195 -0
- package/website/components/ui/index.ts +11 -0
- package/website/content/docs/{00-HOME.md → 00-home.md} +1 -1
- package/website/content/docs/agents/catalog.md +28 -0
- package/website/content/docs/{AIFlow-Framework-Integration-with-OSSA.md → aiflow-framework-integration-with-ossa.md} +2 -2
- package/website/content/docs/api-reference/index.md +38 -0
- package/website/content/docs/api-reference/ossa-core-api.md +634 -0
- package/website/content/docs/api-reference/ossa-registry-api.md +515 -0
- package/website/content/docs/api-reference/unified-agent-gateway.md +599 -0
- package/website/content/docs/cli-reference/index.md +111 -0
- package/website/content/docs/cli-reference/ossa-agents.md +70 -0
- package/website/content/docs/cli-reference/ossa-export.md +56 -0
- package/website/content/docs/cli-reference/ossa-generate.md +66 -0
- package/website/content/docs/cli-reference/ossa-gitlab-agent.md +57 -0
- package/website/content/docs/cli-reference/ossa-import.md +56 -0
- package/website/content/docs/cli-reference/ossa-init.md +57 -0
- package/website/content/docs/cli-reference/ossa-migrate.md +62 -0
- package/website/content/docs/cli-reference/ossa-run.md +66 -0
- package/website/content/docs/cli-reference/ossa-schema.md +57 -0
- package/website/content/docs/cli-reference/ossa-setup.md +57 -0
- package/website/content/docs/cli-reference/ossa-validate.md +66 -0
- package/website/content/docs/configuration/index.md +97 -0
- package/website/content/docs/deployment/github-mirroring.md +924 -0
- package/website/content/docs/documentation.md +100 -0
- package/website/content/docs/ecosystem/framework-support.md +551 -9
- package/website/content/docs/errors/index.md +10 -0
- package/website/content/docs/examples/{AIFlow-Framework-Integration-with-OSSA.md → aiflow-framework-integration-with-ossa.md} +2 -2
- package/website/content/docs/examples/catalog.md +300 -0
- package/website/content/docs/for-audiences/{Students-Researchers.md → students-researchers.md} +1 -1
- package/website/content/docs/getting-started/{Installation.md → installation.md} +1 -1
- package/website/content/docs/getting-started.md +1 -1
- package/website/content/docs/integrations/aiflow.md +2 -2
- package/website/content/docs/migration-guides/anthropic-mcp-to-ossa.md +5 -5
- package/website/content/docs/migration-guides/crewai-to-ossa.md +3 -3
- package/website/content/docs/migration-guides/drupal-eca-to-ossa.md +7 -7
- package/website/content/docs/migration-guides/langchain-to-ossa.md +4 -4
- package/website/content/docs/openapi-extensions/index.md +1 -1
- package/website/content/docs/ossa-compliant-badge.md +1 -1
- package/website/content/docs/pre-release/index.md +5 -5
- package/website/content/docs/releases/v0.2.6.md +99 -0
- package/website/content/docs/schema-reference/agent-capabilities.md +50 -0
- package/website/content/docs/schema-reference/agent-id.md +52 -0
- package/website/content/docs/schema-reference/agent-name.md +50 -0
- package/website/content/docs/schema-reference/agent-role.md +54 -0
- package/website/content/docs/schema-reference/agent-version.md +50 -0
- package/website/content/docs/schema-reference/index.md +26 -157
- package/website/content/docs/types-reference/index.md +105 -0
- package/website/content/docs/versioning.md +3 -3
- package/website/dev.sh +53 -0
- package/website/docker-compose.dev.yml +36 -0
- package/website/lib/version.ts +1 -1
- package/website/lib/versions.json +45 -20
- package/website/package.json +1 -1
- package/website/styles/_spacing.scss +453 -0
- package/website/styles/_tokens.scss +245 -0
- package/website/styles/_typography.scss +361 -0
- package/website/styles/_variables.scss +270 -19
- package/website/tailwind.config.ts +113 -79
- package/.kiro/specs/agent-buildkit-templates/design.md +0 -495
- package/.kiro/specs/agent-buildkit-templates/requirements.md +0 -165
- package/.kiro/specs/kiro-ide-supercharger/README.md +0 -202
- package/.kiro/specs/kiro-ide-supercharger/design.md +0 -1005
- package/.kiro/specs/kiro-ide-supercharger/requirements.md +0 -141
- package/.kiro/specs/kiro-ide-supercharger/tasks.md +0 -507
- package/docs/issue-19-completion-summary.md +0 -648
- package/docs/issue-19-validation.md +0 -351
- package/website/content/docs/Examples.md +0 -71
- package/website/content/docs/OpenAPI-Extensions.md +0 -934
- package/website/content/docs/core-concepts/Project-Structure.md +0 -348
- package/website/content/docs/examples/Migration-Guides.md +0 -214
- package/website/content/docs/for-audiences/Architects.md +0 -224
- package/website/content/docs/for-audiences/Developers.md +0 -220
- package/website/content/docs/for-audiences/Enterprises.md +0 -256
- package/website/content/docs/getting-started/5-Minute-Overview.md +0 -85
- package/website/content/docs/getting-started/First-Agent.md +0 -196
- package/website/content/docs/getting-started/Hello-World.md +0 -184
- package/website/content/docs/migration-guides/00-INDEX.md +0 -76
- package/website/content/docs/migration-guides/README.md +0 -133
- /package/dist/spec/v0.2.4/{ossa-0.2.4-dev.yaml → ossa-0.2.4.yaml} +0 -0
- /package/spec/v0.2.4/{ossa-0.2.4-dev.yaml → ossa-0.2.4.yaml} +0 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GitLab Issue Creation Helper (Zod Edition)
|
|
5
|
+
*
|
|
6
|
+
* Creates GitLab issues via API with proper validation and error handling.
|
|
7
|
+
* Uses Zod for runtime validation and type safety.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* npx tsx scripts/create-issue-helper.ts <title> <milestone-id> <labels> [description-file]
|
|
11
|
+
*
|
|
12
|
+
* Example:
|
|
13
|
+
* npx tsx scripts/create-issue-helper.ts "Enhance bin" 3 "enhancement,cli,bin" .gitlab/ISSUE-BIN-ENHANCEMENT.md
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import fs from 'fs';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
19
|
+
import { z } from 'zod';
|
|
20
|
+
|
|
21
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
+
const __dirname = path.dirname(__filename);
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Zod Schemas
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
const ConfigSchema = z.object({
|
|
29
|
+
gitlabApiUrl: z.string().url(),
|
|
30
|
+
gitlabToken: z.string().min(1, 'GitLab token is required'),
|
|
31
|
+
projectId: z.string().min(1, 'Project ID is required'),
|
|
32
|
+
title: z.string().min(1, 'Title is required'),
|
|
33
|
+
milestoneId: z.number().int().positive('Milestone ID must be a positive integer'),
|
|
34
|
+
labels: z.array(z.string().min(1)).min(1, 'At least one label is required'),
|
|
35
|
+
description: z.string().optional(),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const GitLabIssueResponseSchema = z.object({
|
|
39
|
+
iid: z.number(),
|
|
40
|
+
web_url: z.string().url(),
|
|
41
|
+
title: z.string(),
|
|
42
|
+
state: z.string(),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const GitLabErrorResponseSchema = z.object({
|
|
46
|
+
message: z.string().optional(),
|
|
47
|
+
error: z.string().optional(),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
type Config = z.infer<typeof ConfigSchema>;
|
|
51
|
+
type GitLabIssueResponse = z.infer<typeof GitLabIssueResponseSchema>;
|
|
52
|
+
type GitLabErrorResponse = z.infer<typeof GitLabErrorResponseSchema>;
|
|
53
|
+
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// Configuration
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
function getConfig(): Config {
|
|
59
|
+
const args = process.argv.slice(2);
|
|
60
|
+
|
|
61
|
+
if (args.length < 3) {
|
|
62
|
+
console.error('❌ Usage: tsx scripts/create-issue-helper.ts <title> <milestone-id> <labels> [description-file]');
|
|
63
|
+
console.error(' Example: tsx scripts/create-issue-helper.ts "Enhance bin" 3 "enhancement,cli,bin" .gitlab/ISSUE-BIN-ENHANCEMENT.md');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const [title, milestoneIdStr, labelsStr, descFile] = args;
|
|
68
|
+
|
|
69
|
+
// Parse milestone ID
|
|
70
|
+
const milestoneId = parseInt(milestoneIdStr, 10);
|
|
71
|
+
if (isNaN(milestoneId) || milestoneId <= 0) {
|
|
72
|
+
console.error(`❌ Invalid milestone ID: ${milestoneIdStr}`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Parse labels
|
|
77
|
+
const labels = labelsStr.split(',').map(l => l.trim()).filter(l => l.length > 0);
|
|
78
|
+
if (labels.length === 0) {
|
|
79
|
+
console.error(`❌ No valid labels provided: ${labelsStr}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Read description file if provided
|
|
84
|
+
let description: string | undefined;
|
|
85
|
+
if (descFile) {
|
|
86
|
+
const descPath = path.isAbsolute(descFile) ? descFile : path.join(process.cwd(), descFile);
|
|
87
|
+
if (!fs.existsSync(descPath)) {
|
|
88
|
+
console.error(`❌ Description file not found: ${descPath}`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
description = fs.readFileSync(descPath, 'utf-8');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Get GitLab token (try multiple sources)
|
|
95
|
+
const gitlabToken = process.env.SERVICE_ACCOUNT_OSSA_TOKEN ||
|
|
96
|
+
process.env.SERVICE_ACCOUNT_VERSION_MANAGER_TOKEN ||
|
|
97
|
+
process.env.GITLAB_TOKEN ||
|
|
98
|
+
process.env.GITLAB_PUSH_TOKEN ||
|
|
99
|
+
'';
|
|
100
|
+
|
|
101
|
+
if (!gitlabToken) {
|
|
102
|
+
console.error('❌ No GitLab token found. Please set one of:');
|
|
103
|
+
console.error(' - SERVICE_ACCOUNT_OSSA_TOKEN');
|
|
104
|
+
console.error(' - SERVICE_ACCOUNT_VERSION_MANAGER_TOKEN');
|
|
105
|
+
console.error(' - GITLAB_TOKEN');
|
|
106
|
+
console.error(' - GITLAB_PUSH_TOKEN');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Get project ID
|
|
111
|
+
const projectId = process.env.CI_PROJECT_ID ||
|
|
112
|
+
process.env.GITLAB_PROJECT_ID ||
|
|
113
|
+
'blueflyio/openstandardagents';
|
|
114
|
+
|
|
115
|
+
// Get API URL
|
|
116
|
+
const gitlabApiUrl = process.env.CI_API_V4_URL ||
|
|
117
|
+
process.env.GITLAB_API_URL ||
|
|
118
|
+
'https://gitlab.com/api/v4';
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
return ConfigSchema.parse({
|
|
122
|
+
gitlabApiUrl,
|
|
123
|
+
gitlabToken,
|
|
124
|
+
projectId,
|
|
125
|
+
title,
|
|
126
|
+
milestoneId,
|
|
127
|
+
labels,
|
|
128
|
+
description,
|
|
129
|
+
});
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (error instanceof z.ZodError) {
|
|
132
|
+
console.error('❌ Configuration validation failed:');
|
|
133
|
+
error.issues.forEach((issue) => {
|
|
134
|
+
console.error(` • ${issue.path.join('.')}: ${issue.message}`);
|
|
135
|
+
});
|
|
136
|
+
} else {
|
|
137
|
+
console.error('❌ Configuration error:', error instanceof Error ? error.message : String(error));
|
|
138
|
+
}
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// ============================================================================
|
|
144
|
+
// GitLab API
|
|
145
|
+
// ============================================================================
|
|
146
|
+
|
|
147
|
+
async function createIssue(config: Config): Promise<GitLabIssueResponse> {
|
|
148
|
+
const projectPath = encodeURIComponent(config.projectId);
|
|
149
|
+
const url = `${config.gitlabApiUrl}/projects/${projectPath}/issues`;
|
|
150
|
+
|
|
151
|
+
const payload = {
|
|
152
|
+
title: config.title,
|
|
153
|
+
description: config.description || '',
|
|
154
|
+
milestone_id: config.milestoneId,
|
|
155
|
+
labels: config.labels.join(','),
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
const response = await fetch(url, {
|
|
160
|
+
method: 'POST',
|
|
161
|
+
headers: {
|
|
162
|
+
'PRIVATE-TOKEN': config.gitlabToken,
|
|
163
|
+
'Content-Type': 'application/json',
|
|
164
|
+
},
|
|
165
|
+
body: JSON.stringify(payload),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const responseText = await response.text();
|
|
169
|
+
let responseData: unknown;
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
responseData = JSON.parse(responseText);
|
|
173
|
+
} catch {
|
|
174
|
+
responseData = responseText;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
// Try to parse as error response
|
|
179
|
+
const errorData = GitLabErrorResponseSchema.safeParse(responseData);
|
|
180
|
+
if (errorData.success) {
|
|
181
|
+
const error = errorData.data;
|
|
182
|
+
throw new Error(`GitLab API error: ${error.message || error.error || responseText}`);
|
|
183
|
+
}
|
|
184
|
+
throw new Error(`GitLab API error (HTTP ${response.status}): ${responseText}`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Validate response
|
|
188
|
+
const issue = GitLabIssueResponseSchema.parse(responseData);
|
|
189
|
+
return issue;
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (error instanceof z.ZodError) {
|
|
192
|
+
console.error('❌ Invalid response from GitLab API:');
|
|
193
|
+
error.issues.forEach((issue) => {
|
|
194
|
+
console.error(` • ${issue.path.join('.')}: ${issue.message}`);
|
|
195
|
+
});
|
|
196
|
+
throw new Error('Failed to parse GitLab API response');
|
|
197
|
+
}
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ============================================================================
|
|
203
|
+
// Main
|
|
204
|
+
// ============================================================================
|
|
205
|
+
|
|
206
|
+
async function main(): Promise<void> {
|
|
207
|
+
console.log('🔧 GitLab Issue Creation Helper (Zod Edition)');
|
|
208
|
+
console.log('==============================================\n');
|
|
209
|
+
|
|
210
|
+
const config = getConfig();
|
|
211
|
+
|
|
212
|
+
console.log(`📋 Configuration:`);
|
|
213
|
+
console.log(` Project: ${config.projectId}`);
|
|
214
|
+
console.log(` Title: ${config.title}`);
|
|
215
|
+
console.log(` Milestone: #${config.milestoneId}`);
|
|
216
|
+
console.log(` Labels: ${config.labels.join(', ')}`);
|
|
217
|
+
console.log(` Description: ${config.description ? `${config.description.length} chars` : 'none'}`);
|
|
218
|
+
console.log('');
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
const issue = await createIssue(config);
|
|
222
|
+
|
|
223
|
+
console.log('✅ Issue created successfully!');
|
|
224
|
+
console.log(` Issue: !${issue.iid}`);
|
|
225
|
+
console.log(` URL: ${issue.web_url}`);
|
|
226
|
+
console.log(` State: ${issue.state}`);
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error('❌ Failed to create issue:', error instanceof Error ? error.message : String(error));
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Run
|
|
234
|
+
main().catch((error) => {
|
|
235
|
+
console.error('❌ Fatal error:', error instanceof Error ? error.message : String(error));
|
|
236
|
+
process.exit(1);
|
|
237
|
+
});
|
|
238
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create GitLab Issue for Milestone
|
|
5
|
+
* Quick script to create issues via GitLab API
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
|
|
10
|
+
const GITLAB_API_URL = process.env.CI_API_V4_URL || 'https://gitlab.com/api/v4';
|
|
11
|
+
const GITLAB_TOKEN = process.env.SERVICE_ACCOUNT_OSSA_TOKEN ||
|
|
12
|
+
process.env.GITLAB_TOKEN ||
|
|
13
|
+
process.env.GITLAB_PUSH_TOKEN || '';
|
|
14
|
+
const PROJECT_ID = process.env.CI_PROJECT_ID || 'blueflyio/openstandardagents';
|
|
15
|
+
|
|
16
|
+
async function createIssue(
|
|
17
|
+
title: string,
|
|
18
|
+
description: string,
|
|
19
|
+
milestoneId: number,
|
|
20
|
+
labels: string[] = []
|
|
21
|
+
) {
|
|
22
|
+
if (!GITLAB_TOKEN) {
|
|
23
|
+
console.error('❌ GITLAB_TOKEN or SERVICE_ACCOUNT_OSSA_TOKEN required');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const projectPath = encodeURIComponent(PROJECT_ID);
|
|
28
|
+
const url = `${GITLAB_API_URL}/projects/${projectPath}/issues`;
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const response = await fetch(url, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'PRIVATE-TOKEN': GITLAB_TOKEN,
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify({
|
|
38
|
+
title,
|
|
39
|
+
description,
|
|
40
|
+
milestone_id: milestoneId,
|
|
41
|
+
labels: labels.join(','),
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
const error = await response.text();
|
|
47
|
+
throw new Error(`Failed to create issue: ${error}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const issue = await response.json();
|
|
51
|
+
console.log(`✅ Issue created: !${issue.iid}`);
|
|
52
|
+
console.log(` URL: ${issue.web_url}`);
|
|
53
|
+
return issue.iid;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('❌ Error creating issue:', error);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Main
|
|
61
|
+
const args = process.argv.slice(2);
|
|
62
|
+
if (args.length < 3) {
|
|
63
|
+
console.log('Usage: tsx scripts/create-milestone-issue.ts <title> <milestone-id> <labels> [description-file]');
|
|
64
|
+
console.log('Example: tsx scripts/create-milestone-issue.ts "Enhance bin" 3 "enhancement,cli"');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const [title, milestoneId, labelsStr, descFile] = args;
|
|
69
|
+
const labels = labelsStr.split(',').map(l => l.trim());
|
|
70
|
+
const description = descFile && readFileSync(descFile, 'utf-8') || '';
|
|
71
|
+
|
|
72
|
+
createIssue(title, description, parseInt(milestoneId), labels);
|
|
73
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fix unsupported format constraints in JSON schemas
|
|
5
|
+
* Removes format constraints that aren't supported by ajv-cli
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const UNSUPPORTED_FORMATS = ['uri'];
|
|
12
|
+
const SPEC_DIR = path.join(__dirname, '..', 'spec');
|
|
13
|
+
|
|
14
|
+
function fixSchema(schemaPath) {
|
|
15
|
+
const content = fs.readFileSync(schemaPath, 'utf8');
|
|
16
|
+
const schema = JSON.parse(content);
|
|
17
|
+
|
|
18
|
+
let fixed = false;
|
|
19
|
+
|
|
20
|
+
function walk(obj) {
|
|
21
|
+
if (typeof obj !== 'object' || obj === null) return;
|
|
22
|
+
|
|
23
|
+
if (obj.format && UNSUPPORTED_FORMATS.includes(obj.format)) {
|
|
24
|
+
delete obj.format;
|
|
25
|
+
fixed = true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (const key in obj) {
|
|
29
|
+
walk(obj[key]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
walk(schema);
|
|
34
|
+
|
|
35
|
+
if (fixed) {
|
|
36
|
+
fs.writeFileSync(schemaPath, JSON.stringify(schema, null, 2) + '\n');
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function findSchemas(dir) {
|
|
44
|
+
const schemas = [];
|
|
45
|
+
|
|
46
|
+
function scan(currentDir) {
|
|
47
|
+
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
48
|
+
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
51
|
+
|
|
52
|
+
if (entry.isDirectory()) {
|
|
53
|
+
scan(fullPath);
|
|
54
|
+
} else if (entry.name.endsWith('.schema.json')) {
|
|
55
|
+
schemas.push(fullPath);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
scan(dir);
|
|
61
|
+
return schemas;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log('🔧 Fixing schema format constraints...\n');
|
|
65
|
+
|
|
66
|
+
const schemas = findSchemas(SPEC_DIR);
|
|
67
|
+
let fixedCount = 0;
|
|
68
|
+
|
|
69
|
+
for (const schemaPath of schemas) {
|
|
70
|
+
const relative = path.relative(process.cwd(), schemaPath);
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
if (fixSchema(schemaPath)) {
|
|
74
|
+
console.log(`✓ Fixed: ${relative}`);
|
|
75
|
+
fixedCount++;
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.error(`✗ Error in ${relative}: ${err.message}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.log(`\n${fixedCount} schema(s) fixed`);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { readdirSync, readFileSync, writeFileSync, statSync, mkdirSync } from 'fs';
|
|
3
|
+
import { join, relative } from 'path';
|
|
4
|
+
import yaml from 'js-yaml';
|
|
5
|
+
|
|
6
|
+
const AGENTS_DIR = join(process.cwd(), '.gitlab/agents');
|
|
7
|
+
const OUTPUT_FILE = join(process.cwd(), 'website/content/docs/agents/catalog.md');
|
|
8
|
+
|
|
9
|
+
interface Agent {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
role: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
capabilities: Array<{ name: string; description: string }>;
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function findAgents(): Agent[] {
|
|
19
|
+
const agents: Agent[] = [];
|
|
20
|
+
const entries = readdirSync(AGENTS_DIR);
|
|
21
|
+
|
|
22
|
+
for (const entry of entries) {
|
|
23
|
+
const manifestPath = join(AGENTS_DIR, entry, 'manifest.ossa.yaml');
|
|
24
|
+
try {
|
|
25
|
+
const content = readFileSync(manifestPath, 'utf-8');
|
|
26
|
+
const data = yaml.load(content) as any;
|
|
27
|
+
|
|
28
|
+
if (data?.agent) {
|
|
29
|
+
agents.push({
|
|
30
|
+
id: data.agent.id,
|
|
31
|
+
name: data.agent.name,
|
|
32
|
+
role: data.agent.role,
|
|
33
|
+
description: data.agent.description,
|
|
34
|
+
capabilities: data.agent.capabilities || [],
|
|
35
|
+
path: relative(process.cwd(), manifestPath)
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
} catch (error) {
|
|
39
|
+
// Skip if no manifest
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return agents;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const agents = findAgents();
|
|
47
|
+
|
|
48
|
+
let doc = `# GitLab Agents Catalog
|
|
49
|
+
|
|
50
|
+
OSSA-compliant agents for GitLab CI/CD automation.
|
|
51
|
+
|
|
52
|
+
**Total Agents**: ${agents.length}
|
|
53
|
+
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
for (const agent of agents.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
57
|
+
doc += `## ${agent.name}\n\n`;
|
|
58
|
+
doc += `**ID**: \`${agent.id}\` \n`;
|
|
59
|
+
doc += `**Role**: \`${agent.role}\`\n\n`;
|
|
60
|
+
if (agent.description) doc += `${agent.description}\n\n`;
|
|
61
|
+
|
|
62
|
+
if (agent.capabilities.length > 0) {
|
|
63
|
+
doc += `### Capabilities\n\n`;
|
|
64
|
+
for (const cap of agent.capabilities) {
|
|
65
|
+
doc += `- **${cap.name}**: ${cap.description}\n`;
|
|
66
|
+
}
|
|
67
|
+
doc += '\n';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
doc += `**Manifest**: [\`${agent.path}\`](https://github.com/blueflyio/openstandardagents/blob/main/${agent.path})\n\n`;
|
|
71
|
+
doc += `\`\`\`bash\n# Deploy agent\nkubectl apply -f ${agent.path}\n\`\`\`\n\n`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
mkdirSync(join(process.cwd(), 'website/content/docs/agents'), { recursive: true });
|
|
75
|
+
writeFileSync(OUTPUT_FILE, doc);
|
|
76
|
+
|
|
77
|
+
console.log(`✅ Generated agents catalog: ${agents.length} agents`);
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Generate API documentation from OpenAPI specifications
|
|
4
|
+
*
|
|
5
|
+
* Usage: npm run docs:api:generate
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
|
|
9
|
+
import { join, basename } from 'path';
|
|
10
|
+
import yaml from 'js-yaml';
|
|
11
|
+
|
|
12
|
+
interface OpenAPISpec {
|
|
13
|
+
openapi: string;
|
|
14
|
+
info: {
|
|
15
|
+
title: string;
|
|
16
|
+
version: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
};
|
|
19
|
+
servers?: Array<{ url: string; description?: string }>;
|
|
20
|
+
paths: Record<string, Record<string, any>>;
|
|
21
|
+
components?: {
|
|
22
|
+
schemas?: Record<string, any>;
|
|
23
|
+
securitySchemes?: Record<string, any>;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const OPENAPI_DIR = join(process.cwd(), 'openapi');
|
|
28
|
+
const OUTPUT_DIR = join(process.cwd(), 'website/content/docs/api-reference');
|
|
29
|
+
|
|
30
|
+
function generateEndpointDoc(path: string, method: string, operation: any): string {
|
|
31
|
+
const methodUpper = method.toUpperCase();
|
|
32
|
+
let doc = `### ${operation.summary || `${methodUpper} ${path}`}\n\n`;
|
|
33
|
+
|
|
34
|
+
doc += '```http\n';
|
|
35
|
+
doc += `${methodUpper} ${path}\n`;
|
|
36
|
+
doc += '```\n\n';
|
|
37
|
+
|
|
38
|
+
if (operation.description) {
|
|
39
|
+
doc += `**Description**: ${operation.description}\n\n`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Parameters
|
|
43
|
+
if (operation.parameters && operation.parameters.length > 0) {
|
|
44
|
+
doc += '**Parameters**:\n\n';
|
|
45
|
+
for (const param of operation.parameters) {
|
|
46
|
+
const required = param.required ? ', required' : '';
|
|
47
|
+
doc += `- \`${param.name}\` (${param.in}${required}) - ${param.description || 'No description'}\n`;
|
|
48
|
+
}
|
|
49
|
+
doc += '\n';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Request body
|
|
53
|
+
if (operation.requestBody) {
|
|
54
|
+
doc += '**Request Body**:\n\n';
|
|
55
|
+
const content = operation.requestBody.content;
|
|
56
|
+
if (content && content['application/json']) {
|
|
57
|
+
doc += '```json\n';
|
|
58
|
+
doc += JSON.stringify(content['application/json'].example || {}, null, 2);
|
|
59
|
+
doc += '\n```\n\n';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Responses
|
|
64
|
+
if (operation.responses) {
|
|
65
|
+
doc += '**Responses**:\n\n';
|
|
66
|
+
for (const [code, response] of Object.entries(operation.responses)) {
|
|
67
|
+
doc += `**${code}**: ${(response as any).description}\n\n`;
|
|
68
|
+
const content = (response as any).content;
|
|
69
|
+
if (content && content['application/json']) {
|
|
70
|
+
doc += '```json\n';
|
|
71
|
+
doc += JSON.stringify(content['application/json'].example || {}, null, 2);
|
|
72
|
+
doc += '\n```\n\n';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Example
|
|
78
|
+
doc += '**Example**:\n\n';
|
|
79
|
+
doc += '```bash\n';
|
|
80
|
+
doc += `curl -X ${methodUpper} "https://api.ossa.dev${path}" \\\n`;
|
|
81
|
+
doc += ' -H "Authorization: Bearer YOUR_TOKEN"';
|
|
82
|
+
if (operation.requestBody) {
|
|
83
|
+
doc += ' \\\n -H "Content-Type: application/json" \\\n -d @request.json';
|
|
84
|
+
}
|
|
85
|
+
doc += '\n```\n\n';
|
|
86
|
+
|
|
87
|
+
return doc;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function generateAPIDoc(spec: OpenAPISpec, filename: string): string {
|
|
91
|
+
const apiName = spec.info.title;
|
|
92
|
+
const apiVersion = spec.info.version;
|
|
93
|
+
|
|
94
|
+
let doc = `# ${apiName}\n\n`;
|
|
95
|
+
doc += `**Version**: ${apiVersion}\n\n`;
|
|
96
|
+
|
|
97
|
+
if (spec.info.description) {
|
|
98
|
+
doc += `${spec.info.description}\n\n`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
doc += '## Base URL\n\n';
|
|
102
|
+
if (spec.servers && spec.servers.length > 0) {
|
|
103
|
+
for (const server of spec.servers) {
|
|
104
|
+
doc += `- \`${server.url}\``;
|
|
105
|
+
if (server.description) {
|
|
106
|
+
doc += ` - ${server.description}`;
|
|
107
|
+
}
|
|
108
|
+
doc += '\n';
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
doc += '`https://api.ossa.dev`\n';
|
|
112
|
+
}
|
|
113
|
+
doc += '\n';
|
|
114
|
+
|
|
115
|
+
// Authentication
|
|
116
|
+
if (spec.components?.securitySchemes) {
|
|
117
|
+
doc += '## Authentication\n\n';
|
|
118
|
+
doc += 'This API requires authentication. See [Authentication Guide](../authentication.md) for details.\n\n';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Endpoints
|
|
122
|
+
doc += '## Endpoints\n\n';
|
|
123
|
+
|
|
124
|
+
for (const [path, methods] of Object.entries(spec.paths)) {
|
|
125
|
+
for (const [method, operation] of Object.entries(methods)) {
|
|
126
|
+
if (['get', 'post', 'put', 'patch', 'delete'].includes(method)) {
|
|
127
|
+
doc += generateEndpointDoc(path, method, operation);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Related documentation
|
|
133
|
+
doc += '## Related Documentation\n\n';
|
|
134
|
+
doc += '- [CLI Reference](../cli-reference/index.md)\n';
|
|
135
|
+
doc += '- [Schema Reference](../schema-reference/index.md)\n';
|
|
136
|
+
doc += '- [Authentication Guide](../authentication.md)\n';
|
|
137
|
+
|
|
138
|
+
return doc;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function main() {
|
|
142
|
+
console.log('🚀 Generating API documentation...\n');
|
|
143
|
+
|
|
144
|
+
// Create output directory
|
|
145
|
+
mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
146
|
+
|
|
147
|
+
// Process core APIs
|
|
148
|
+
const coreDir = join(OPENAPI_DIR, 'core');
|
|
149
|
+
const coreFiles = readdirSync(coreDir).filter(f => f.endsWith('.yaml'));
|
|
150
|
+
|
|
151
|
+
console.log(`📁 Processing ${coreFiles.length} core API specs...\n`);
|
|
152
|
+
|
|
153
|
+
for (const file of coreFiles) {
|
|
154
|
+
try {
|
|
155
|
+
const specPath = join(coreDir, file);
|
|
156
|
+
const specContent = readFileSync(specPath, 'utf-8');
|
|
157
|
+
const spec = yaml.load(specContent) as OpenAPISpec;
|
|
158
|
+
|
|
159
|
+
const docContent = generateAPIDoc(spec, file);
|
|
160
|
+
const outputFile = join(OUTPUT_DIR, file.replace('.openapi.yaml', '.md'));
|
|
161
|
+
|
|
162
|
+
writeFileSync(outputFile, docContent);
|
|
163
|
+
console.log(`✅ Generated: ${basename(outputFile)}`);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.log(`⚠️ Skipped: ${file} (${(error as Error).message})`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Generate index
|
|
170
|
+
const indexContent = `# API Reference
|
|
171
|
+
|
|
172
|
+
Welcome to the OSSA API Reference documentation.
|
|
173
|
+
|
|
174
|
+
## Core APIs
|
|
175
|
+
|
|
176
|
+
${coreFiles.map(f => {
|
|
177
|
+
const name = f.replace('.openapi.yaml', '').replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
178
|
+
const link = f.replace('.openapi.yaml', '.md');
|
|
179
|
+
return `- [${name}](${link})`;
|
|
180
|
+
}).join('\n')}
|
|
181
|
+
|
|
182
|
+
## Authentication
|
|
183
|
+
|
|
184
|
+
All API endpoints require authentication. See the [Authentication Guide](./authentication.md) for details.
|
|
185
|
+
|
|
186
|
+
## Rate Limiting
|
|
187
|
+
|
|
188
|
+
- 100 requests per minute per API key
|
|
189
|
+
- 1000 requests per hour per API key
|
|
190
|
+
|
|
191
|
+
## Error Responses
|
|
192
|
+
|
|
193
|
+
All APIs use standard HTTP status codes and return errors in the following format:
|
|
194
|
+
|
|
195
|
+
\`\`\`json
|
|
196
|
+
{
|
|
197
|
+
"error": "error_code",
|
|
198
|
+
"message": "Human-readable error message",
|
|
199
|
+
"details": []
|
|
200
|
+
}
|
|
201
|
+
\`\`\`
|
|
202
|
+
|
|
203
|
+
## Support
|
|
204
|
+
|
|
205
|
+
For API support, please:
|
|
206
|
+
- Check the [Troubleshooting Guide](../guides/troubleshooting.md)
|
|
207
|
+
- Open an issue on [GitLab](https://gitlab.com/blueflyio/openstandardagents/-/issues)
|
|
208
|
+
- Join our [Discord community](https://discord.gg/ossa)
|
|
209
|
+
`;
|
|
210
|
+
|
|
211
|
+
writeFileSync(join(OUTPUT_DIR, 'index.md'), indexContent);
|
|
212
|
+
console.log(`✅ Generated: index.md`);
|
|
213
|
+
|
|
214
|
+
console.log(`\n✨ API documentation generated successfully!`);
|
|
215
|
+
console.log(`📂 Output: ${OUTPUT_DIR}`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
main();
|