forgeos 0.1.0-alpha.7 → 0.1.0-alpha.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 (185) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +14 -0
  3. package/adapters/go/README.md +23 -0
  4. package/adapters/go/go.mod +3 -0
  5. package/adapters/go/http.go +149 -0
  6. package/adapters/go/registry.go +234 -0
  7. package/adapters/go/types.go +136 -0
  8. package/docs/changelog.md +82 -0
  9. package/docs/forge-protocol.md +155 -0
  10. package/examples/go-billing/go.mod +7 -0
  11. package/examples/go-billing/main.go +120 -0
  12. package/package.json +5 -1
  13. package/schemas/forge-manifest.schema.json +57 -0
  14. package/src/forge/_generated/actionSubscriptions.json +2 -2
  15. package/src/forge/_generated/actionSubscriptions.ts +3 -3
  16. package/src/forge/_generated/agentAdapterManifest.json +2 -2
  17. package/src/forge/_generated/agentAdapterManifest.ts +3 -3
  18. package/src/forge/_generated/agentContract.json +2 -2
  19. package/src/forge/_generated/agentContract.ts +5 -2
  20. package/src/forge/_generated/agentQuickstart.md +1 -1
  21. package/src/forge/_generated/agentTools.json +2 -2
  22. package/src/forge/_generated/agentTools.md +1 -1
  23. package/src/forge/_generated/agentTools.ts +2 -2
  24. package/src/forge/_generated/aiContext.ts +1 -1
  25. package/src/forge/_generated/aiModels.json +1 -1
  26. package/src/forge/_generated/aiModels.ts +1 -1
  27. package/src/forge/_generated/aiProviders.json +1 -1
  28. package/src/forge/_generated/aiProviders.ts +1 -1
  29. package/src/forge/_generated/aiRegistry.json +2 -2
  30. package/src/forge/_generated/aiRegistry.ts +3 -3
  31. package/src/forge/_generated/api.json +2 -2
  32. package/src/forge/_generated/api.ts +7 -2
  33. package/src/forge/_generated/appGraph.json +2 -2
  34. package/src/forge/_generated/appGraph.ts +661 -254
  35. package/src/forge/_generated/appMap.md +1 -1
  36. package/src/forge/_generated/artifactManifest.json +2 -2
  37. package/src/forge/_generated/artifactManifest.ts +2 -2
  38. package/src/forge/_generated/authClaims.json +1 -1
  39. package/src/forge/_generated/authClaims.ts +1 -1
  40. package/src/forge/_generated/authConfig.json +1 -1
  41. package/src/forge/_generated/authConfig.ts +1 -1
  42. package/src/forge/_generated/authContext.ts +1 -1
  43. package/src/forge/_generated/authRegistry.json +1 -1
  44. package/src/forge/_generated/authRegistry.ts +1 -1
  45. package/src/forge/_generated/buildInfo.json +2 -2
  46. package/src/forge/_generated/buildInfo.ts +4 -4
  47. package/src/forge/_generated/capabilityMap.json +2 -2
  48. package/src/forge/_generated/capabilityMap.md +1 -1
  49. package/src/forge/_generated/capabilityMap.ts +2 -2
  50. package/src/forge/_generated/client.ts +88 -1
  51. package/src/forge/_generated/clientApi.ts +2 -1
  52. package/src/forge/_generated/clientManifest.json +2 -2
  53. package/src/forge/_generated/clientManifest.ts +6 -4
  54. package/src/forge/_generated/clientTypes.ts +19 -1
  55. package/src/forge/_generated/configRegistry.json +1 -1
  56. package/src/forge/_generated/configRegistry.ts +1 -1
  57. package/src/forge/_generated/dataGraph.json +2 -2
  58. package/src/forge/_generated/dataGraph.ts +3 -3
  59. package/src/forge/_generated/db.json +1 -1
  60. package/src/forge/_generated/db.ts +1 -1
  61. package/src/forge/_generated/dbSecurityManifest.json +1 -1
  62. package/src/forge/_generated/dbSecurityManifest.ts +1 -1
  63. package/src/forge/_generated/dbSessionContext.json +1 -1
  64. package/src/forge/_generated/dbSessionContext.ts +1 -1
  65. package/src/forge/_generated/deployManifest.json +2 -2
  66. package/src/forge/_generated/deployManifest.ts +7 -7
  67. package/src/forge/_generated/devManifest.json +2 -2
  68. package/src/forge/_generated/devManifest.ts +3 -3
  69. package/src/forge/_generated/envSchema.json +1 -1
  70. package/src/forge/_generated/envSchema.ts +1 -1
  71. package/src/forge/_generated/externalServices.json +2 -0
  72. package/src/forge/_generated/externalServices.ts +9 -0
  73. package/src/forge/_generated/frontendGraph.json +1 -1
  74. package/src/forge/_generated/frontendGraph.ts +1 -1
  75. package/src/forge/_generated/importGuards.json +1 -1
  76. package/src/forge/_generated/importGuards.ts +1 -1
  77. package/src/forge/_generated/index.ts +2 -1
  78. package/src/forge/_generated/liveProductionManifest.json +1 -1
  79. package/src/forge/_generated/liveProductionManifest.ts +1 -1
  80. package/src/forge/_generated/liveProtocol.json +1 -1
  81. package/src/forge/_generated/liveProtocol.ts +1 -1
  82. package/src/forge/_generated/liveQueryRegistry.json +2 -2
  83. package/src/forge/_generated/liveQueryRegistry.ts +3 -3
  84. package/src/forge/_generated/liveTransportConfig.json +1 -1
  85. package/src/forge/_generated/liveTransportConfig.ts +1 -1
  86. package/src/forge/_generated/makeRegistry.json +2 -2
  87. package/src/forge/_generated/makeRegistry.ts +2 -2
  88. package/src/forge/_generated/makeTemplates.json +1 -1
  89. package/src/forge/_generated/makeTemplates.ts +1 -1
  90. package/src/forge/_generated/mockMap.json +1 -1
  91. package/src/forge/_generated/mockMap.ts +1 -1
  92. package/src/forge/_generated/operationPlaybooks.md +1 -1
  93. package/src/forge/_generated/packageGraph.json +2 -2
  94. package/src/forge/_generated/packageGraph.ts +2 -2
  95. package/src/forge/_generated/packageUpgradeRegistry.json +2 -2
  96. package/src/forge/_generated/packageUpgradeRegistry.ts +2 -2
  97. package/src/forge/_generated/permissionMatrix.json +2 -2
  98. package/src/forge/_generated/permissionMatrix.ts +3 -3
  99. package/src/forge/_generated/policyRegistry.json +2 -2
  100. package/src/forge/_generated/policyRegistry.ts +3 -3
  101. package/src/forge/_generated/queryRegistry.json +2 -2
  102. package/src/forge/_generated/queryRegistry.ts +3 -3
  103. package/src/forge/_generated/react.d.ts +1 -1
  104. package/src/forge/_generated/react.ts +1 -1
  105. package/src/forge/_generated/reactManifest.json +2 -2
  106. package/src/forge/_generated/reactManifest.ts +3 -3
  107. package/src/forge/_generated/releaseManifest.json +2 -2
  108. package/src/forge/_generated/releaseManifest.ts +3 -3
  109. package/src/forge/_generated/rlsPolicies.json +1 -1
  110. package/src/forge/_generated/rlsPolicies.sql +1 -1
  111. package/src/forge/_generated/rlsPolicies.ts +1 -1
  112. package/src/forge/_generated/runtimeGraph.json +2 -2
  113. package/src/forge/_generated/runtimeGraph.ts +3 -3
  114. package/src/forge/_generated/runtimeMatrix.json +1 -1
  115. package/src/forge/_generated/runtimeMatrix.ts +1 -1
  116. package/src/forge/_generated/runtimeRegistry.ts +1 -1
  117. package/src/forge/_generated/runtimeRules.md +1 -1
  118. package/src/forge/_generated/secretRegistry.json +1 -1
  119. package/src/forge/_generated/secretRegistry.ts +1 -1
  120. package/src/forge/_generated/secretsContext.ts +1 -1
  121. package/src/forge/_generated/serverApi.ts +2 -1
  122. package/src/forge/_generated/sourceMapManifest.json +2 -2
  123. package/src/forge/_generated/sourceMapManifest.ts +2 -2
  124. package/src/forge/_generated/sqlPlan.json +1 -1
  125. package/src/forge/_generated/sqlPlan.ts +1 -1
  126. package/src/forge/_generated/subscriptionManifest.json +2 -2
  127. package/src/forge/_generated/subscriptionManifest.ts +3 -3
  128. package/src/forge/_generated/symbolicationManifest.json +2 -2
  129. package/src/forge/_generated/symbolicationManifest.ts +2 -2
  130. package/src/forge/_generated/telemetryRegistry.json +2 -2
  131. package/src/forge/_generated/telemetryRegistry.ts +3 -3
  132. package/src/forge/_generated/telemetrySinks.json +2 -2
  133. package/src/forge/_generated/telemetrySinks.ts +2 -2
  134. package/src/forge/_generated/tenantScope.json +2 -2
  135. package/src/forge/_generated/tenantScope.ts +3 -3
  136. package/src/forge/_generated/testGraph.json +2 -2
  137. package/src/forge/_generated/testGraph.ts +57 -3
  138. package/src/forge/_generated/testPlanRegistry.json +2 -2
  139. package/src/forge/_generated/testPlanRegistry.ts +2 -2
  140. package/src/forge/_generated/uiRoutes.json +1 -1
  141. package/src/forge/_generated/uiRoutes.ts +1 -1
  142. package/src/forge/_generated/uiScenarios.json +1 -1
  143. package/src/forge/_generated/uiScenarios.ts +1 -1
  144. package/src/forge/_generated/uiTestManifest.json +2 -2
  145. package/src/forge/_generated/uiTestManifest.ts +2 -2
  146. package/src/forge/_generated/workflowRegistry.json +2 -2
  147. package/src/forge/_generated/workflowRegistry.ts +3 -3
  148. package/src/forge/_generated/workflowSubscriptions.json +2 -2
  149. package/src/forge/_generated/workflowSubscriptions.ts +3 -3
  150. package/src/forge/bench.ts +248 -0
  151. package/src/forge/cli/ai.ts +16 -1
  152. package/src/forge/cli/build.ts +1 -1
  153. package/src/forge/cli/commands.ts +118 -0
  154. package/src/forge/cli/main.ts +3 -1
  155. package/src/forge/cli/parse.ts +84 -0
  156. package/src/forge/cli/run.ts +41 -0
  157. package/src/forge/cli/verify.ts +201 -24
  158. package/src/forge/compiler/agent-contract/build.ts +121 -7
  159. package/src/forge/compiler/agent-contract/types.ts +30 -1
  160. package/src/forge/compiler/api-surface/build.ts +47 -0
  161. package/src/forge/compiler/app-graph/build.ts +33 -5
  162. package/src/forge/compiler/app-graph/module-graph.ts +73 -78
  163. package/src/forge/compiler/app-graph/parser.ts +24 -24
  164. package/src/forge/compiler/app-graph/profile.ts +26 -0
  165. package/src/forge/compiler/classifier/capabilities.ts +3 -2
  166. package/src/forge/compiler/classifier/classify.ts +32 -8
  167. package/src/forge/compiler/classifier/secrets.ts +3 -2
  168. package/src/forge/compiler/classifier/signals.ts +91 -1
  169. package/src/forge/compiler/client-sdk/build-manifest.ts +4 -0
  170. package/src/forge/compiler/client-sdk/render-client.ts +105 -0
  171. package/src/forge/compiler/diagnostics/codes.ts +12 -0
  172. package/src/forge/compiler/external-manifest/registry.ts +204 -0
  173. package/src/forge/compiler/external-manifest/types.ts +89 -0
  174. package/src/forge/compiler/external-manifest/validate.ts +335 -0
  175. package/src/forge/compiler/orchestrator/plan-profile.ts +23 -0
  176. package/src/forge/compiler/orchestrator/plan.ts +52 -11
  177. package/src/forge/compiler/orchestrator/profile.ts +65 -0
  178. package/src/forge/compiler/orchestrator/run.ts +97 -31
  179. package/src/forge/compiler/orchestrator/serialize.ts +13 -6
  180. package/src/forge/compiler/policy-registry/build.ts +44 -1
  181. package/src/forge/compiler/test-graph/build.ts +11 -3
  182. package/src/forge/compiler/types/cli.ts +3 -0
  183. package/src/forge/dev/server.ts +68 -0
  184. package/src/forge/runtime/external/bridge.ts +553 -0
  185. package/src/forge/version.ts +1 -1
