@bluefly/openstandardagents 0.2.7 → 0.2.9

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 (327) hide show
  1. package/.devfile.yaml +1 -1
  2. package/.env.example +1 -1
  3. package/.github/AGENTS.md +245 -0
  4. package/.github/agents/github-issue-triage.ossa.yaml +99 -0
  5. package/.github/agents/github-pr-triage.ossa.yaml +137 -0
  6. package/.github/workflows/issue-sync-to-gitlab.yml +138 -0
  7. package/.github/workflows/pr-triage-to-gitlab.yml +164 -0
  8. package/.version.json +2 -2
  9. package/.wiki-config.json +24 -0
  10. package/CHANGELOG.md +44 -18
  11. package/CODEOWNERS +75 -0
  12. package/CONTRIBUTING.md +103 -4
  13. package/README.md +178 -243
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/repositories/schema.repository.d.ts +6 -1
  19. package/dist/repositories/schema.repository.d.ts.map +1 -1
  20. package/dist/repositories/schema.repository.js +49 -27
  21. package/dist/repositories/schema.repository.js.map +1 -1
  22. package/dist/services/migration.service.d.ts +4 -3
  23. package/dist/services/migration.service.d.ts.map +1 -1
  24. package/dist/services/migration.service.js +11 -10
  25. package/dist/services/migration.service.js.map +1 -1
  26. package/dist/services/release-automation/release.service.js +1 -1
  27. package/dist/services/release-automation/release.service.js.map +1 -1
  28. package/dist/services/release-automation/schemas/release.schema.js +1 -1
  29. package/dist/services/release-automation/webhook.service.js +3 -3
  30. package/dist/services/release-automation/webhook.service.js.map +1 -1
  31. package/dist/services/runtime/claude/claude-adapter.d.ts +1 -1
  32. package/dist/services/runtime/claude/claude-adapter.d.ts.map +1 -1
  33. package/dist/services/runtime/claude/claude-adapter.js +2 -2
  34. package/dist/services/runtime/claude/claude-adapter.js.map +1 -1
  35. package/dist/spec/v0.2.8/CHANGELOG.md +401 -0
  36. package/dist/spec/v0.2.8/README.md +72 -0
  37. package/dist/spec/v0.2.8/migrations/v0.2.3-to-v0.2.4.md +599 -0
  38. package/dist/spec/v0.2.8/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
  39. package/dist/spec/v0.2.8/migrations/v0.2.6-to-v0.2.8.md +81 -0
  40. package/{spec/v0.2.6-dev/ossa-0.2.5.schema.json → dist/spec/v0.2.8/ossa-0.2.8.schema.json} +1509 -52
  41. package/dist/spec/v0.2.8/ossa-0.2.8.yaml +581 -0
  42. package/dist/spec/v0.2.9/a2a-protocol.md +1337 -0
  43. package/dist/spec/v0.2.9/agent.md +1946 -0
  44. package/dist/spec/v0.2.9/capabilities/index.yaml +25 -0
  45. package/dist/spec/v0.2.9/capabilities/memory.yaml +251 -0
  46. package/dist/spec/v0.2.9/capability-schema.md +576 -0
  47. package/dist/spec/v0.2.9/compliance-profiles.md +533 -0
  48. package/dist/spec/v0.2.9/conformance-testing.md +1527 -0
  49. package/dist/spec/v0.2.9/gitlab-duo-integration.md +621 -0
  50. package/dist/spec/v0.2.9/ossa-0.2.9.schema.json +3699 -0
  51. package/dist/spec/v0.2.9/runtime-semantics.md +464 -0
  52. package/dist/spec/v0.2.9/security-model.md +1245 -0
  53. package/dist/spec/v0.2.9/semantic-conventions.md +347 -0
  54. package/dist/spec/v0.2.9/types.ts +522 -0
  55. package/dist/types/index.d.ts +3 -2
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/dist/types/policy.d.ts +377 -0
  58. package/dist/types/policy.d.ts.map +1 -0
  59. package/dist/types/policy.js +84 -0
  60. package/dist/types/policy.js.map +1 -0
  61. package/dist/utils/index.d.ts +6 -0
  62. package/dist/utils/index.d.ts.map +1 -0
  63. package/dist/utils/index.js +6 -0
  64. package/dist/utils/index.js.map +1 -0
  65. package/dist/utils/version.d.ts +68 -0
  66. package/dist/utils/version.d.ts.map +1 -0
  67. package/dist/utils/version.js +156 -0
  68. package/dist/utils/version.js.map +1 -0
  69. package/docs/specs/policy-dsl.md +925 -0
  70. package/eslint-report.json +1 -0
  71. package/examples/adk-integration/code-review-workflow.yml +1 -1
  72. package/examples/adk-integration/customer-support.yml +1 -1
  73. package/examples/adk-integration/data-pipeline.yml +1 -1
  74. package/examples/advanced/reasoning-agent.yaml +136 -0
  75. package/examples/advanced/workflows/hybrid-model-strategy.yaml +1 -1
  76. package/examples/agent-manifests/critics/critic-agent.yaml +1 -1
  77. package/examples/agent-manifests/governors/governor-agent.yaml +1 -1
  78. package/examples/agent-manifests/integrators/integrator-agent.yaml +1 -1
  79. package/examples/agent-manifests/judges/judge-agent.yaml +1 -1
  80. package/examples/agent-manifests/monitors/monitor-agent.yaml +1 -1
  81. package/examples/agent-manifests/orchestrators/orchestrator-agent.yaml +1 -1
  82. package/examples/agent-manifests/sample-compliant-agent.yaml +1 -1
  83. package/examples/agent-manifests/workers/worker-agent.yaml +1 -1
  84. package/examples/agents-md/code-agent.ossa.json +100 -0
  85. package/examples/agents-md/monorepo-agent.ossa.yaml +180 -0
  86. package/examples/anthropic/claude-assistant.ossa.json +1 -1
  87. package/examples/autogen/multi-agent.ossa.json +1 -1
  88. package/examples/claude-code/code-reviewer.ossa.yaml +78 -0
  89. package/examples/claude-code/ossa-validator.ossa.yaml +80 -0
  90. package/examples/common_npm/agent-router.ossa.yaml +1 -0
  91. package/examples/common_npm/agent-router.v0.2.2.ossa.yaml +1 -1
  92. package/examples/crewai/research-team.ossa.json +1 -1
  93. package/examples/cursor/code-review-agent.ossa.json +1 -1
  94. package/examples/drupal/gitlab-ml-recommender.ossa.yaml +1 -0
  95. package/examples/drupal/gitlab-ml-recommender.v0.2.2.ossa.yaml +1 -1
  96. package/examples/extensions/agents-md-v1.yml +175 -0
  97. package/examples/extensions/drupal-v1.yml +1 -1
  98. package/examples/extensions/kagent-v1.yml +1 -1
  99. package/examples/getting-started/hello-world-complete.ossa.yaml +1 -1
  100. package/examples/integration-patterns/agent-to-agent-orchestration.ossa.yaml +4 -4
  101. package/examples/kagent/compliance-validator.ossa.yaml +1 -1
  102. package/examples/kagent/cost-optimizer.ossa.yaml +1 -1
  103. package/examples/kagent/documentation-agent.ossa.yaml +1 -1
  104. package/examples/kagent/k8s-troubleshooter-v1.ossa.yaml +1 -0
  105. package/examples/kagent/k8s-troubleshooter-v1.v0.2.2.ossa.yaml +1 -1
  106. package/examples/kagent/k8s-troubleshooter.ossa.yaml +1 -1
  107. package/examples/kagent/security-scanner.ossa.yaml +1 -1
  108. package/examples/langchain/chain-agent.ossa.json +1 -1
  109. package/examples/langflow/workflow-agent.ossa.json +1 -1
  110. package/examples/langgraph/state-machine-agent.ossa.json +1 -1
  111. package/examples/llamaindex/rag-agent.ossa.json +1 -1
  112. package/examples/migration-guides/from-langchain-to-ossa.yaml +4 -4
  113. package/examples/multi-agent/README.md +74 -0
  114. package/examples/multi-agent/conditional-router.ossa.yaml +42 -0
  115. package/examples/multi-agent/parallel-execution.ossa.yaml +54 -0
  116. package/examples/multi-agent/sequential-pipeline.ossa.yaml +45 -0
  117. package/examples/openai/basic-agent.ossa.yaml +1 -1
  118. package/examples/openai/multi-tool-agent.ossa.json +1 -1
  119. package/examples/openai/swarm-agent.ossa.json +1 -1
  120. package/examples/production/document-analyzer-openai.yml +1 -1
  121. package/examples/quickstart/support-agent.ossa.yaml +1 -1
  122. package/examples/spec-examples/audit-agent.yml +1 -1
  123. package/examples/spec-examples/chat-agent.yml +1 -1
  124. package/examples/spec-examples/compliance-agent.yml +1 -1
  125. package/examples/spec-examples/monitoring-agent.yml +1 -1
  126. package/examples/spec-examples/workflow-agent.yml +1 -1
  127. package/examples/templates/ossa-compliance.yaml +1 -1
  128. package/examples/vercel/edge-agent.ossa.json +1 -1
  129. package/gl-code-quality-report.json +62 -0
  130. package/llms-ctx-full.txt +39 -0
  131. package/llms-ctx.txt +39 -0
  132. package/llms.txt +47 -0
  133. package/package.json +6 -3
  134. package/scripts/README.md +25 -0
  135. package/scripts/compliance-audit.ts +796 -0
  136. package/scripts/eslint-to-codequality.cjs +34 -0
  137. package/scripts/generate-agents-catalog.ts +2 -1
  138. package/scripts/generate-api-docs.ts +2 -1
  139. package/scripts/generate-examples-docs.ts +2 -1
  140. package/scripts/generate-llms-ctx.sh +17 -0
  141. package/scripts/generate-schema-docs.ts +31 -10
  142. package/scripts/sync-version.js +4 -12
  143. package/scripts/validate-schema.ts +2 -1
  144. package/spec/v0.2.8/CHANGELOG.md +401 -0
  145. package/spec/v0.2.8/README.md +72 -0
  146. package/spec/v0.2.8/migrations/v0.2.3-to-v0.2.4.md +599 -0
  147. package/spec/v0.2.8/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
  148. package/spec/v0.2.8/migrations/v0.2.6-to-v0.2.8.md +81 -0
  149. package/spec/{v0.2.6-dev/ossa-0.2.6-dev.schema.json → v0.2.8/ossa-0.2.8.schema.json} +1509 -52
  150. package/spec/v0.2.8/ossa-0.2.8.yaml +581 -0
  151. package/spec/v0.2.9/a2a-protocol.md +1337 -0
  152. package/spec/v0.2.9/agent.md +1946 -0
  153. package/spec/v0.2.9/capabilities/index.yaml +25 -0
  154. package/spec/v0.2.9/capabilities/memory.yaml +251 -0
  155. package/spec/v0.2.9/capability-schema.md +576 -0
  156. package/spec/v0.2.9/compliance-profiles.md +533 -0
  157. package/spec/v0.2.9/conformance-testing.md +1527 -0
  158. package/spec/v0.2.9/gitlab-duo-integration.md +621 -0
  159. package/spec/v0.2.9/ossa-0.2.9.schema.json +3699 -0
  160. package/spec/v0.2.9/runtime-semantics.md +464 -0
  161. package/spec/v0.2.9/security-model.md +1245 -0
  162. package/spec/v0.2.9/semantic-conventions.md +347 -0
  163. package/spec/v0.2.9/types.ts +522 -0
  164. package/test-results/junit.xml +337 -0
  165. package/.github/workflows/pr-comment.yml +0 -33
  166. package/bin/validate-ossa-0.2.5-RC.ts +0 -244
  167. package/dist/spec/v0.2.6-dev/ossa-0.2.5.schema.json +0 -1696
  168. package/dist/spec/v0.2.6-dev/ossa-0.2.6-dev.schema.json +0 -1696
  169. package/scripts/lib/exec.ts +0 -37
  170. package/scripts/lib/file-ops.ts +0 -58
  171. package/scripts/lib/version.ts +0 -83
  172. package/website/.lighthouserc.ts +0 -24
  173. package/website/.prettierrc +0 -10
  174. package/website/DESIGN_SYSTEM_IMPLEMENTATION.md +0 -445
  175. package/website/Dockerfile +0 -30
  176. package/website/app/about/page.tsx +0 -304
  177. package/website/app/blog/[slug]/page.tsx +0 -208
  178. package/website/app/blog/page.tsx +0 -249
  179. package/website/app/design-guide/page.tsx +0 -511
  180. package/website/app/docs/[[...slug]]/page.tsx +0 -847
  181. package/website/app/docs/core-concepts/project-structure/page.tsx +0 -349
  182. package/website/app/ecosystem/page.tsx +0 -410
  183. package/website/app/examples/page.tsx +0 -133
  184. package/website/app/globals.scss +0 -370
  185. package/website/app/layout.tsx +0 -106
  186. package/website/app/license/page.tsx +0 -183
  187. package/website/app/not-found.tsx +0 -18
  188. package/website/app/page.tsx +0 -686
  189. package/website/app/page.tsx.bak +0 -679
  190. package/website/app/page.tsx.bak2 +0 -649
  191. package/website/app/playground/page.tsx +0 -487
  192. package/website/app/robots.ts +0 -19
  193. package/website/app/rss.xml/route.ts +0 -74
  194. package/website/app/schema/page.tsx +0 -1001
  195. package/website/app/sitemap.ts +0 -56
  196. package/website/app/specification/page.tsx +0 -287
  197. package/website/components/InstallCommand.tsx +0 -96
  198. package/website/components/Logo.tsx +0 -97
  199. package/website/components/StructuredData.tsx +0 -65
  200. package/website/components/docs/DocsSearch.tsx +0 -104
  201. package/website/components/docs/DocsSidebar.tsx +0 -155
  202. package/website/components/docs/MarkdownContent.tsx +0 -401
  203. package/website/components/docs/VersionSelector.tsx +0 -105
  204. package/website/components/examples/ExamplesViewer.tsx +0 -293
  205. package/website/components/layout/Footer.tsx +0 -116
  206. package/website/components/layout/Header.tsx +0 -172
  207. package/website/components/schema/SchemaComponentsAccordion.tsx +0 -84
  208. package/website/components/schema/SchemaExplorer.tsx +0 -213
  209. package/website/components/ui/Badge.tsx +0 -82
  210. package/website/components/ui/Button.tsx +0 -116
  211. package/website/components/ui/Card.tsx +0 -167
  212. package/website/components/ui/Checkbox.tsx +0 -141
  213. package/website/components/ui/Input.tsx +0 -169
  214. package/website/components/ui/Radio.tsx +0 -141
  215. package/website/components/ui/Select.tsx +0 -182
  216. package/website/components/ui/Tag.tsx +0 -158
  217. package/website/components/ui/Textarea.tsx +0 -195
  218. package/website/components/ui/index.ts +0 -11
  219. package/website/content/blog/OpenAPI-AI-Agents-Standard.md +0 -285
  220. package/website/content/blog/Why-Formal-Standards-Matter-Now.md +0 -198
  221. package/website/content/blog/gitlab-kubernetes-agent-ecosystem.md +0 -286
  222. package/website/content/blog/introducing-ossa-framework.md +0 -328
  223. package/website/content/blog/ossa-production-results.md +0 -279
  224. package/website/content/blog/welcome-to-ossa.md +0 -43
  225. package/website/content/blog/why-ai-agents-need-open-standard.md +0 -98
  226. package/website/content/docs/00-home.md +0 -153
  227. package/website/content/docs/adapters/openai-adapter.md +0 -693
  228. package/website/content/docs/agents/catalog.md +0 -28
  229. package/website/content/docs/aiflow-framework-integration-with-ossa.md +0 -107
  230. package/website/content/docs/api-reference/index.md +0 -38
  231. package/website/content/docs/api-reference/ossa-core-api.md +0 -634
  232. package/website/content/docs/api-reference/ossa-registry-api.md +0 -515
  233. package/website/content/docs/api-reference/unified-agent-gateway.md +0 -599
  234. package/website/content/docs/architecture/execution-flow.md +0 -335
  235. package/website/content/docs/architecture/multi-agent-systems.md +0 -737
  236. package/website/content/docs/architecture/overview.md +0 -121
  237. package/website/content/docs/architecture/stack-integration.md +0 -461
  238. package/website/content/docs/changelog.md +0 -246
  239. package/website/content/docs/cli-reference/index.md +0 -111
  240. package/website/content/docs/cli-reference/ossa-agents.md +0 -70
  241. package/website/content/docs/cli-reference/ossa-export.md +0 -56
  242. package/website/content/docs/cli-reference/ossa-generate.md +0 -66
  243. package/website/content/docs/cli-reference/ossa-gitlab-agent.md +0 -57
  244. package/website/content/docs/cli-reference/ossa-import.md +0 -56
  245. package/website/content/docs/cli-reference/ossa-init.md +0 -57
  246. package/website/content/docs/cli-reference/ossa-migrate.md +0 -62
  247. package/website/content/docs/cli-reference/ossa-run.md +0 -66
  248. package/website/content/docs/cli-reference/ossa-schema.md +0 -57
  249. package/website/content/docs/cli-reference/ossa-setup.md +0 -57
  250. package/website/content/docs/cli-reference/ossa-validate.md +0 -66
  251. package/website/content/docs/configuration/index.md +0 -97
  252. package/website/content/docs/contributing.md +0 -599
  253. package/website/content/docs/deployment/github-mirroring.md +0 -924
  254. package/website/content/docs/documentation.md +0 -100
  255. package/website/content/docs/ecosystem/framework-support.md +0 -1361
  256. package/website/content/docs/ecosystem/overview.md +0 -366
  257. package/website/content/docs/errors/index.md +0 -10
  258. package/website/content/docs/examples/aiflow-framework-integration-with-ossa.md +0 -107
  259. package/website/content/docs/examples/catalog.md +0 -300
  260. package/website/content/docs/for-audiences/students-researchers.md +0 -122
  261. package/website/content/docs/getting-started/index.md +0 -92
  262. package/website/content/docs/getting-started/installation.md +0 -155
  263. package/website/content/docs/getting-started/running-agents.md +0 -309
  264. package/website/content/docs/getting-started.md +0 -91
  265. package/website/content/docs/integrations/aiflow.md +0 -104
  266. package/website/content/docs/integrations/drupal.md +0 -105
  267. package/website/content/docs/migration-guides/agent-schema-comparison.md +0 -232
  268. package/website/content/docs/migration-guides/anthropic-mcp-to-ossa.md +0 -1750
  269. package/website/content/docs/migration-guides/crewai-to-ossa.md +0 -274
  270. package/website/content/docs/migration-guides/drupal-eca-to-ossa.md +0 -2017
  271. package/website/content/docs/migration-guides/general-agent-schema.yml +0 -247
  272. package/website/content/docs/migration-guides/index.md +0 -133
  273. package/website/content/docs/migration-guides/langchain-to-ossa.md +0 -1714
  274. package/website/content/docs/migration-guides/langflow-to-ossa.md +0 -2075
  275. package/website/content/docs/migration-guides/migration-manifest.json +0 -64
  276. package/website/content/docs/migration-guides/openai-to-ossa.md +0 -1202
  277. package/website/content/docs/openapi-extensions/examples.md +0 -550
  278. package/website/content/docs/openapi-extensions/index.md +0 -551
  279. package/website/content/docs/openapi-extensions/operation-extensions.md +0 -457
  280. package/website/content/docs/openapi-extensions/root-extensions.md +0 -410
  281. package/website/content/docs/ossa-compliant-badge.md +0 -251
  282. package/website/content/docs/pre-release/index.md +0 -175
  283. package/website/content/docs/quick-reference.md +0 -17
  284. package/website/content/docs/readme.md +0 -35
  285. package/website/content/docs/releases/v0.2.6.md +0 -99
  286. package/website/content/docs/schema-reference/agent-capabilities.md +0 -50
  287. package/website/content/docs/schema-reference/agent-id.md +0 -52
  288. package/website/content/docs/schema-reference/agent-name.md +0 -50
  289. package/website/content/docs/schema-reference/agent-role.md +0 -54
  290. package/website/content/docs/schema-reference/agent-spec.md +0 -406
  291. package/website/content/docs/schema-reference/agent-version.md +0 -50
  292. package/website/content/docs/schema-reference/autonomy.md +0 -568
  293. package/website/content/docs/schema-reference/constraints.md +0 -543
  294. package/website/content/docs/schema-reference/index.md +0 -45
  295. package/website/content/docs/schema-reference/llm-config.md +0 -445
  296. package/website/content/docs/schema-reference/observability.md +0 -654
  297. package/website/content/docs/schema-reference/ossa-manifest.md +0 -309
  298. package/website/content/docs/schema-reference/taxonomy.md +0 -509
  299. package/website/content/docs/schema-reference/tools.md +0 -628
  300. package/website/content/docs/templates/blog-post.md +0 -43
  301. package/website/content/docs/types-reference/index.md +0 -105
  302. package/website/content/docs/use-cases/00-index.md +0 -395
  303. package/website/content/docs/use-cases/cicd-code-review.md +0 -1236
  304. package/website/content/docs/use-cases/customer-support.md +0 -1234
  305. package/website/content/docs/use-cases/enterprise-compliance.md +0 -1208
  306. package/website/content/docs/use-cases/research-multi-agent.md +0 -1161
  307. package/website/content/docs/versioning.md +0 -288
  308. package/website/dev.sh +0 -53
  309. package/website/docker-compose.dev.yml +0 -36
  310. package/website/lib/version.ts +0 -35
  311. package/website/lib/versions.json +0 -103
  312. package/website/next.config.ts +0 -18
  313. package/website/nginx.conf +0 -32
  314. package/website/package-lock.json +0 -9679
  315. package/website/package.json +0 -59
  316. package/website/postcss.config.mjs +0 -9
  317. package/website/scripts/fetch-versions.js +0 -166
  318. package/website/scripts/generate-examples-index.js +0 -163
  319. package/website/scripts/merge-docs-to-wiki.ts +0 -207
  320. package/website/scripts/sync-version.js +0 -72
  321. package/website/scripts/sync-wiki.ts +0 -322
  322. package/website/scripts/upload-wiki.ts +0 -199
  323. package/website/styles/_spacing.scss +0 -453
  324. package/website/styles/_tokens.scss +0 -245
  325. package/website/styles/_typography.scss +0 -361
  326. package/website/styles/_variables.scss +0 -287
  327. package/website/tailwind.config.ts +0 -170
