orbit-code-ai 0.1.0

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.
@@ -0,0 +1,185 @@
1
+ # Template: HTTP/REST Flow
2
+
3
+ Use this template when building a flow exposed as a REST endpoint that calls a backend service and returns a JSON response synchronously.
4
+
5
+ ---
6
+
7
+ ## Files to Create
8
+
9
+ ```
10
+ MyServiceApp/
11
+ ├── .project
12
+ ├── GetMyData.msgflow
13
+ ├── GetMyData_Compute.esql
14
+ ├── GetMyData_PrepareRequest.esql
15
+ ├── GetMyData_MapResponse.esql
16
+ └── GetMyData.json ← REST API descriptor (optional, for swagger)
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Message Flow Structure (GetMyData.msgflow)
22
+
23
+ ```
24
+ [Rest_Input_Node] ← HTTP input, parses JSON to XMLNSC
25
+ ↓ out
26
+ [PropertyReader] ← ApplicationLabel="BS_MyService", PropertiesFileName="MYSERVICE-PROPERTIES.xml"
27
+ ↓ out
28
+ [LogAudit] ← flowStart=TRUE
29
+ ↓ out
30
+ [GetMyData_Compute] ← validate input, set routing
31
+ ↓ out
32
+ [HTTPRequestAdapter] ← call backend (set IsT24Adapter=TRUE or relevant flag)
33
+ ↓ out
34
+ [HTTPResponseAdapter] ← normalize backend response
35
+ ↓ out
36
+ [GetMyData_MapResponse] ← map to ESB response structure
37
+ ↓ out
38
+ [LogOutgoingAudit] ← flowStart=FALSE
39
+ ↓ out
40
+ [HTTP Reply Node] ← return JSON response to caller
41
+
42
+ All failure terminals → [ErrorHandler] → [LogError] → [MWBusinessErrorResponse]
43
+ ```
44
+
45
+ Note: HTTP flows use `MWBusinessErrorResponse` (not `MQ_Dead_Output_Node`) on the error path.
46
+
47
+ ---
48
+
49
+ ## GetMyData_Compute.esql
50
+
51
+ ```esql
52
+ BROKER SCHEMA Qiwa.BS_MyService
53
+
54
+ CREATE COMPUTE MODULE GetMyData_Compute
55
+ CREATE FUNCTION Main() RETURNS BOOLEAN
56
+ BEGIN
57
+ CALL CopyMessageHeaders();
58
+ CALL CopyEntireMessage();
59
+
60
+ -- JSON input arrives as XMLNSC (Rest_Input_Node converts it)
61
+ DECLARE customerId CHARACTER InputRoot.XMLNSC.Root.Body.CustomerId;
62
+
63
+ -- Validate
64
+ IF customerId IS NULL OR customerId = '' THEN
65
+ SET Environment.ErrorDetails.Code = '99999999';
66
+ SET Environment.ErrorDetails.EnglishMsg = 'CustomerId is required';
67
+ RETURN FALSE;
68
+ END IF;
69
+
70
+ -- Generate correlation ID
71
+ DECLARE corrId CHARACTER;
72
+ CALL getChannelCorrelationID(
73
+ InputRoot.XMLNSC.Root.Header.ChannelId,
74
+ InputRoot.XMLNSC.Root.Header.SessionId,
75
+ corrId
76
+ );
77
+ SET OutputRoot.HTTPInputHeader.X-Correlation-Id = corrId;
78
+
79
+ RETURN TRUE;
80
+ END;
81
+ END MODULE;
82
+ ```
83
+
84
+ ---
85
+
86
+ ## GetMyData_PrepareRequest.esql
87
+
88
+ ```esql
89
+ BROKER SCHEMA Qiwa.BS_MyService
90
+
91
+ CREATE COMPUTE MODULE GetMyData_PrepareRequest
92
+ CREATE FUNCTION Main() RETURNS BOOLEAN
93
+ BEGIN
94
+ CALL CopyMessageHeaders();
95
+
96
+ -- Set target URL from properties
97
+ SET Environment.Destination.HTTP.RequestURL =
98
+ Environment.Properties.BS_MyService.GetMyData.BankIdForRoutingService.qiwa[3];
99
+
100
+ -- Build backend request payload
101
+ SET OutputRoot.XMLNSC.BackendRequest.CustomerId =
102
+ InputRoot.XMLNSC.Root.Body.CustomerId;
103
+
104
+ RETURN TRUE;
105
+ END;
106
+ END MODULE;
107
+ ```
108
+
109
+ ---
110
+
111
+ ## GetMyData_MapResponse.esql
112
+
113
+ ```esql
114
+ BROKER SCHEMA Qiwa.BS_MyService
115
+
116
+ CREATE COMPUTE MODULE GetMyData_MapResponse
117
+ CREATE FUNCTION Main() RETURNS BOOLEAN
118
+ BEGIN
119
+ CALL CopyMessageHeaders();
120
+
121
+ -- Build standard ESB response
122
+ SET OutputRoot.XMLNSC.Root.Header.ResponseStatus.Code = '00000000';
123
+ SET OutputRoot.XMLNSC.Root.Header.ResponseStatus.Status = 'Success';
124
+ SET OutputRoot.XMLNSC.Root.Header.ResponseStatus.EnglishMsg = 'Success';
125
+
126
+ -- Map business data from backend response
127
+ SET OutputRoot.XMLNSC.Root.Body.AccountBalance =
128
+ InputRoot.XMLNSC.BackendResponse.Balance;
129
+
130
+ -- Set HTTP response code
131
+ SET OutputRoot.HTTPResponseHeader."$statusCode" = 200;
132
+
133
+ RETURN TRUE;
134
+ END;
135
+ END MODULE;
136
+ ```
137
+
138
+ ---
139
+
140
+ ## MYSERVICE-PROPERTIES.xml (HTTP variant)
141
+
142
+ Same structure as MQ flow — see `templates/mq-flow.md` for full XML.
143
+
144
+ Key difference for HTTP flows — `Retry` is usually disabled:
145
+ ```xml
146
+ <group name="Retry">
147
+ <property name="RetryEnabled" value="FALSE" />
148
+ </group>
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Error Response (MWBusinessErrorResponse)
154
+
155
+ On any failure, the error handler returns:
156
+ ```json
157
+ {
158
+ "Root": {
159
+ "Header": {
160
+ "ResponseStatus": {
161
+ "Code": "99999999",
162
+ "Status": "Error",
163
+ "EnglishMsg": "Technical error occurred"
164
+ }
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ HTTP status code: `200` (ESB pattern — errors are in the payload, not HTTP status)
171
+
172
+ ---
173
+
174
+ ## Checklist for New HTTP Flow
175
+
176
+ - [ ] Create `.msgflow` with `Rest_Input_Node` as entry point
177
+ - [ ] Create Compute, PrepareRequest, MapResponse ESQL modules
178
+ - [ ] Add properties group to properties XML file
179
+ - [ ] Wire ALL failure terminals to `ErrorHandler` → `MWBusinessErrorResponse`
180
+ - [ ] Set `ApplicationLabel` and `PropertiesFileName` on `PropertyReader` node
181
+ - [ ] Set correct backend adapter flag on `HTTPRequestAdapter` node
182
+ - [ ] Set `HTTP Reply Node` as the success terminal exit
183
+ - [ ] Set `OutputRoot.HTTPResponseHeader."$statusCode"` = 200 in MapResponse
184
+ - [ ] Confirm `UserPassword` is masked in audit config
185
+ - [ ] No queue definitions needed for HTTP flows (no MQ infrastructure)
@@ -0,0 +1,248 @@
1
+ # Template: MQ Request/Response Flow
2
+
3
+ Use this template when building a new asynchronous MQ-based message flow.
4
+
5
+ ---
6
+
7
+ ## Files to Create
8
+
9
+ For a new application called `BS_MyService` with flow `GetMyData`:
10
+
11
+ ```
12
+ MyServiceApp/
13
+ ├── .project
14
+ ├── GetMyData.msgflow ← main message flow
15
+ ├── GetMyData_Compute.esql ← your business logic
16
+ ├── GetMyData_PrepareRequest.esql ← format backend request
17
+ ├── GetMyData_MapResponse.esql ← map backend response to ESB format
18
+ └── (referenced shared lib: Framework)
19
+ ```
20
+
21
+ Plus in the Framework (or a domain-specific properties file):
22
+ ```
23
+ MYSERVICE-PROPERTIES.xml
24
+ MyServiceQueuesDefinition.sh
25
+ MyServiceDBScript.sql
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Message Flow Structure (GetMyData.msgflow)
31
+
32
+ ```
33
+ [MQ_Input_Node]
34
+ ↓ out
35
+ [PropertyReader] ← ApplicationLabel="BS_MyService", PropertiesFileName="MYSERVICE-PROPERTIES.xml"
36
+ ↓ out
37
+ [LogAudit] ← flowStart=TRUE
38
+ ↓ out
39
+ [GetMyData_Compute] ← your ESQL: validate input, prepare backend call
40
+ ↓ out
41
+ [HTTPRequestAdapter] ← set IsT24Adapter=TRUE (or relevant backend flag)
42
+ ↓ out
43
+ [HTTPResponseAdapter]
44
+ ↓ out
45
+ [GetMyData_MapResponse] ← your ESQL: map backend response to Root.Header + Root.Body
46
+ ↓ out
47
+ [LogOutgoingAudit] ← flowStart=FALSE
48
+ ↓ out
49
+ [MQ_Output_Node] ← or MQ_ReplyToQ_Node for sync reply
50
+
51
+ All failure terminals → [ErrorHandler] → [LogError] → [MQ_Dead_Output_Node]
52
+ ```
53
+
54
+ ---
55
+
56
+ ## GetMyData_Compute.esql
57
+
58
+ ```esql
59
+ BROKER SCHEMA Qiwa.BS_MyService
60
+
61
+ CREATE COMPUTE MODULE GetMyData_Compute
62
+ CREATE FUNCTION Main() RETURNS BOOLEAN
63
+ BEGIN
64
+ CALL CopyMessageHeaders();
65
+ CALL CopyEntireMessage();
66
+
67
+ -- Validate required input fields
68
+ DECLARE customerId CHARACTER InputRoot.XMLNSC.Root.Body.CustomerId;
69
+ IF customerId IS NULL OR customerId = '' THEN
70
+ SET Environment.ErrorDetails.Code = '99999999';
71
+ SET Environment.ErrorDetails.EnglishMsg = 'CustomerId is required';
72
+ RETURN FALSE; -- routes to failure terminal → ErrorHandler
73
+ END IF;
74
+
75
+ -- Set correlation ID
76
+ DECLARE corrId CHARACTER;
77
+ CALL getChannelCorrelationID(
78
+ InputRoot.XMLNSC.Root.Header.ChannelId,
79
+ InputRoot.XMLNSC.Root.Header.SessionId,
80
+ corrId
81
+ );
82
+ SET OutputRoot.MQMD.CorrelId = CAST(corrId AS BLOB CCSID 1208);
83
+
84
+ RETURN TRUE;
85
+ END;
86
+ END MODULE;
87
+ ```
88
+
89
+ ---
90
+
91
+ ## GetMyData_PrepareRequest.esql
92
+
93
+ ```esql
94
+ BROKER SCHEMA Qiwa.BS_MyService
95
+
96
+ CREATE COMPUTE MODULE GetMyData_PrepareRequest
97
+ CREATE FUNCTION Main() RETURNS BOOLEAN
98
+ BEGIN
99
+ CALL CopyMessageHeaders();
100
+
101
+ -- Build backend request (adjust structure for your backend)
102
+ SET OutputRoot.XMLNSC.BackendRequest.CustomerId =
103
+ InputRoot.XMLNSC.Root.Body.CustomerId;
104
+ SET OutputRoot.XMLNSC.BackendRequest.RequestTime =
105
+ InputRoot.XMLNSC.Root.Header.RequestTime;
106
+
107
+ -- Set HTTP destination from properties
108
+ SET Environment.Destination.HTTP.RequestURL =
109
+ Environment.Properties.BS_MyService.GetMyData.BankIdForRoutingService.qiwa[3];
110
+
111
+ RETURN TRUE;
112
+ END;
113
+ END MODULE;
114
+ ```
115
+
116
+ ---
117
+
118
+ ## GetMyData_MapResponse.esql
119
+
120
+ ```esql
121
+ BROKER SCHEMA Qiwa.BS_MyService
122
+
123
+ CREATE COMPUTE MODULE GetMyData_MapResponse
124
+ CREATE FUNCTION Main() RETURNS BOOLEAN
125
+ BEGIN
126
+ CALL CopyMessageHeaders();
127
+ CALL CopyEntireMessage();
128
+
129
+ -- Map backend response to ESB standard structure
130
+ SET OutputRoot.XMLNSC.Root.Header.ResponseStatus.Code = '00000000';
131
+ SET OutputRoot.XMLNSC.Root.Header.ResponseStatus.Status = 'Success';
132
+ SET OutputRoot.XMLNSC.Root.Header.ResponseStatus.EnglishMsg = 'Success';
133
+
134
+ -- Map business data
135
+ SET OutputRoot.XMLNSC.Root.Body.AccountBalance =
136
+ InputRoot.XMLNSC.BackendResponse.Balance;
137
+ -- ... map other fields
138
+
139
+ RETURN TRUE;
140
+ END;
141
+ END MODULE;
142
+ ```
143
+
144
+ ---
145
+
146
+ ## MYSERVICE-PROPERTIES.xml
147
+
148
+ ```xml
149
+ <?xml version="1.0" encoding="UTF-8"?>
150
+ <properties refresh-policy="automatic">
151
+
152
+ <group name="BS_MyService.GetMyData">
153
+
154
+ <group name="Logging">
155
+ <property name="LogEnabled" value="TRUE" />
156
+ <property name="AuditEnabled" value="TRUE" />
157
+ <property name="MaskingEnabled" value="TRUE" />
158
+ <property name="key1" value="CUSTOMER.ID" />
159
+ <property name="value1" value="*.Body.CustomerId" />
160
+ <property name="maskingIn">
161
+ <value>*.Header.ChannelUserInfo.UserPassword</value>
162
+ </property>
163
+ <property name="maskingOut">
164
+ <value>*.Header.ChannelUserInfo.UserPassword</value>
165
+ </property>
166
+ </group>
167
+
168
+ <group name="Retry">
169
+ <property name="RetryEnabled" value="FALSE" />
170
+ <property name="maxRetryCount" value="5" />
171
+ <property name="minWaitDurationSec" value="60" />
172
+ </group>
173
+
174
+ <group name="Variables">
175
+ <property name="callCorrIDOffset" value="1" />
176
+ </group>
177
+
178
+ <group name="SchemaValidation">
179
+ <property name="ValidationEnabled" value="FALSE" />
180
+ </group>
181
+
182
+ <group name="Priority">
183
+ <property name="Priority" value="4" />
184
+ </group>
185
+
186
+ <group name="BankIdForRoutingService">
187
+ <property name="qiwa">
188
+ <value>T24</value>
189
+ <value>GetMyDataService</value>
190
+ <value>http://backend-host:port/services/GetMyData</value>
191
+ </property>
192
+ </group>
193
+
194
+ </group>
195
+
196
+ </properties>
197
+ ```
198
+
199
+ ---
200
+
201
+ ## MyServiceQueuesDefinition.sh
202
+
203
+ ```bash
204
+ #!/bin/bash
205
+ # Queue definitions for BS_MyService
206
+
207
+ runmqsc QMGR_NAME << EOF
208
+
209
+ DEFINE QLOCAL('BS.GET.MY.DATA.RQ.BACKOUT') DEFPSIST(YES) MAXDEPTH(640000) REPLACE
210
+ DEFINE QLOCAL('BS.GET.MY.DATA.RQ') DEFPSIST(YES) MAXDEPTH(640000) BOQNAME('BS.GET.MY.DATA.RQ.BACKOUT') BOTHRESH(5) REPLACE
211
+
212
+ DEFINE QLOCAL('BS.GET.MY.DATA.RS.BACKOUT') DEFPSIST(YES) MAXDEPTH(640000) REPLACE
213
+ DEFINE QLOCAL('BS.GET.MY.DATA.RS') DEFPSIST(YES) MAXDEPTH(640000) BOQNAME('BS.GET.MY.DATA.RS.BACKOUT') BOTHRESH(5) REPLACE
214
+
215
+ EOF
216
+ ```
217
+
218
+ ---
219
+
220
+ ## MyServiceDBScript.sql
221
+
222
+ ```sql
223
+ -- Register the service in routing table
224
+ INSERT INTO MCR_CHANNESBFUNC_TBL (ESBFUNCID, ESBFUNCNAME, REQUEST_QUEUE_NAME, RESPONSE_QUEUE_NAME)
225
+ VALUES ('GMYD0001', 'GET_MY_DATA', 'BS.GET.MY.DATA.RQ', 'BS.GET.MY.DATA.RS');
226
+
227
+ -- Grant channel access
228
+ INSERT INTO MCR_CHANNAUTH_TBL (CHANNID, ESBFUNCID)
229
+ VALUES ('MOBILE', 'GMYD0001');
230
+ VALUES ('WEB', 'GMYD0001');
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Checklist for New MQ Flow
236
+
237
+ - [ ] Create application project folder
238
+ - [ ] Create `.msgflow` file with all nodes wired
239
+ - [ ] Create `_Compute.esql` for input validation and routing
240
+ - [ ] Create `_PrepareRequest.esql` for backend request formatting
241
+ - [ ] Create `_MapResponse.esql` for response normalization
242
+ - [ ] Add properties group to `MYSERVICE-PROPERTIES.xml` (or create new file)
243
+ - [ ] Create queue definition shell script
244
+ - [ ] Create DB script to register service and channel auth
245
+ - [ ] Wire ALL failure terminals to `ErrorHandler`
246
+ - [ ] Set `ApplicationLabel` and `PropertiesFileName` on `PropertyReader` node
247
+ - [ ] Set correct backend adapter flag on `HTTPRequestAdapter` node
248
+ - [ ] Confirm `UserPassword` is in `maskingIn` and `maskingOut`
@@ -0,0 +1,13 @@
1
+ import { join, win32 } from 'path'
2
+ import { pathToFileURL } from 'url'
3
+
4
+ export function getDistImportSpecifier(baseDir) {
5
+ if (/^[A-Za-z]:\\/.test(baseDir)) {
6
+ const distPath = win32.join(baseDir, '..', 'dist', 'cli.mjs')
7
+ return `file:///${distPath.replace(/\\/g, '/')}`
8
+ }
9
+
10
+ const joinImpl = join
11
+ const distPath = joinImpl(baseDir, '..', 'dist', 'cli.mjs')
12
+ return pathToFileURL(distPath).href
13
+ }
@@ -0,0 +1,13 @@
1
+ import assert from 'node:assert/strict'
2
+ import test from 'node:test'
3
+
4
+ import { getDistImportSpecifier } from './import-specifier.mjs'
5
+
6
+ test('builds a file URL import specifier for dist/cli.mjs', () => {
7
+ const specifier = getDistImportSpecifier('C:\\repo\\bin')
8
+
9
+ assert.equal(
10
+ specifier,
11
+ 'file:///C:/repo/dist/cli.mjs',
12
+ )
13
+ })
package/bin/orbit ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Orbit AI — AI-powered IBM ACE coding companion
5
+ *
6
+ * If dist/cli.mjs exists (built), run that.
7
+ * Otherwise, tell the user to build first or use `bun run dev`.
8
+ */
9
+
10
+ import { existsSync } from 'fs'
11
+ import { join, dirname } from 'path'
12
+ import { fileURLToPath, pathToFileURL } from 'url'
13
+
14
+ const __dirname = dirname(fileURLToPath(import.meta.url))
15
+ const distPath = join(__dirname, '..', 'dist', 'cli.mjs')
16
+
17
+ if (existsSync(distPath)) {
18
+ await import(pathToFileURL(distPath).href)
19
+ } else {
20
+ console.error(`
21
+ orbitcode: dist/cli.mjs not found.
22
+
23
+ Build first:
24
+ bun run build
25
+
26
+ Or run directly with Bun:
27
+ bun run dev
28
+
29
+ See README.md for setup instructions.
30
+ `)
31
+ process.exit(1)
32
+ }