package/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- // @forge-generated generator=0.1.0-alpha.7 input=4fe172e9300b7393cef5b37bfef064fb779c42d420e54af7e07045ad230330a9 content=1611635edf59c122b013ba76c85bd333ab3b30b289aaea04a9074f9438782a50
1
+ // @forge-generated generator=0.1.0-alpha.9 input=f9063a03ef56a20a89f1418951bede5ab5ed87d800bb0512a0d0445309642a36 content=1611635edf59c122b013ba76c85bd333ab3b30b289aaea04a9074f9438782a50
2
2
  # AGENTS.md
3
3
 
4
4
  <!-- forge-generated:start -->
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # forgeos
2
2
 
3
+ ## 0.1.0-alpha.9
4
+
5
+ ### Patch Changes
6
+
7
+ - Reuse compiler classifier package signals across export classification, dropping repeated package signal scans.
8
+ - Reuse serialized graph JSON when rendering the largest generated TypeScript graph artifacts.
9
+ - Keep generated Forge artifacts aligned with the `0.1.0-alpha.9` compiler/runtime version.
10
+
11
+ ## 0.1.0-alpha.8
12
+
13
+ ### Patch Changes
14
+
15
+ - [`7568756`](https://github.com/Stahldavid/forge/commit/756875688873dd60d3d6cf700a7bb7c211968c69) Thanks [@Stahldavid](https://github.com/Stahldavid)! - Publish prerelease packages through the ForgeOS alpha publisher so npm dist-tags stay aligned.
16
+
3
17
  ## 0.1.0-alpha.7
4
18
 
5
19
  ### Patch Changes
@@ -0,0 +1,23 @@
1
+ # Forge Go Adapter
2
+
3
+ `adapters/go` is the minimal Go SDK for external Forge runtimes. It registers
4
+ commands and queries, emits `forge.manifest.json`, and exposes a Forge-compatible
5
+ HTTP handler.
6
+
7
+ ```go
8
+ app := forge.New("billing", forge.BaseURL("http://127.0.0.1:8787"))
9
+
10
+ app.Command("createInvoice", forge.Handle(createInvoice),
11
+ forge.Policy("billing.manage"),
12
+ forge.TenantScoped(true),
13
+ forge.NeedsApproval(true),
14
+ )
15
+
16
+ app.Query("listInvoices", forge.Handle(listInvoices),
17
+ forge.Policy("billing.manage"),
18
+ forge.TenantScoped(true),
19
+ )
20
+ ```
21
+
22
+ The HTTP handler accepts Forge runtime envelopes on `/commands/:name` and
23
+ `/queries/:name`, then returns `{ "ok": true, "result": ... }` envelopes.
@@ -0,0 +1,3 @@
1
+ module github.com/Stahldavid/forge/adapters/go
2
+
3
+ go 1.22
@@ -0,0 +1,149 @@
1
+ package forge
2
+
3
+ import (
4
+ "encoding/json"
5
+ "errors"
6
+ "net/http"
7
+ "strings"
8
+ )
9
+
10
+ func (registry *Registry) HTTPHandler() http.Handler {
11
+ mux := http.NewServeMux()
12
+ mux.HandleFunc(registry.service.Health, registry.handleHealth)
13
+ mux.HandleFunc("/manifest", registry.handleManifest)
14
+ mux.HandleFunc("/commands/", registry.handleRuntime(KindCommand, "/commands/"))
15
+ mux.HandleFunc("/queries/", registry.handleRuntime(KindQuery, "/queries/"))
16
+ return mux
17
+ }
18
+
19
+ func (registry *Registry) handleHealth(response http.ResponseWriter, request *http.Request) {
20
+ writeJSON(response, http.StatusOK, map[string]any{
21
+ "ok": true,
22
+ "service": registry.service.Name,
23
+ })
24
+ }
25
+
26
+ func (registry *Registry) handleManifest(response http.ResponseWriter, request *http.Request) {
27
+ baseURL := request.URL.Query().Get("baseUrl")
28
+ if baseURL == "" {
29
+ baseURL = registry.service.BaseURL
30
+ }
31
+ writeJSON(response, http.StatusOK, registry.Manifest(baseURL))
32
+ }
33
+
34
+ func (registry *Registry) handleRuntime(kind EntryKind, prefix string) http.HandlerFunc {
35
+ return func(response http.ResponseWriter, request *http.Request) {
36
+ name := strings.TrimPrefix(request.URL.Path, prefix)
37
+ registered, ok := registry.lookup[lookupKey(kind, name)]
38
+ if !ok {
39
+ writeError(response, http.StatusNotFound, "", "FORGE_GO_ENTRY_NOT_FOUND", "external entry not found")
40
+ return
41
+ }
42
+ if request.Method != http.MethodPost && request.Method != http.MethodGet {
43
+ writeError(response, http.StatusMethodNotAllowed, "", "FORGE_GO_METHOD_NOT_ALLOWED", "external entry only accepts GET or POST")
44
+ return
45
+ }
46
+
47
+ envelope, err := readRequestEnvelope(request)
48
+ traceID := traceIDFrom(request, envelope)
49
+ if err != nil {
50
+ writeError(response, http.StatusBadRequest, traceID, "FORGE_GO_BAD_REQUEST", err.Error())
51
+ return
52
+ }
53
+ if envelope.Forge.Service == "" {
54
+ envelope.Forge.Service = registry.service.Name
55
+ }
56
+ if envelope.Forge.Entry == "" {
57
+ envelope.Forge.Entry = name
58
+ }
59
+ if envelope.Forge.Kind == "" {
60
+ envelope.Forge.Kind = string(kind)
61
+ }
62
+ if envelope.Forge.TraceID == "" {
63
+ envelope.Forge.TraceID = traceID
64
+ }
65
+ if envelope.Auth.Kind == "" {
66
+ envelope.Auth = authFromHeaders(request.Header)
67
+ }
68
+
69
+ call := &Context{
70
+ Auth: envelope.Auth,
71
+ Forge: envelope.Forge,
72
+ Headers: request.Header,
73
+ }
74
+ result, err := registered.handler(request.Context(), call, envelope.Args)
75
+ if err != nil {
76
+ writeError(response, http.StatusInternalServerError, envelope.Forge.TraceID, "FORGE_GO_HANDLER_FAILED", err.Error())
77
+ return
78
+ }
79
+ writeJSON(response, http.StatusOK, ResponseEnvelope{
80
+ OK: true,
81
+ Result: result,
82
+ TraceID: envelope.Forge.TraceID,
83
+ })
84
+ }
85
+ }
86
+
87
+ func readRequestEnvelope(request *http.Request) (RequestEnvelope, error) {
88
+ if request.Method == http.MethodGet {
89
+ args := request.URL.Query().Get("args")
90
+ if args == "" {
91
+ args = "{}"
92
+ }
93
+ return RequestEnvelope{Args: json.RawMessage(args)}, nil
94
+ }
95
+ defer request.Body.Close()
96
+ var envelope RequestEnvelope
97
+ decoder := json.NewDecoder(request.Body)
98
+ if err := decoder.Decode(&envelope); err != nil {
99
+ return envelope, err
100
+ }
101
+ if len(envelope.Args) == 0 {
102
+ envelope.Args = json.RawMessage("{}")
103
+ }
104
+ if !json.Valid(envelope.Args) {
105
+ return envelope, errors.New("request args must be valid JSON")
106
+ }
107
+ return envelope, nil
108
+ }
109
+
110
+ func authFromHeaders(headers http.Header) Auth {
111
+ auth := Auth{Kind: headers.Get("x-forge-auth-kind")}
112
+ if auth.Kind == "" {
113
+ auth.Kind = "anonymous"
114
+ }
115
+ auth.UserID = headers.Get("x-forge-user-id")
116
+ auth.TenantID = headers.Get("x-forge-tenant-id")
117
+ auth.Role = headers.Get("x-forge-role")
118
+ return auth
119
+ }
120
+
121
+ func traceIDFrom(request *http.Request, envelope RequestEnvelope) string {
122
+ if envelope.Forge.TraceID != "" {
123
+ return envelope.Forge.TraceID
124
+ }
125
+ return request.Header.Get("x-forge-trace-id")
126
+ }
127
+
128
+ func writeError(response http.ResponseWriter, status int, traceID string, code string, message string) {
129
+ writeJSON(response, status, ResponseEnvelope{
130
+ OK: false,
131
+ Diagnostics: []Diagnostic{{
132
+ Severity: "error",
133
+ Code: code,
134
+ Message: message,
135
+ Docs: []string{"docs/forge-protocol.md"},
136
+ }},
137
+ Error: &ErrorInfo{
138
+ Code: code,
139
+ Message: message,
140
+ },
141
+ TraceID: traceID,
142
+ })
143
+ }
144
+
145
+ func writeJSON(response http.ResponseWriter, status int, body any) {
146
+ response.Header().Set("content-type", "application/json")
147
+ response.WriteHeader(status)
148
+ _ = json.NewEncoder(response).Encode(body)
149
+ }
@@ -0,0 +1,234 @@
1
+ package forge
2
+
3
+ import (
4
+ "encoding/json"
5
+ "io"
6
+ )
7
+
8
+ type Registry struct {
9
+ service Service
10
+ framework string
11
+ schemas map[string]any
12
+ entries []registeredEntry
13
+ lookup map[string]registeredEntry
14
+ }
15
+
16
+ type registeredEntry struct {
17
+ entry Entry
18
+ handler HandlerFunc
19
+ }
20
+
21
+ type RegistryOption func(*Registry)
22
+ type EntryOption func(*Entry)
23
+
24
+ func New(serviceName string, options ...RegistryOption) *Registry {
25
+ registry := &Registry{
26
+ service: Service{
27
+ Name: serviceName,
28
+ Transport: "http",
29
+ Health: "/health",
30
+ },
31
+ framework: "net/http",
32
+ schemas: map[string]any{},
33
+ lookup: map[string]registeredEntry{},
34
+ }
35
+ for _, option := range options {
36
+ option(registry)
37
+ }
38
+ return registry
39
+ }
40
+
41
+ func Framework(value string) RegistryOption {
42
+ return func(registry *Registry) {
43
+ registry.framework = value
44
+ }
45
+ }
46
+
47
+ func BaseURL(value string) RegistryOption {
48
+ return func(registry *Registry) {
49
+ registry.service.BaseURL = value
50
+ }
51
+ }
52
+
53
+ func Health(path string) RegistryOption {
54
+ return func(registry *Registry) {
55
+ registry.service.Health = path
56
+ }
57
+ }
58
+
59
+ func SchemaRef(name string, schema any) RegistryOption {
60
+ return func(registry *Registry) {
61
+ registry.schemas[name] = schema
62
+ }
63
+ }
64
+
65
+ func (registry *Registry) Command(name string, handler HandlerFunc, options ...EntryOption) {
66
+ entry := Entry{
67
+ Name: name,
68
+ Kind: KindCommand,
69
+ Path: "/commands/" + name,
70
+ Method: "POST",
71
+ Transaction: TransactionExternalManaged,
72
+ Risk: RiskWrite,
73
+ }
74
+ registry.add(entry, handler, options...)
75
+ }
76
+
77
+ func (registry *Registry) Query(name string, handler HandlerFunc, options ...EntryOption) {
78
+ entry := Entry{
79
+ Name: name,
80
+ Kind: KindQuery,
81
+ Path: "/queries/" + name,
82
+ Method: "POST",
83
+ Transaction: TransactionReadOnly,
84
+ Risk: RiskRead,
85
+ }
86
+ registry.add(entry, handler, options...)
87
+ }
88
+
89
+ func (registry *Registry) add(entry Entry, handler HandlerFunc, options ...EntryOption) {
90
+ for _, option := range options {
91
+ option(&entry)
92
+ }
93
+ registered := registeredEntry{entry: entry, handler: handler}
94
+ registry.entries = append(registry.entries, registered)
95
+ registry.lookup[lookupKey(entry.Kind, entry.Name)] = registered
96
+ }
97
+
98
+ func Description(value string) EntryOption {
99
+ return func(entry *Entry) {
100
+ entry.Description = value
101
+ }
102
+ }
103
+
104
+ func Path(value string) EntryOption {
105
+ return func(entry *Entry) {
106
+ entry.Path = value
107
+ }
108
+ }
109
+
110
+ func Method(value string) EntryOption {
111
+ return func(entry *Entry) {
112
+ entry.Method = value
113
+ }
114
+ }
115
+
116
+ func InputSchema(schema any) EntryOption {
117
+ return func(entry *Entry) {
118
+ entry.InputSchema = schema
119
+ }
120
+ }
121
+
122
+ func OutputSchema(schema any) EntryOption {
123
+ return func(entry *Entry) {
124
+ entry.OutputSchema = schema
125
+ }
126
+ }
127
+
128
+ func Policy(value string) EntryOption {
129
+ return func(entry *Entry) {
130
+ entry.Policy = value
131
+ }
132
+ }
133
+
134
+ func TenantScoped(value bool) EntryOption {
135
+ return func(entry *Entry) {
136
+ entry.TenantScoped = value
137
+ }
138
+ }
139
+
140
+ func TransactionMode(value Transaction) EntryOption {
141
+ return func(entry *Entry) {
142
+ entry.Transaction = value
143
+ }
144
+ }
145
+
146
+ func EntryRisk(value Risk) EntryOption {
147
+ return func(entry *Entry) {
148
+ entry.Risk = value
149
+ }
150
+ }
151
+
152
+ func NeedsApproval(value bool) EntryOption {
153
+ return func(entry *Entry) {
154
+ entry.NeedsApproval = &value
155
+ }
156
+ }
157
+
158
+ func Effects(values ...string) EntryOption {
159
+ return func(entry *Entry) {
160
+ entry.Effects = append([]string{}, values...)
161
+ }
162
+ }
163
+
164
+ func ReadOnly() EntryOption {
165
+ return func(entry *Entry) {
166
+ entry.Transaction = TransactionReadOnly
167
+ entry.Risk = RiskRead
168
+ }
169
+ }
170
+
171
+ func (registry *Registry) Manifest(baseURL string) Manifest {
172
+ service := registry.service
173
+ if baseURL != "" {
174
+ service.BaseURL = baseURL
175
+ }
176
+ entries := make([]Entry, 0, len(registry.entries))
177
+ for _, registered := range registry.entries {
178
+ entries = append(entries, registered.entry)
179
+ }
180
+ manifest := Manifest{
181
+ ForgeProtocol: ProtocolVersion,
182
+ Language: "go",
183
+ Framework: registry.framework,
184
+ Service: service,
185
+ Entries: entries,
186
+ }
187
+ if len(registry.schemas) > 0 {
188
+ manifest.Schemas = registry.schemas
189
+ }
190
+ return manifest
191
+ }
192
+
193
+ func (registry *Registry) MarshalManifest(baseURL string) ([]byte, error) {
194
+ return json.MarshalIndent(registry.Manifest(baseURL), "", " ")
195
+ }
196
+
197
+ func (registry *Registry) WriteManifest(writer io.Writer, baseURL string) error {
198
+ encoded, err := registry.MarshalManifest(baseURL)
199
+ if err != nil {
200
+ return err
201
+ }
202
+ if _, err := writer.Write(encoded); err != nil {
203
+ return err
204
+ }
205
+ _, err = writer.Write([]byte("\n"))
206
+ return err
207
+ }
208
+
209
+ func Object(properties map[string]any, required ...string) Schema {
210
+ schema := Schema{
211
+ "type": "object",
212
+ "properties": properties,
213
+ }
214
+ if len(required) > 0 {
215
+ schema["required"] = required
216
+ }
217
+ return schema
218
+ }
219
+
220
+ func String() Schema {
221
+ return Schema{"type": "string"}
222
+ }
223
+
224
+ func Boolean() Schema {
225
+ return Schema{"type": "boolean"}
226
+ }
227
+
228
+ func Array(items any) Schema {
229
+ return Schema{"type": "array", "items": items}
230
+ }
231
+
232
+ func lookupKey(kind EntryKind, name string) string {
233
+ return string(kind) + ":" + name
234
+ }
@@ -0,0 +1,136 @@
1
+ package forge
2
+
3
+ import (
4
+ "context"
5
+ "encoding/json"
6
+ "net/http"
7
+ )
8
+
9
+ const ProtocolVersion = "1.0"
10
+
11
+ type EntryKind string
12
+ type Risk string
13
+ type Transaction string
14
+
15
+ const (
16
+ KindCommand EntryKind = "command"
17
+ KindQuery EntryKind = "query"
18
+
19
+ RiskRead Risk = "read"
20
+ RiskWrite Risk = "write"
21
+ RiskDestructive Risk = "destructive"
22
+ RiskExternal Risk = "external"
23
+
24
+ TransactionReadOnly Transaction = "read-only"
25
+ TransactionExternalManaged Transaction = "external-managed"
26
+ TransactionForgeManaged Transaction = "forge-managed"
27
+ TransactionSaga Transaction = "saga"
28
+ )
29
+
30
+ type Schema map[string]any
31
+
32
+ type Manifest struct {
33
+ ForgeProtocol string `json:"forgeProtocol"`
34
+ Language string `json:"language"`
35
+ Framework string `json:"framework,omitempty"`
36
+ Service Service `json:"service"`
37
+ Entries []Entry `json:"entries"`
38
+ Schemas map[string]any `json:"schemas,omitempty"`
39
+ }
40
+
41
+ type Service struct {
42
+ Name string `json:"name"`
43
+ Transport string `json:"transport"`
44
+ BaseURL string `json:"baseUrl,omitempty"`
45
+ Command string `json:"command,omitempty"`
46
+ Health string `json:"health,omitempty"`
47
+ }
48
+
49
+ type Entry struct {
50
+ Name string `json:"name"`
51
+ Kind EntryKind `json:"kind"`
52
+ Description string `json:"description,omitempty"`
53
+ Path string `json:"path,omitempty"`
54
+ Method string `json:"method,omitempty"`
55
+ InputSchema any `json:"inputSchema,omitempty"`
56
+ OutputSchema any `json:"outputSchema,omitempty"`
57
+ Policy string `json:"policy,omitempty"`
58
+ TenantScoped bool `json:"tenantScoped,omitempty"`
59
+ Transaction Transaction `json:"transaction,omitempty"`
60
+ Risk Risk `json:"risk,omitempty"`
61
+ NeedsApproval *bool `json:"needsApproval,omitempty"`
62
+ Effects []string `json:"effects,omitempty"`
63
+ }
64
+
65
+ type Auth struct {
66
+ Kind string `json:"kind"`
67
+ UserID string `json:"userId,omitempty"`
68
+ TenantID string `json:"tenantId,omitempty"`
69
+ Role string `json:"role,omitempty"`
70
+ Roles []string `json:"roles,omitempty"`
71
+ Permissions []string `json:"permissions,omitempty"`
72
+ Email string `json:"email,omitempty"`
73
+ Name string `json:"name,omitempty"`
74
+ Claims map[string]any `json:"claims,omitempty"`
75
+ }
76
+
77
+ type ForgeCall struct {
78
+ Service string `json:"service"`
79
+ Entry string `json:"entry"`
80
+ Kind string `json:"kind"`
81
+ TraceID string `json:"traceId"`
82
+ }
83
+
84
+ type Context struct {
85
+ Auth Auth
86
+ Forge ForgeCall
87
+ Headers http.Header
88
+ }
89
+
90
+ type HandlerFunc func(context.Context, *Context, json.RawMessage) (any, error)
91
+
92
+ type RequestEnvelope struct {
93
+ Args json.RawMessage `json:"args"`
94
+ Auth Auth `json:"auth"`
95
+ Forge ForgeCall `json:"forge"`
96
+ }
97
+
98
+ type ResponseEnvelope struct {
99
+ OK bool `json:"ok"`
100
+ Result any `json:"result,omitempty"`
101
+ Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
102
+ Error *ErrorInfo `json:"error,omitempty"`
103
+ TraceID string `json:"traceId,omitempty"`
104
+ }
105
+
106
+ type Diagnostic struct {
107
+ Severity string `json:"severity"`
108
+ Code string `json:"code"`
109
+ Message string `json:"message"`
110
+ File string `json:"file,omitempty"`
111
+ FixHint string `json:"fixHint,omitempty"`
112
+ Docs []string `json:"docs,omitempty"`
113
+ }
114
+
115
+ type ErrorInfo struct {
116
+ Code string `json:"code"`
117
+ Message string `json:"message"`
118
+ }
119
+
120
+ func Decode(raw json.RawMessage, target any) error {
121
+ if len(raw) == 0 || string(raw) == "null" {
122
+ raw = json.RawMessage("{}")
123
+ }
124
+ return json.Unmarshal(raw, target)
125
+ }
126
+
127
+ func Handle[In any, Out any](handler func(context.Context, *Context, In) (Out, error)) HandlerFunc {
128
+ return func(ctx context.Context, call *Context, raw json.RawMessage) (any, error) {
129
+ var input In
130
+ if err := Decode(raw, &input); err != nil {
131
+ var zero Out
132
+ return zero, err
133
+ }
134
+ return handler(ctx, call, input)
135
+ }
136
+ }
@@ -0,0 +1,82 @@
1
+ # Changelog
2
+
3
+ Release history for the `forgeos` npm package (`alpha` dist-tag).
4
+
5
+ The canonical source file in the repository is `CHANGELOG.md`.
6
+
7
+ ## Unreleased
8
+
9
+ Release and packaging hardening:
10
+
11
+ - Added `forge --version` / `forge --version --json`.
12
+ - Updated `create-forgeos-app` help to read the wrapper package version instead of a hardcoded string and bumped the wrapper to `0.1.0-alpha.2`.
13
+ - Added dependency vulnerability evidence with an explicit waiver file and CI release gate.
14
+ - Updated generated web template dependencies to current Vite/plugin-react and Next majors.
15
+
16
+ ## 0.1.0-alpha.5
17
+
18
+ Release alignment for the public alpha channel:
19
+
20
+ - Added `forge ai redteam --model-level --json` with deterministic prompt-injection, secret-exfiltration, approval-bypass, cross-tenant, and indirect tool-injection probes.
21
+ - Added `forge security prove --full --json` support for source checkouts, with graceful structural-proof fallback when packaged apps do not include ForgeOS test fixtures.
22
+ - Strengthened npm publish workflows to run `security prove --db postgres --full --json`.
23
+ - Added public registry smoke coverage for `forgeos@alpha` and `create-forgeos-app@alpha`.
24
+ - Bumped the create-app wrapper package line to `create-forgeos-app@0.1.0-alpha.1`.
25
+
26
+ ## 0.1.0-alpha.4
27
+
28
+ Security assurance and release evidence hardening:
29
+
30
+ - Added value-aware telemetry redaction for known secret values in safe-looking fields, messages, details, outputs, and stack traces.
31
+ - Added webhook signature, timestamp, and replay protection helpers with Stripe/GitHub/generic HMAC coverage.
32
+ - Added HTTP tenant-isolation tests that exercise the dev server/API boundary, not only the internal runtime executor.
33
+ - Added `forge rls mutate-test --json` to kill dangerous generated RLS mutations such as missing FORCE RLS, missing policies, unconditional predicates, and `BYPASSRLS`.
34
+ - Extended `forge security prove --json` with RLS mutation proof and invariant-level evidence metadata.
35
+ - Added scripts to split security evidence by invariant and emit basic release supply-chain evidence plus CycloneDX SBOM.
36
+ - Strengthened publish/security workflows so release gates use Postgres-backed security proof, RLS mutation proof, release evidence, and SBOM generation.
37
+
38
+ ## 0.1.0-alpha.3
39
+
40
+ Native Forge AI agents on top of Vercel AI SDK v6:
41
+
42
+ - Added `aiTool` and `agent` primitives with generated `agentTools.json` / `agentTools.md`.
43
+ - Added `ctx.agent.run` and `ctx.ai.runAgent` using AI SDK `ToolLoopAgent`.
44
+ - Added auto-tools for commands, queries, and liveQueries with read-only vs approval-required writes.
45
+ - Added dev agent endpoints: `POST /ai/agents/run` and `POST /ai/agents/chat`.
46
+ - Extended `forge ai` CLI with `tools`, `agents`, and `trace` subcommands.
47
+ - Added `forge inspect agent-tools` and agent tool metadata in `agentContract.json`.
48
+ - Upgraded runtime dependency to AI SDK v6 for tool calling, streaming UI, and MCP compatibility.
49
+
50
+ Documentation:
51
+
52
+ - Added public [AI](ai.md) page and AST-aware `rename command` codemod docs.
53
+ - Full RTD expansion: [Agent Workflow](agent-workflow.md), [Frontend](frontend.md), [Security & Data](security-and-data.md), [Authoring](authoring.md), [Testing & Repair](testing-and-repair.md), [Self-Host](self-host.md), [Templates](templates.md), Material theme, search, and Mermaid diagrams.
54
+
55
+ ## 0.1.0-alpha.2
56
+
57
+ Windows and generated-app hardening:
58
+
59
+ - Fixed Node ESM handler loading on Windows by importing generated app modules through `file://` URLs across commands, queries, liveQueries, outbox actions, workflow steps, mocks, and telemetry adapters.
60
+ - Fixed `forge dev` SSE streaming on the Node HTTP fallback so liveQuery snapshots are flushed immediately instead of buffering forever.
61
+ - Hardened generated app scaffolding and web dev spawning on Windows.
62
+ - Updated the B2B support template to route frontend imports through `web/lib/forge.ts` and use safer handler input validation.
63
+ - Added focused tests for Node compatibility, template scaffolding, runtime imports, and streaming responses.
64
+ - Added `create-forgeos-app@alpha` for `npm create forgeos-app@alpha`.
65
+ - Added GitHub Packages mirror workflow for scoped package publishing.
66
+
67
+ ## 0.1.0-alpha.1
68
+
69
+ Republish alpha with the dependency/API oracle improvements:
70
+
71
+ - Added dependency API inspection commands for agents: `forge deps api`, `forge deps trace`, and `forge deps runtime-compat`.
72
+ - Added dependency API summaries to `agentContract.json`.
73
+ - Added package resolution traces, runtime compatibility metadata, and runtime/type mismatch diagnostics to `packageGraph`.
74
+ - Reduced package graph warning noise for `package.json` metadata exports, declaration-file subpaths, and pattern exports.
75
+
76
+ ## 0.1.0-alpha.0
77
+
78
+ Initial alpha packaging baseline for ForgeOS.
79
+
80
+ This release line validates npm installation, the `forge` CLI binary, template creation, generated contracts, and the agent-native local development loop.
81
+
82
+ Added Read the Docs-ready public documentation, generator/package version alignment checks, and a broad generated-app field-test harness for release hardening.