@@ -1,322 +0,0 @@
1
- #!/usr/bin/env npx tsx
2
- /**
3
- * GitLab Wiki Sync Script
4
- *
5
- * Fetches wiki pages from GitLab and saves them to content/docs for static site generation.
6
- * Run this during build or manually with: npx tsx scripts/sync-wiki.ts
7
- */
8
-
9
- import fs from 'fs';
10
- import path from 'path';
11
- import os from 'os';
12
-
13
- // Load .env.local first to get project path
14
- loadEnvLocal();
15
-
16
- // Get GITLAB_HOST from env or CI variables, with fallback
17
- const GITLAB_HOST = process.env.GITLAB_HOST || process.env.CI_SERVER_HOST || 'gitlab.com';
18
- // Get project path from env (GITLAB_PROJECT_PATH) or fallback to default
19
- const PROJECT_PATH = process.env.GITLAB_PROJECT_PATH || 'blueflyio/openstandardagents';
20
- const DOCS_DIR = path.join(process.cwd(), 'content/docs');
21
- const BLOG_DIR = path.join(process.cwd(), 'content/blog');
22
-
23
- interface WikiPage {
24
- slug: string;
25
- title: string;
26
- content: string;
27
- format: string;
28
- }
29
-
30
- function loadEnvLocal(): void {
31
- // Check multiple common locations for .env.local
32
- const envPaths: string[] = [];
33
-
34
- // If ENV_FILE is set, use that first
35
- if (process.env.ENV_FILE) {
36
- envPaths.push(process.env.ENV_FILE);
37
- }
38
-
39
- // Current directory and parent directories (walk up to 5 levels)
40
- let currentDir = process.cwd();
41
- for (let i = 0; i < 5; i++) {
42
- envPaths.push(path.join(currentDir, '.env.local'));
43
- const parentDir = path.dirname(currentDir);
44
- if (parentDir === currentDir) break; // Reached filesystem root
45
- currentDir = parentDir;
46
- }
47
-
48
- // User home directory
49
- envPaths.push(path.join(os.homedir(), '.env.local'));
50
-
51
- for (const envLocalPath of envPaths) {
52
- if (fs.existsSync(envLocalPath)) {
53
- try {
54
- const envContent = fs.readFileSync(envLocalPath, 'utf-8');
55
- envContent.split('\n').forEach(line => {
56
- const trimmed = line.trim();
57
- if (trimmed && !trimmed.startsWith('#')) {
58
- const [key, ...valueParts] = trimmed.split('=');
59
- if (key && valueParts.length > 0) {
60
- const value = valueParts.join('=').replace(/^["']|["']$/g, '').trim();
61
- if (!process.env[key] && value) {
62
- process.env[key] = value;
63
- }
64
- }
65
- }
66
- });
67
- // Load from first found file only
68
- return;
69
- } catch (error) {
70
- // Continue to next location if this one fails
71
- continue;
72
- }
73
- }
74
- }
75
- }
76
-
77
- async function getGitLabToken(): Promise<string | null> {
78
- // .env.local already loaded at top level
79
-
80
- // Try environment variables (check multiple possible names)
81
- if (process.env.GITLAB_TOKEN) {
82
- return process.env.GITLAB_TOKEN;
83
- }
84
- if (process.env.GITLAB_PUSH_TOKEN) {
85
- return process.env.GITLAB_PUSH_TOKEN;
86
- }
87
- if (process.env.CI_JOB_TOKEN) {
88
- return process.env.CI_JOB_TOKEN;
89
- }
90
-
91
- // Try reading from ~/.tokens/gitlab
92
- const tokenPath = path.join(process.env.HOME || '', '.tokens', 'gitlab');
93
- if (fs.existsSync(tokenPath)) {
94
- return fs.readFileSync(tokenPath, 'utf-8').trim();
95
- }
96
-
97
- return null;
98
- }
99
-
100
- async function fetchWikiPages(): Promise<WikiPage[]> {
101
- const token = await getGitLabToken();
102
-
103
- if (!token) {
104
- console.log('⚠️ No GitLab token found - skipping wiki sync');
105
- console.log(' Set GITLAB_TOKEN env var or create ~/.tokens/gitlab to enable sync');
106
- return [];
107
- }
108
-
109
- const encodedPath = encodeURIComponent(PROJECT_PATH);
110
-
111
- const response = await fetch(
112
- `https://${GITLAB_HOST}/api/v4/projects/${encodedPath}/wikis?with_content=1`,
113
- {
114
- headers: {
115
- 'PRIVATE-TOKEN': token,
116
- },
117
- }
118
- );
119
-
120
- if (!response.ok) {
121
- // Handle auth errors gracefully - use existing content
122
- if (response.status === 401 || response.status === 403) {
123
- console.log(`⚠️ Wiki API returned ${response.status} - using existing content`);
124
- console.log(' Token may lack wiki read permission');
125
- return [];
126
- }
127
- throw new Error(`Failed to fetch wiki pages: ${response.status} ${response.statusText}`);
128
- }
129
-
130
- return response.json();
131
- }
132
-
133
- function slugToFilePath(slug: string): string {
134
- // Convert GitLab wiki slug to local file path
135
- // e.g., "Getting-Started/5-Minute-Overview" -> "getting-started/5-minute-overview.md"
136
- const parts = slug.split('/');
137
-
138
- // Lowercase everything for URL-friendly paths
139
- if (parts.length > 1) {
140
- const dirs = parts.slice(0, -1).map(d => d.toLowerCase());
141
- const filename = parts[parts.length - 1].toLowerCase();
142
- return path.join(...dirs, `${filename}.md`);
143
- }
144
-
145
- return `${slug.toLowerCase()}.md`;
146
- }
147
-
148
- function processContent(content: string, title: string): string {
149
- // Add frontmatter if not present
150
- if (!content.startsWith('---')) {
151
- const frontmatter = `---
152
- title: "${title.replace(/"/g, '\\"')}"
153
- ---
154
-
155
- `;
156
- return frontmatter + content;
157
- }
158
- return content;
159
- }
160
-
161
- function processBlogContent(content: string, title: string): string {
162
- // Extract or generate blog metadata from content
163
- let bodyContent = content;
164
- let existingMeta: Record<string, string> = {};
165
-
166
- // Parse existing frontmatter if present
167
- if (content.startsWith('---')) {
168
- const endIndex = content.indexOf('---', 3);
169
- if (endIndex !== -1) {
170
- const frontmatterText = content.substring(3, endIndex).trim();
171
- bodyContent = content.substring(endIndex + 3).trim();
172
-
173
- // Parse simple key: value frontmatter
174
- frontmatterText.split('\n').forEach(line => {
175
- const colonIndex = line.indexOf(':');
176
- if (colonIndex > 0) {
177
- const key = line.substring(0, colonIndex).trim();
178
- const value = line.substring(colonIndex + 1).trim();
179
- existingMeta[key] = value;
180
- }
181
- });
182
- }
183
- }
184
-
185
- // Look for author in content (e.g., "**Thomas Scola**")
186
- const authorMatch = bodyContent.match(/\*\*([^*]+)\*\*\s*\n\s*\*([^*]+)\*/);
187
- const extractedAuthor = authorMatch ? authorMatch[1].trim() : null;
188
-
189
- // Try to extract excerpt from abstract or first paragraph
190
- let excerpt = '';
191
- const abstractMatch = bodyContent.match(/###\s*Abstract\s*\n+([^\n#]+)/i);
192
- if (abstractMatch) {
193
- excerpt = abstractMatch[1].substring(0, 200).trim();
194
- if (abstractMatch[1].length > 200) excerpt += '...';
195
- } else {
196
- const lines = bodyContent.split('\n');
197
- const firstPara = lines.find(line =>
198
- line.trim() &&
199
- !line.startsWith('#') &&
200
- !line.startsWith('*') &&
201
- !line.startsWith('[')
202
- );
203
- if (firstPara) {
204
- excerpt = firstPara.substring(0, 200).trim();
205
- if (firstPara.length > 200) excerpt += '...';
206
- }
207
- }
208
-
209
- // Build final frontmatter with blog-specific fields
210
- const finalTitle = existingMeta.title || title;
211
- const date = existingMeta.date || new Date().toISOString().split('T')[0];
212
- const author = existingMeta.author || extractedAuthor || 'OSSA Team';
213
- const category = existingMeta.category || 'Research';
214
- const tags = existingMeta.tags || '["OSSA", "AI Agents", "Standards"]';
215
- const finalExcerpt = existingMeta.excerpt || excerpt;
216
-
217
- const frontmatter = `---
218
- title: "${finalTitle.replace(/"/g, '\\"').replace(/\\/g, '')}"
219
- date: "${date}"
220
- author: "${author}"
221
- category: "${category}"
222
- tags: ${tags}
223
- excerpt: "${finalExcerpt.replace(/"/g, '\\"')}"
224
- ---
225
-
226
- `;
227
- return frontmatter + bodyContent;
228
- }
229
-
230
- async function syncWiki(): Promise<void> {
231
- console.log('🔄 Syncing GitLab wiki...');
232
-
233
- // Fetch all wiki pages
234
- const pages = await fetchWikiPages();
235
-
236
- // If no pages returned (no token or empty wiki), skip sync
237
- if (pages.length === 0) {
238
- console.log('📋 No pages to sync - using existing content');
239
- return;
240
- }
241
-
242
- console.log(`📚 Found ${pages.length} wiki pages`);
243
-
244
- // Track synced files for cleanup
245
- const syncedDocs = new Set<string>();
246
- const syncedBlogs = new Set<string>();
247
-
248
- for (const page of pages) {
249
- // Skip Home page (we have our own docs landing)
250
- if (page.slug === 'Home') {
251
- console.log(`⏭️ Skipping Home page (using custom landing)`);
252
- continue;
253
- }
254
-
255
- // Handle Blog pages separately
256
- if (page.slug === 'Blog' || page.slug.startsWith('Blog/')) {
257
- // Skip the Blog index and template pages
258
- if (page.slug === 'Blog' || page.slug === 'Blog/Template') {
259
- console.log(`⏭️ Skipping ${page.slug} (not a blog post)`);
260
- continue;
261
- }
262
-
263
- // Extract blog post name from slug (Blog/My-Post -> My-Post)
264
- const blogSlug = page.slug.replace('Blog/', '');
265
- const filename = `${blogSlug}.md`;
266
- const fullPath = path.join(BLOG_DIR, filename);
267
-
268
- // Ensure blog directory exists
269
- if (!fs.existsSync(BLOG_DIR)) {
270
- fs.mkdirSync(BLOG_DIR, { recursive: true });
271
- }
272
-
273
- // Process and write blog content
274
- const processedContent = processBlogContent(page.content, page.title);
275
- fs.writeFileSync(fullPath, processedContent);
276
- syncedBlogs.add(filename);
277
-
278
- console.log(`📝 Blog: ${page.slug} -> content/blog/${filename}`);
279
- continue;
280
- }
281
-
282
- // Regular docs pages
283
- const relativePath = slugToFilePath(page.slug);
284
- const fullPath = path.join(DOCS_DIR, relativePath);
285
- const dirPath = path.dirname(fullPath);
286
-
287
- // Ensure directory exists
288
- if (!fs.existsSync(dirPath)) {
289
- fs.mkdirSync(dirPath, { recursive: true });
290
- }
291
-
292
- // Process and write content
293
- const processedContent = processContent(page.content, page.title);
294
- fs.writeFileSync(fullPath, processedContent);
295
- syncedDocs.add(relativePath);
296
-
297
- console.log(`✅ ${page.slug} -> ${relativePath}`);
298
- }
299
-
300
- console.log(`\n✨ Synced ${syncedDocs.size} docs + ${syncedBlogs.size} blog posts`);
301
-
302
- // Write manifest for tracking
303
- const manifest = {
304
- lastSync: new Date().toISOString(),
305
- source: `https://${GITLAB_HOST}/${PROJECT_PATH}/-/wikis/home`,
306
- docs: Array.from(syncedDocs).sort(),
307
- blogs: Array.from(syncedBlogs).sort(),
308
- };
309
-
310
- fs.writeFileSync(
311
- path.join(DOCS_DIR, '.wiki-sync-manifest.json'),
312
- JSON.stringify(manifest, null, 2)
313
- );
314
-
315
- console.log('📋 Updated .wiki-sync-manifest.json');
316
- }
317
-
318
- // Run if called directly
319
- syncWiki().catch((error) => {
320
- console.error('❌ Wiki sync failed:', error.message);
321
- process.exit(1);
322
- });
@@ -1,199 +0,0 @@
1
- #!/usr/bin/env npx tsx
2
- /**
3
- * Upload Wiki Export to GitLab
4
- *
5
- * Uploads prepared wiki files from .wiki-export to GitLab wiki via API
6
- */
7
-
8
- import fs from 'fs';
9
- import path from 'path';
10
- import os from 'os';
11
-
12
- // Load .env.local first to get project path
13
- loadEnvLocal();
14
-
15
- const GITLAB_HOST = process.env.GITLAB_HOST || process.env.CI_SERVER_HOST || 'gitlab.com';
16
- // Get project path from env (GITLAB_PROJECT_PATH) or fallback to default
17
- const PROJECT_PATH = process.env.GITLAB_PROJECT_PATH || 'blueflyio/openstandardagents';
18
- const EXPORT_DIR = path.join(process.cwd(), '.wiki-export');
19
-
20
- function loadEnvLocal(): void {
21
- // Check multiple common locations for .env.local
22
- const envPaths: string[] = [];
23
-
24
- // If ENV_FILE is set, use that first
25
- if (process.env.ENV_FILE) {
26
- envPaths.push(process.env.ENV_FILE);
27
- }
28
-
29
- // Current directory and parent directories (walk up to 5 levels)
30
- let currentDir = process.cwd();
31
- for (let i = 0; i < 5; i++) {
32
- envPaths.push(path.join(currentDir, '.env.local'));
33
- const parentDir = path.dirname(currentDir);
34
- if (parentDir === currentDir) break; // Reached filesystem root
35
- currentDir = parentDir;
36
- }
37
-
38
- // User home directory
39
- envPaths.push(path.join(os.homedir(), '.env.local'));
40
-
41
- for (const envLocalPath of envPaths) {
42
- if (fs.existsSync(envLocalPath)) {
43
- try {
44
- const envContent = fs.readFileSync(envLocalPath, 'utf-8');
45
- envContent.split('\n').forEach(line => {
46
- const trimmed = line.trim();
47
- if (trimmed && !trimmed.startsWith('#')) {
48
- const [key, ...valueParts] = trimmed.split('=');
49
- if (key && valueParts.length > 0) {
50
- const value = valueParts.join('=').replace(/^["']|["']$/g, '').trim();
51
- if (!process.env[key] && value) {
52
- process.env[key] = value;
53
- }
54
- }
55
- }
56
- });
57
- // Load from first found file only
58
- return;
59
- } catch (error) {
60
- // Continue to next location if this one fails
61
- continue;
62
- }
63
- }
64
- }
65
- }
66
-
67
- async function getGitLabToken(): Promise<string | null> {
68
- // .env.local already loaded at top level
69
-
70
- // Try environment variables (check multiple possible names)
71
- if (process.env.GITLAB_TOKEN) {
72
- return process.env.GITLAB_TOKEN;
73
- }
74
- if (process.env.GITLAB_PUSH_TOKEN) {
75
- return process.env.GITLAB_PUSH_TOKEN;
76
- }
77
- if (process.env.CI_JOB_TOKEN) {
78
- return process.env.CI_JOB_TOKEN;
79
- }
80
-
81
- const tokenPath = path.join(process.env.HOME || '', '.tokens', 'gitlab');
82
- if (fs.existsSync(tokenPath)) {
83
- return fs.readFileSync(tokenPath, 'utf-8').trim();
84
- }
85
-
86
- return null;
87
- }
88
-
89
- async function uploadWikiPage(slug: string, content: string): Promise<boolean> {
90
- const token = await getGitLabToken();
91
- if (!token) {
92
- console.error('❌ No GitLab token found');
93
- console.error(' Set GITLAB_TOKEN env var or create ~/.tokens/gitlab');
94
- return false;
95
- }
96
-
97
- const encodedPath = encodeURIComponent(PROJECT_PATH);
98
- const url = `https://${GITLAB_HOST}/api/v4/projects/${encodedPath}/wikis`;
99
-
100
- try {
101
- const response = await fetch(url, {
102
- method: 'POST',
103
- headers: {
104
- 'PRIVATE-TOKEN': token,
105
- 'Content-Type': 'application/json',
106
- },
107
- body: JSON.stringify({
108
- title: slug,
109
- content: content,
110
- format: 'markdown',
111
- }),
112
- });
113
-
114
- if (response.ok) {
115
- return true;
116
- } else if (response.status === 409 || response.status === 400) {
117
- // Page already exists, try to update it
118
- const updateUrl = `${url}/${encodeURIComponent(slug)}`;
119
- const updateResponse = await fetch(updateUrl, {
120
- method: 'PUT',
121
- headers: {
122
- 'PRIVATE-TOKEN': token,
123
- 'Content-Type': 'application/json',
124
- },
125
- body: JSON.stringify({
126
- content: content,
127
- format: 'markdown',
128
- }),
129
- });
130
- if (updateResponse.ok) {
131
- return true;
132
- } else {
133
- const errorText = await updateResponse.text();
134
- console.error(` Update error: ${updateResponse.status} ${updateResponse.statusText}`);
135
- console.error(` ${errorText.substring(0, 200)}`);
136
- return false;
137
- }
138
- } else {
139
- const errorText = await response.text();
140
- console.error(` API error: ${response.status} ${response.statusText}`);
141
- console.error(` ${errorText.substring(0, 200)}`);
142
- return false;
143
- }
144
- } catch (error: any) {
145
- console.error(` Network error: ${error.message}`);
146
- return false;
147
- }
148
- }
149
-
150
- async function uploadWikiFiles(): Promise<void> {
151
- console.log('🔄 Uploading wiki files to GitLab...\n');
152
-
153
- if (!fs.existsSync(EXPORT_DIR)) {
154
- console.error('❌ .wiki-export directory not found');
155
- console.error(' Run: npm run merge-docs-to-wiki first');
156
- return;
157
- }
158
-
159
- const manifestPath = path.join(EXPORT_DIR, 'MANIFEST.json');
160
- if (!fs.existsSync(manifestPath)) {
161
- console.error('❌ MANIFEST.json not found');
162
- return;
163
- }
164
-
165
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
166
- console.log(`📚 Found ${manifest.length} files to upload\n`);
167
-
168
- let successCount = 0;
169
- let failCount = 0;
170
-
171
- for (const item of manifest) {
172
- const filePath = path.join(EXPORT_DIR, `${item.slug}.md`);
173
- if (!fs.existsSync(filePath)) {
174
- console.log(`⚠️ ${item.slug} - file not found, skipping`);
175
- failCount++;
176
- continue;
177
- }
178
-
179
- const content = fs.readFileSync(filePath, 'utf-8');
180
- console.log(`📤 Uploading ${item.slug}...`);
181
-
182
- const success = await uploadWikiPage(item.slug, content);
183
- if (success) {
184
- console.log(`✅ ${item.slug} - uploaded successfully`);
185
- successCount++;
186
- } else {
187
- console.log(`❌ ${item.slug} - upload failed`);
188
- failCount++;
189
- }
190
- }
191
-
192
- console.log(`\n✨ Upload complete: ${successCount} succeeded, ${failCount} failed`);
193
- }
194
-
195
- uploadWikiFiles().catch((error) => {
196
- console.error('❌ Upload failed:', error.message);
197
- process.exit(1);
198
- });
199
-