@aifabrix/builder 2.58.0 → 2.59.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.
- package/lib/agent-kit/codex-app-server.js +44 -0
- package/lib/agent-kit/init.js +4 -17
- package/lib/agent-kit/session-report.js +15 -10
- package/lib/agent-kit/setup-auth.js +131 -0
- package/lib/agent-kit/setup-context.js +118 -0
- package/lib/agent-kit/setup-github.js +70 -0
- package/lib/agent-kit/setup-managed.js +79 -0
- package/lib/agent-kit/setup-process.js +42 -0
- package/lib/agent-kit/setup-session.js +53 -0
- package/lib/agent-kit/setup-state.js +52 -0
- package/lib/agent-kit/setup-workspace.js +113 -0
- package/lib/agent-kit/setup.js +84 -0
- package/lib/agent-kit/start.js +4 -3
- package/lib/agent-kit/tmux-sessions.js +20 -3
- package/lib/api/dev.api.js +1 -1
- package/lib/api/miso-health.api.js +26 -0
- package/lib/api/types/dev.types.js +3 -3
- package/lib/app/deploy.js +0 -102
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-dev-path-commands.js +4 -0
- package/lib/cli/setup-dev.js +7 -4
- package/lib/cli/setup-help.js +86 -0
- package/lib/cli/setup-onboarding.js +37 -0
- package/lib/cli/setup-utility-repair.js +7 -5
- package/lib/commands/agent-kit-help.js +21 -7
- package/lib/commands/agent-kit-sessions.js +126 -0
- package/lib/commands/agent-kit-setup.js +44 -0
- package/lib/commands/agent-kit.js +5 -79
- package/lib/commands/dev-init.js +21 -23
- package/lib/commands/dev-refresh.js +2 -2
- package/lib/commands/governance-verify-external.js +12 -5
- package/lib/commands/repair-datasource.js +9 -9
- package/lib/commands/repair.js +45 -8
- package/lib/commands/upload-qualification-client.js +56 -11
- package/lib/commands/upload-qualification-poll.js +51 -22
- package/lib/commands/wizard-dataplane.js +16 -52
- package/lib/datasource/datasource-validate-summary.js +8 -5
- package/lib/datasource/sync-defaults.js +53 -0
- package/lib/deployment/installation/azure-infra-stage.js +10 -0
- package/lib/deployment/installation/azure-preflight.js +13 -2
- package/lib/deployment/installation/azure-readiness.js +24 -2
- package/lib/deployment/installation/environment-auth.js +60 -20
- package/lib/deployment/installation/environment-stage.js +9 -5
- package/lib/deployment/installation/infra-catalog.js +8 -2
- package/lib/deployment/installation/infra-manifest.js +5 -0
- package/lib/deployment/installation/registry-auth-mode.js +33 -10
- package/lib/deployment/marketplace-environment.js +26 -1
- package/lib/generator/index.js +23 -12
- package/lib/integration-definition/apply.js +2 -2
- package/lib/internal/fs-real-sync.js +4 -1
- package/lib/programmatic/bearer-auth.js +3 -62
- package/lib/programmatic/builder-api-startup.js +51 -0
- package/lib/programmatic/builder-miso-runtime.js +167 -0
- package/lib/programmatic/openapi-descriptions.js +3 -3
- package/lib/programmatic/openapi-schema-descriptions-core.js +3 -3
- package/lib/programmatic/openapi-spec.js +2 -1
- package/lib/programmatic/route-handler-map.js +3 -2
- package/lib/schema/environment-deploy-request.schema.json +1 -1
- package/lib/schema/external-datasource.schema.json +20 -5
- package/lib/schema/infra-parameter.schema.json +1 -1
- package/lib/schema/infra.parameter.yaml +2 -1
- package/lib/schema/infrastructure-schema.json +145 -1
- package/lib/schema/installation-environment.schema.json +1 -1
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/config-paths.js +24 -29
- package/lib/utils/config-registry-preference.js +13 -6
- package/lib/utils/dev-init-ssh-merge.js +5 -4
- package/lib/utils/dev-user-groups.js +2 -1
- package/lib/utils/docker-daemon-tls-ca.js +2 -2
- package/lib/utils/error-formatters/validation-errors.js +25 -5
- package/lib/utils/help-builder.js +4 -3
- package/lib/utils/token-manager.js +29 -36
- package/package.json +3 -2
- package/templates/agent-kit/instructions/AGENTKIT.md +39 -2
- package/templates/agent-kit/instructions/root.AGENTS.md +40 -1
- package/templates/agent-kit/skills/shared/hosts.md +23 -5
- package/templates/agent-kit/workspace/README.md +14 -1
- package/templates/applications/builder-api/application.yaml +1 -1
- package/templates/applications/dataplane/application.yaml +1 -1
- package/templates/applications/dataplane/env.template +1 -1
- package/templates/applications/miso-controller/application.yaml +1 -1
- package/templates/applications/miso-controller/env.template +1 -1
- package/templates/external-system/external-datasource.yaml.hbs +7 -6
- package/templates/marketplace/main.json +438 -80
|
@@ -163,16 +163,17 @@ async function mergeDevSshConfigBlock(p) {
|
|
|
163
163
|
* Update ~/.ssh/config with Host <user>.<host> for interactive SSH; log result.
|
|
164
164
|
* @param {string} baseUrl - Builder Server base URL
|
|
165
165
|
* @param {string} devId - Developer ID (digits)
|
|
166
|
+
* @param {Object} [freshSettings] - Current authenticated server settings; never mix with saved identity
|
|
166
167
|
* @returns {Promise<{ hostAlias: string|null, syncUser: string, syncHost: string|null }>}
|
|
167
168
|
*/
|
|
168
|
-
async function mergeDevSshConfigAfterInit(baseUrl, devId) {
|
|
169
|
-
const syncHost = (await config.getSyncSshHost()) || hostnameFromBaseUrl(baseUrl);
|
|
170
|
-
const syncUser = (await config.getSyncSshUser()) || `dev${devId}`;
|
|
169
|
+
async function mergeDevSshConfigAfterInit(baseUrl, devId, freshSettings) {
|
|
170
|
+
const syncHost = (freshSettings ? freshSettings['sync-ssh-host'] : await config.getSyncSshHost()) || hostnameFromBaseUrl(baseUrl);
|
|
171
|
+
const syncUser = (freshSettings ? freshSettings['sync-ssh-user'] : await config.getSyncSshUser()) || `dev${devId}`;
|
|
171
172
|
if (!syncHost) {
|
|
172
173
|
return { hostAlias: null, syncUser, syncHost: null };
|
|
173
174
|
}
|
|
174
175
|
try {
|
|
175
|
-
const rootTrimmed = trimDeveloperRootDomain(await config.getDeveloperRootDomain());
|
|
176
|
+
const rootTrimmed = trimDeveloperRootDomain(freshSettings ? freshSettings['developer-root-domain'] : await config.getDeveloperRootDomain());
|
|
176
177
|
return await mergeDevSshConfigBlock({
|
|
177
178
|
baseUrl,
|
|
178
179
|
devId,
|
|
@@ -146,7 +146,7 @@ function dockerEndpointFromRemoteServer(remoteServerUrl) {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
149
|
-
* Resolve docker-endpoint
|
|
149
|
+
* Resolve only an explicitly advertised docker-endpoint; a server hostname is not Docker access.
|
|
150
150
|
* @param {{ settings?: Object|null, remoteServerUrl?: string|null }} ctx
|
|
151
151
|
* @returns {string|null}
|
|
152
152
|
*/
|
|
@@ -156,7 +156,7 @@ function resolveDockerEndpointForCaAugment(ctx) {
|
|
|
156
156
|
if (typeof fromSettings === 'string' && fromSettings.trim()) {
|
|
157
157
|
return fromSettings.trim();
|
|
158
158
|
}
|
|
159
|
-
return
|
|
159
|
+
return null;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
/**
|
|
@@ -11,6 +11,26 @@ const { formatBlockingError } = require('../cli-test-layout-chalk');
|
|
|
11
11
|
|
|
12
12
|
const chalk = require('chalk');
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Resolves legacy application lookup codes without replacing API explanations.
|
|
16
|
+
* @param {Object|string} error - Validation error entry
|
|
17
|
+
* @returns {{message: string, applicationNotFound: boolean}} Display information
|
|
18
|
+
*/
|
|
19
|
+
function getValidationMessage(error) {
|
|
20
|
+
const message = typeof error === 'string' ? error : error.msg || error.message;
|
|
21
|
+
const code = typeof error === 'object' ? error.code : undefined;
|
|
22
|
+
const applicationNotFound = message === 'APPLICATION_NOT_FOUND' || code === 'APPLICATION_NOT_FOUND';
|
|
23
|
+
if (applicationNotFound && (!message || message === 'APPLICATION_NOT_FOUND')) {
|
|
24
|
+
return {
|
|
25
|
+
message: 'The controller could not find the application. ' +
|
|
26
|
+
'Check that it is registered on the selected controller and that its application key matches. ' +
|
|
27
|
+
'(Error code: APPLICATION_NOT_FOUND)',
|
|
28
|
+
applicationNotFound
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return { message: message || 'Invalid value', applicationNotFound };
|
|
32
|
+
}
|
|
33
|
+
|
|
14
34
|
/**
|
|
15
35
|
* Adds main error message to lines array
|
|
16
36
|
* @param {Array<string>} lines - Lines array to append to
|
|
@@ -52,7 +72,7 @@ function addValidationErrorsList(lines, errors) {
|
|
|
52
72
|
lines.push(chalk.yellow('Validation errors:'));
|
|
53
73
|
errors.forEach(err => {
|
|
54
74
|
const field = err.field || err.path || err.loc?.join('.') || 'validation';
|
|
55
|
-
const message = err
|
|
75
|
+
const { message } = getValidationMessage(err);
|
|
56
76
|
const value = err.value !== undefined ? ` (value: ${JSON.stringify(err.value)})` : '';
|
|
57
77
|
if (field === 'validation' || field === 'unknown') {
|
|
58
78
|
lines.push(chalk.gray(` • ${message}${value}`));
|
|
@@ -91,10 +111,10 @@ function addConfigurationErrors(lines, configuration) {
|
|
|
91
111
|
/**
|
|
92
112
|
* Adds actionable guidance tips to lines
|
|
93
113
|
* @param {Array<string>} lines - Lines array to append to
|
|
94
|
-
* @param {
|
|
114
|
+
* @param {Array<Object|string>} errors - Validation errors
|
|
95
115
|
*/
|
|
96
|
-
function addValidationGuidance(lines,
|
|
97
|
-
if (!
|
|
116
|
+
function addValidationGuidance(lines, errors) {
|
|
117
|
+
if (!Array.isArray(errors) || !errors.some(err => !getValidationMessage(err).applicationNotFound)) {
|
|
98
118
|
return;
|
|
99
119
|
}
|
|
100
120
|
lines.push(chalk.gray('Tips:'));
|
|
@@ -117,7 +137,7 @@ function formatValidationError(errorData) {
|
|
|
117
137
|
addValidationErrorMessage(lines, errorData);
|
|
118
138
|
addValidationErrorsList(lines, errorData.errors);
|
|
119
139
|
addConfigurationErrors(lines, errorData.configuration);
|
|
120
|
-
addValidationGuidance(lines, errorData.errors
|
|
140
|
+
addValidationGuidance(lines, errorData.errors);
|
|
121
141
|
|
|
122
142
|
if (errorData.instance) {
|
|
123
143
|
lines.push(chalk.gray(`Endpoint: ${errorData.instance}`));
|
|
@@ -17,6 +17,7 @@ const { Help } = require('commander');
|
|
|
17
17
|
* @type {Array<{ name: string, commands: Array<{ name: string, term?: string }> }>}
|
|
18
18
|
*/
|
|
19
19
|
const CATEGORIES = [
|
|
20
|
+
{ name: 'Getting Started', commands: [{ name: 'help', term: 'help [command]' }, { name: 'onboarding' }] },
|
|
20
21
|
{
|
|
21
22
|
name: 'Infrastructure (Local Development)',
|
|
22
23
|
commands: [
|
|
@@ -209,9 +210,9 @@ function formatCommandCategories(helper, program) {
|
|
|
209
210
|
for (const { term, desc: d } of lines) out.push(` ${term.padEnd(pad)}${d}`);
|
|
210
211
|
out.push('');
|
|
211
212
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
if (!program.commands.some(command => command.name() === 'help')) {
|
|
214
|
+
out.push('Help:', ` ${'help [command]'.padEnd(pad)}display help for command`, '');
|
|
215
|
+
}
|
|
215
216
|
out.push(` ${''.padEnd(pad)}Tip: aifabrix <command> --help for flags and examples`);
|
|
216
217
|
out.push('');
|
|
217
218
|
return out;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
const config = require('../core/config');
|
|
13
13
|
const logger = require('./logger');
|
|
14
|
+
const { maskSensitiveData } = require('./log-redaction');
|
|
14
15
|
const {
|
|
15
16
|
refreshClientToken,
|
|
16
17
|
refreshDeviceToken
|
|
@@ -99,55 +100,47 @@ async function getOrRefreshClientToken(environment, appName, controllerUrl) {
|
|
|
99
100
|
* @returns {Promise<{token: string, controller: string}|null>} Token and controller URL, or null if not available
|
|
100
101
|
*/
|
|
101
102
|
async function getOrRefreshDeviceToken(controllerUrl) {
|
|
102
|
-
// Try to get existing token
|
|
103
103
|
const tokenInfo = await getDeviceToken(controllerUrl);
|
|
104
|
-
|
|
105
|
-
if (!tokenInfo) {
|
|
106
|
-
return
|
|
104
|
+
if (!tokenInfo) return null;
|
|
105
|
+
if (reusableDeviceToken(tokenInfo) && !shouldRefreshToken(tokenInfo.expiresAt)) {
|
|
106
|
+
return reusableDeviceToken(tokenInfo);
|
|
107
107
|
}
|
|
108
|
-
|
|
109
|
-
// Check if token should be refreshed proactively (within 15 minutes of expiry)
|
|
110
|
-
// This ensures we refresh before Keycloak's SSO Session Idle timeout (30 minutes)
|
|
111
|
-
const needsRefresh = shouldRefreshToken(tokenInfo.expiresAt);
|
|
112
|
-
|
|
113
|
-
if (!needsRefresh) {
|
|
114
|
-
// Token is valid and doesn't need refresh yet
|
|
115
|
-
return {
|
|
116
|
-
token: tokenInfo.token,
|
|
117
|
-
controller: tokenInfo.controller
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Token needs refresh (expired or within 15 minutes of expiry)
|
|
122
|
-
// Try to refresh if refresh token exists
|
|
123
108
|
if (!tokenInfo.refreshToken) {
|
|
124
|
-
const
|
|
125
|
-
if (!
|
|
126
|
-
|
|
127
|
-
'Access token expired and no refresh token available. Please login again using: aifabrix login'
|
|
128
|
-
);
|
|
109
|
+
const usable = reusableDeviceToken(tokenInfo);
|
|
110
|
+
if (!usable) {
|
|
111
|
+
warnRefreshFailureOnce(controllerUrl, 'No usable access token and no refresh token available. Please login again using: aifabrix login');
|
|
129
112
|
}
|
|
130
|
-
return
|
|
113
|
+
return usable;
|
|
131
114
|
}
|
|
132
|
-
|
|
133
115
|
try {
|
|
134
116
|
const refreshed = await refreshDeviceToken(controllerUrl, tokenInfo.refreshToken);
|
|
135
|
-
return {
|
|
136
|
-
token: refreshed.token,
|
|
137
|
-
controller: controllerUrl
|
|
138
|
-
};
|
|
117
|
+
return { token: refreshed.token, controller: controllerUrl };
|
|
139
118
|
} catch (error) {
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
119
|
+
let message = error.message || String(error);
|
|
120
|
+
for (const secret of [tokenInfo.token, tokenInfo.refreshToken]) {
|
|
121
|
+
if (secret) message = message.split(secret).join('***');
|
|
122
|
+
}
|
|
123
|
+
message = maskSensitiveData(message);
|
|
124
|
+
if (message.includes('Refresh token has expired')) {
|
|
125
|
+
warnRefreshTokenExpiredOnce(controllerUrl, message);
|
|
144
126
|
} else {
|
|
145
|
-
warnRefreshFailureOnce(controllerUrl,
|
|
127
|
+
warnRefreshFailureOnce(controllerUrl, message);
|
|
146
128
|
}
|
|
147
|
-
return
|
|
129
|
+
return reusableDeviceToken(tokenInfo);
|
|
148
130
|
}
|
|
149
131
|
}
|
|
150
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Reuse only a token whose actual expiry is known and still in the future.
|
|
135
|
+
* @param {Object} tokenInfo - Stored device token
|
|
136
|
+
* @returns {Object|null} Usable token, without refresh credentials
|
|
137
|
+
*/
|
|
138
|
+
function reusableDeviceToken(tokenInfo) {
|
|
139
|
+
const expiry = typeof tokenInfo.expiresAt === 'string' ? Date.parse(tokenInfo.expiresAt) : NaN;
|
|
140
|
+
return tokenInfo.token && Number.isFinite(expiry) && expiry > Date.now()
|
|
141
|
+
? { token: tokenInfo.token, controller: tokenInfo.controller } : null;
|
|
142
|
+
}
|
|
143
|
+
|
|
151
144
|
/**
|
|
152
145
|
* Validates deployment auth parameters
|
|
153
146
|
* @function validateDeploymentAuthParams
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aifabrix/builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.59.0",
|
|
4
4
|
"description": "AI Fabrix Builder — CLI and developer scripts (pnpm + af)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -131,7 +131,8 @@
|
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
133
|
"dependencies": {
|
|
134
|
-
"@aifabrix/miso-client": "4.
|
|
134
|
+
"@aifabrix/miso-client": "4.23.1",
|
|
135
|
+
"@azure/identity": "4.11.1",
|
|
135
136
|
"adm-zip": "^0.6.0",
|
|
136
137
|
"ajv": "^8.20.0",
|
|
137
138
|
"ajv-formats": "^3.0.1",
|
|
@@ -2,6 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
Builder-owned. `aifabrix agent-kit update` refreshes this file. If workspace `README.md` is missing, install/update creates it. An existing README is never overwritten.
|
|
4
4
|
|
|
5
|
+
## Onboard
|
|
6
|
+
|
|
7
|
+
On an organisation-managed SSH workspace with a provisioned `config.yaml`:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
af onboarding
|
|
11
|
+
af onboarding --coding claude # or codex or cursor for this run
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
For Claude, onboarding starts or reuses a detached tmux session and prints
|
|
15
|
+
its attach command. For Codex or Cursor, open the printed workspace in the
|
|
16
|
+
selected coding client over SSH, then say “Hi”. `--coding` selects a platform
|
|
17
|
+
for one run without changing the provisioned default.
|
|
18
|
+
The agent reads this workspace's `AGENTS.md` and `README.md`, checks which
|
|
19
|
+
packages already exist, and guides you to a first delivery task.
|
|
20
|
+
|
|
21
|
+
On a Linux or macOS terminal with Builder, Git, and tmux:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
aifabrix agent-kit setup https://controller.example.com
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This prepares a local workspace under the configured AI Fabrix work directory and starts
|
|
28
|
+
Codex. Select Claude with `--code claude`. GitHub is optional: add `--repo owner/name`
|
|
29
|
+
to reuse a matching local checkout, clone a remote, or create a private repository.
|
|
30
|
+
The repository name becomes the folder name; unresolved access stops safely.
|
|
31
|
+
Setup preserves existing agent permissions. Change environment afterward with
|
|
32
|
+
`aifabrix auth --set-environment <environment>`.
|
|
33
|
+
|
|
5
34
|
## Install
|
|
6
35
|
|
|
7
36
|
From this git repository (Builder CLI on PATH):
|
|
@@ -57,7 +86,12 @@ curl -fsSL https://claude.ai/install.sh | bash
|
|
|
57
86
|
claude auth login
|
|
58
87
|
```
|
|
59
88
|
|
|
60
|
-
**
|
|
89
|
+
**Optional terminal session in tmux:** run from this workspace so closing the
|
|
90
|
+
terminal does not kill Claude. The command enables Remote Control and this
|
|
91
|
+
workspace's Claude auto-approval by default. Remote Control is the **same**
|
|
92
|
+
session on this PC, [claude.ai/code](https://claude.ai/code), and the Claude
|
|
93
|
+
mobile app (Code). That is not `claude --cloud` (a separate cloud VM). Claude
|
|
94
|
+
`--tmux` is for worktrees only.
|
|
61
95
|
|
|
62
96
|
```bash
|
|
63
97
|
aifabrix agent-kit start claude
|
|
@@ -76,7 +110,10 @@ npm install -g @openai/codex
|
|
|
76
110
|
codex login
|
|
77
111
|
```
|
|
78
112
|
|
|
79
|
-
**
|
|
113
|
+
**Optional terminal session in tmux:** run from this workspace so a terminal
|
|
114
|
+
Codex session stays after SSH disconnects. This session is separate from a
|
|
115
|
+
Codex app chat opened over SSH. The command requests native Codex Remote
|
|
116
|
+
Control and writes workspace auto-approval by default:
|
|
80
117
|
|
|
81
118
|
```bash
|
|
82
119
|
aifabrix agent-kit start codex
|
|
@@ -14,6 +14,44 @@ Do not edit platform product source (`aifabrix-dataplane`, `aifabrix-miso`, `aif
|
|
|
14
14
|
|
|
15
15
|
Vendor limits, tenant ids, credentials, PII stance, partitions, and the designated mutation subject live only in `integration/<systemKey>/README.md`.
|
|
16
16
|
|
|
17
|
+
## First greeting
|
|
18
|
+
|
|
19
|
+
On a first “Hi”, start with the business problem in plain language. Explain
|
|
20
|
+
that their process, people, outcome, systems, and a real example become a plan,
|
|
21
|
+
Connected Systems, a Role Assistant, and proof. Show these skills in a table:
|
|
22
|
+
|
|
23
|
+
| Skill | How it helps |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| aifabrix-plan | Turn the business context or spec into a plan; ask about gaps |
|
|
26
|
+
| aifabrix-connected-system | Validate, build, test, and publish needed systems |
|
|
27
|
+
| aifabrix-role-assistant | Create or update a catalog role using published systems |
|
|
28
|
+
| aifabrix-prove | Test a real business example and record the result |
|
|
29
|
+
|
|
30
|
+
Render skill names with `$` in Codex and `/` in Claude Code or Cursor. Do not
|
|
31
|
+
run CLI commands or lead with inventory, sign-in, or gates on this first reply.
|
|
32
|
+
|
|
33
|
+
Ask one opening question: what business process or role should we help, and
|
|
34
|
+
what should improve? Invite a spec, API document, sample payload, or example
|
|
35
|
+
workflow if they have one. Say a plain-language description is enough to start;
|
|
36
|
+
missing details will become explicit questions. Keep the greeting brief.
|
|
37
|
+
|
|
38
|
+
## After the business context
|
|
39
|
+
|
|
40
|
+
Before planning or using online Builder commands, check the workspace and
|
|
41
|
+
sign-in. Run `aifabrix auth status`; if signed out, follow
|
|
42
|
+
`.agents/skills/shared/login.md` and ask for the Controller URL only if needed.
|
|
43
|
+
Read `README.md` and list package folder names under `integration/` and
|
|
44
|
+
`role-assistant/`; do not open package data or secrets for discovery. If signed
|
|
45
|
+
in, run `aifabrix list` to find remote systems. If listing fails, report the
|
|
46
|
+
failure; do not infer that there are no systems. Distinguish local packages
|
|
47
|
+
from remote entries, and published Connected Systems from drafts, Role
|
|
48
|
+
Assistants, and Enterprise Knowledge. Never print tokens.
|
|
49
|
+
|
|
50
|
+
Then suggest the relevant skill from the first table and explain its gate.
|
|
51
|
+
Summarize sign-in and discovery only as needed for the chosen work; give at
|
|
52
|
+
most two relevant remote examples unless asked for the
|
|
53
|
+
full list. Do not print email, IDs, URLs, or versions in a routine status.
|
|
54
|
+
|
|
17
55
|
## Secrets
|
|
18
56
|
|
|
19
57
|
Use `kv://` and `aifabrix secret`. Never store, print, ask for, or commit secret values.
|
|
@@ -27,7 +65,8 @@ Do not collapse these into a generic success boolean. Do not start the next life
|
|
|
27
65
|
|
|
28
66
|
## Coding hosts
|
|
29
67
|
|
|
30
|
-
Cursor, Claude Code, and Codex — local
|
|
68
|
+
Cursor, Claude Code, and Codex — local or remote SSH projects, with optional
|
|
69
|
+
tmux terminal sessions: `.agents/skills/shared/hosts.md`.
|
|
31
70
|
Install and sign-in: `AGENTKIT.md`. Builder CLI login from chat: `.agents/skills/shared/login.md`.
|
|
32
71
|
|
|
33
72
|
## Docs
|
|
@@ -6,6 +6,11 @@ Install and sign-in steps are in `AGENTKIT.md`. This file is how to **run** each
|
|
|
6
6
|
|
|
7
7
|
Do not start Claude or Codex in your home directory. `cd` into this git workspace first.
|
|
8
8
|
|
|
9
|
+
For first-time terminal onboarding, run `aifabrix agent-kit setup <controllerUrl>`.
|
|
10
|
+
It creates a local workspace under AI Fabrix work and starts Codex; use `--code claude`
|
|
11
|
+
to select Claude. GitHub is optional through `--repo owner/name`. Setup preserves
|
|
12
|
+
permission settings; the standalone start defaults below remain separate.
|
|
13
|
+
|
|
9
14
|
## Auto-approve
|
|
10
15
|
|
|
11
16
|
`aifabrix agent-kit install` can write gitignored host configs so Claude Code and Codex do not prompt for every tool:
|
|
@@ -23,7 +28,11 @@ Those files stay in **this workspace**. Claude may **read** files under the deve
|
|
|
23
28
|
|
|
24
29
|
## Claude Code
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
On a managed host, `af onboarding --coding claude` starts or reuses a detached
|
|
32
|
+
Claude tmux session and prints how to attach. Its Remote Control session is
|
|
33
|
+
available from the same Claude account when supported.
|
|
34
|
+
|
|
35
|
+
**Optional terminal session — tmux.** When you choose a terminal workflow, Agent Kit starts Claude **inside tmux**, with Remote Control and workspace auto-approval enabled by default. Remote Control is the **same** session on this PC, [claude.ai/code](https://claude.ai/code), and the Claude mobile app (**Code**). Do not use `claude --cloud` for this — that starts a different machine that clones GitHub. Claude `--tmux` is only for `--worktree` sessions, not this wrapper.
|
|
27
36
|
|
|
28
37
|
```bash
|
|
29
38
|
aifabrix agent-kit start claude
|
|
@@ -37,13 +46,21 @@ Closing the terminal (or SSH) does not stop a tmux session. Stopping tmux or the
|
|
|
37
46
|
|
|
38
47
|
## Codex
|
|
39
48
|
|
|
40
|
-
**
|
|
49
|
+
**Remote SSH project.** Open the workspace printed by `af onboarding` in the
|
|
50
|
+
Codex app. The app's server connection runs separately from tmux, so no tmux
|
|
51
|
+
session is needed for that chat.
|
|
52
|
+
|
|
53
|
+
**Optional terminal session — tmux and Remote Control.** tmux keeps a separate
|
|
54
|
+
terminal Codex session running if you disconnect SSH. `agent-kit start codex`
|
|
55
|
+
also requests Codex's native Remote Control by default; the npm-installed CLI
|
|
56
|
+
may require `--no-remote-control` because the daemon needs Codex's standalone
|
|
57
|
+
installer.
|
|
41
58
|
|
|
42
59
|
```bash
|
|
43
60
|
aifabrix agent-kit start codex
|
|
44
61
|
```
|
|
45
62
|
|
|
46
|
-
Default `--name` is the last folder. `--no-remote-control`
|
|
63
|
+
Default `--name` is the last folder. `--no-remote-control` skips that daemon; `--skip-approve-all` leaves Codex permissions unchanged. If that session already exists, `start` fails with list/kill guidance. Detach: `Ctrl-b` then `d`. Reattach with `tmux attach -t aifabrix-docs`. Then `$aifabrix-plan` (and the other `$aifabrix-*` skills). Codex reads `AGENTS.md`. A separate Codex app server used by a desktop SSH chat appears in `agent-kit list` and the interactive `agent-kit kill` menu; stopping it requires confirmation and may disconnect the chat. `codex remote-control stop` only controls a standalone-managed daemon.
|
|
47
64
|
|
|
48
65
|
**Foreground only (no tmux).**
|
|
49
66
|
|
|
@@ -58,8 +75,9 @@ codex
|
|
|
58
75
|
| --- | --- |
|
|
59
76
|
| New named session | `tmux new -s <name> -c /path/to/this-workspace` |
|
|
60
77
|
| Detach (leave it running) | `Ctrl-b`, then `d` |
|
|
61
|
-
| List sessions | `aifabrix agent-kit list` |
|
|
78
|
+
| List sessions; choose tmux to attach or Close | `aifabrix agent-kit list` |
|
|
62
79
|
| Attach | `tmux attach -t <name>` |
|
|
63
|
-
|
|
|
80
|
+
| Stop tmux by name | `aifabrix agent-kit kill <name>` |
|
|
81
|
+
| Choose a tmux session or Codex app server to stop | `aifabrix agent-kit kill` |
|
|
64
82
|
|
|
65
83
|
Use a different `--name` per workspace so several Claude or Codex sessions can run on the same host. Claude and Codex in the **same** folder also need two names.
|
|
@@ -8,8 +8,21 @@ Vendor limits, credentials, designated test subjects, and PII live only in each
|
|
|
8
8
|
|
|
9
9
|
## How to start
|
|
10
10
|
|
|
11
|
+
You can say **“Hi”** in a new agent chat. Describe the business process or
|
|
12
|
+
role you want to improve and the result you need; a plain-language example is
|
|
13
|
+
enough to start. The agent will map that context to Connected Systems, a Role
|
|
14
|
+
Assistant, and a way to prove the result. It checks sign-in and existing
|
|
15
|
+
systems before planning the work.
|
|
16
|
+
|
|
17
|
+
| Claude Code / Cursor | Codex | What the skill guides |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| `/aifabrix-plan` | `$aifabrix-plan` | Turn business context or a spec into a plan and identify missing facts |
|
|
20
|
+
| `/aifabrix-connected-system` | `$aifabrix-connected-system` | Validate, build, test, and publish Connected Systems |
|
|
21
|
+
| `/aifabrix-role-assistant` | `$aifabrix-role-assistant` | Create or update a catalog Role Assistant using published systems |
|
|
22
|
+
| `/aifabrix-prove` | `$aifabrix-prove` | Prove a real business case and record the result |
|
|
23
|
+
|
|
11
24
|
1. Open **this folder** in Cursor, Claude Code, or Codex. Host install and sign-in: **[AGENTKIT.md](./AGENTKIT.md)**.
|
|
12
|
-
2.
|
|
25
|
+
2. Before planning or using online Builder commands, the agent checks `aifabrix auth status`. If you are not signed in, it asks for the Miso Controller URL and gives you a browser link. You do not need a terminal. Details: **[AGENTKIT.md](./AGENTKIT.md)**.
|
|
13
26
|
3. In chat, either **invoke a skill** or **paste a prompt** from the tables below. Work in order. Wait for the gate (`PLAN_READY`, `READY`, `BUILT`, then `PASS` or `PASS_WITH_SKIPS`) before the next step.
|
|
14
27
|
|
|
15
28
|
### How to use prompts
|
|
@@ -5,7 +5,7 @@ app:
|
|
|
5
5
|
description: 'Business Transformation services — HTTP orchestration for connected-system workspace lifecycle via Dataplane Enterprise MCP and governance APIs.'
|
|
6
6
|
type: webapp
|
|
7
7
|
language: typescript
|
|
8
|
-
version:
|
|
8
|
+
version: 2.59.0
|
|
9
9
|
|
|
10
10
|
# Image Configuration
|
|
11
11
|
image:
|
|
@@ -5,7 +5,7 @@ app:
|
|
|
5
5
|
description: "AI Fabrix Dataplane is a secure, in-tenant integration and automation layer that supplies governed, normalized, and explainable enterprise data to AI agents. Using CIP as a declarative standard, it enforces RBAC and ABAC, executes integrations, and exposes trusted data via MCP and OpenAPI."
|
|
6
6
|
type: webapp
|
|
7
7
|
language: python # Explicitly specify Python language
|
|
8
|
-
version: 2.0.
|
|
8
|
+
version: 2.0.71
|
|
9
9
|
# Image Configuration
|
|
10
10
|
# Set tag to match your build (example: aifabrix build dataplane -t 1.0.0).
|
|
11
11
|
# Registry is required so the controller can pull the image (avoids docker-not-found on the controller host).
|
|
@@ -44,7 +44,7 @@ API_KEY_BYPASS_ROLES=full-access
|
|
|
44
44
|
|
|
45
45
|
# API Configuration
|
|
46
46
|
API_V1_STR=/api/v1
|
|
47
|
-
VERSION=2.0.
|
|
47
|
+
VERSION=2.0.71
|
|
48
48
|
# Minimum supported aifabrix-builder CLI semver (advertised on /health and /api/v1/health; empty = no gate)
|
|
49
49
|
# MIN_BUILDER_CLI_VERSION=2.45.0
|
|
50
50
|
MIN_BUILDER_CLI_VERSION=2.45.5
|
|
@@ -4,7 +4,7 @@ app:
|
|
|
4
4
|
displayName: 'Miso Controller'
|
|
5
5
|
description: 'Miso is the AI Fabrix in-tenant controller and portal layer for securely operating enterprise AI apps inside a customer’s Azure tenant. It provides Entra ID SSO, RBAC, audit logs, environment/app configuration via schemas, and safe secret handling via Key Vault references—ensuring governance, traceability, and predictable UX across portal, SDK, and CLI.'
|
|
6
6
|
type: webapp
|
|
7
|
-
version: '2.0.
|
|
7
|
+
version: '2.0.82'
|
|
8
8
|
# Image Configuration
|
|
9
9
|
# Set tag to match your build (e.g. aifabrix build miso-controller -t 1.0.0 then tag: 1.0.0)
|
|
10
10
|
# Registry is required so the controller can pull the image (avoids "docker: not found" on the controller host).
|
|
@@ -46,7 +46,7 @@ SKIP_FIRST_TIME_SETUP=false
|
|
|
46
46
|
ONBOARDING_CONTROLLER_KEY=miso-controller
|
|
47
47
|
|
|
48
48
|
# Infrastructure/service name used by controller/onboarding flows
|
|
49
|
-
INFRASTRUCTURE_NAME
|
|
49
|
+
INFRASTRUCTURE_NAME=${DEV_USERNAME}.${DEV_ROOT_DOMAIN}
|
|
50
50
|
|
|
51
51
|
# Azure region (required for first-time onboarding: controller record / provisioning metadata).
|
|
52
52
|
# Use the region you deploy to (e.g. westeurope, eastus, northeurope). Single env name: LOCATION.
|
|
@@ -98,7 +98,7 @@ openapi:
|
|
|
98
98
|
|
|
99
99
|
# --- Optional sections: uncomment or delete as needed ---
|
|
100
100
|
#
|
|
101
|
-
# Query-time
|
|
101
|
+
# Query-time: public list/get/filter are served from persisted Dataplane DB — not live external HTTP on every read.
|
|
102
102
|
# External APIs: sync jobs and create/update/delete execution paths. CIP fetch→map is for ingestion, writes, or orchestration — populate storage before expecting query APIs.
|
|
103
103
|
#
|
|
104
104
|
# CIP (Composable Integration Pipeline): fetch → [paginate] → [map] → [filter] → output
|
|
@@ -106,12 +106,13 @@ openapi:
|
|
|
106
106
|
# execution.cip requires version "1.0" and operations.<name>.steps ($defs.cipDefinition). Custom operation keys must match the same pattern as capabilities[].
|
|
107
107
|
#
|
|
108
108
|
{{#if (eq schemaEntityType "recordStorage")}}
|
|
109
|
-
# sync: external APIs run during
|
|
109
|
+
# sync: external APIs run during synchronization. New automatic schedules default to calendar-month cadence in UTC.
|
|
110
|
+
# Omit schedule to retain manual-only synchronization. Set enabled: false for total synchronization disable; retained schedule and incremental settings are preserved.
|
|
110
111
|
# sync:
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
112
|
+
# enabled: true
|
|
113
|
+
# mode: pull
|
|
114
|
+
# schedule: "@monthly"
|
|
115
|
+
# batchSize: 500
|
|
115
116
|
# validation: structural / pre-persistence checks; quality: post-mapping acceptance (e.g. rejectIf) — see schema when you enable them.
|
|
116
117
|
# capabilities: standard names list, get, create, update, delete + custom names matching ^[a-z][a-zA-Z0-9]*$; must match execution.cip.operations / openapi.operations you implement.
|
|
117
118
|
# capabilities: [list, get]
|