@aifabrix/builder 2.54.1 → 2.55.2
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/README.md +8 -0
- package/lib/agent-kit/apply-ops.js +82 -0
- package/lib/agent-kit/checksums.js +28 -0
- package/lib/agent-kit/classify.js +113 -0
- package/lib/agent-kit/claude-shim.js +61 -0
- package/lib/agent-kit/constants.js +55 -0
- package/lib/agent-kit/file-list.js +103 -0
- package/lib/agent-kit/host-approve.js +172 -0
- package/lib/agent-kit/hosting/github.js +63 -0
- package/lib/agent-kit/hosts.js +71 -0
- package/lib/agent-kit/init.js +319 -0
- package/lib/agent-kit/kit-root.js +17 -0
- package/lib/agent-kit/managed-section.js +79 -0
- package/lib/agent-kit/package-load.js +45 -0
- package/lib/agent-kit/plan-ops.js +69 -0
- package/lib/agent-kit/remote-prompts.js +272 -0
- package/lib/agent-kit/render-host-markdown.js +40 -0
- package/lib/agent-kit/repo-guard.js +47 -0
- package/lib/agent-kit/report.js +107 -0
- package/lib/agent-kit/run.js +82 -0
- package/lib/agent-kit/scm/git.js +122 -0
- package/lib/agent-kit/start.js +310 -0
- package/lib/agent-kit/state-file.js +83 -0
- package/lib/agent-kit/status.js +50 -0
- package/lib/agent-kit/v1-detect.js +81 -0
- package/lib/agent-kit/validate-kit.js +87 -0
- package/lib/agent-kit/workspace-name.js +40 -0
- package/lib/agent-kit/workspace-skeleton.js +103 -0
- package/lib/api/role-assistant-test-pack.api.js +86 -0
- package/lib/api/work-search.api.js +31 -4
- package/lib/api/work.api.js +19 -12
- package/lib/app/deploy.js +7 -4
- package/lib/app/list-external-systems.js +2 -1
- package/lib/app/offer-create-from-template.js +184 -0
- package/lib/app/show-display.js +33 -6
- package/lib/app/show.js +25 -2
- package/lib/channels/add-channel.js +1 -0
- package/lib/channels/approval-guides/claude.js +2 -2
- package/lib/channels/channel-add-failure.js +1 -0
- package/lib/channels/channel-add-remaining.js +15 -9
- package/lib/channels/channel-definition-status.js +115 -0
- package/lib/channels/channel-description.js +2 -1
- package/lib/channels/channel-install-envelope.js +4 -2
- package/lib/channels/channel-integration-generator.js +2 -0
- package/lib/channels/channel-runtime-resolver.js +14 -0
- package/lib/channels/channel-targets.js +31 -5
- package/lib/channels/claude-setup-values.js +4 -1
- package/lib/channels/slack-channel-add.js +59 -6
- package/lib/channels/slack-mcp-callback.js +51 -0
- package/lib/channels/slack-mcp-runtime.js +156 -0
- package/lib/channels/slack-provisioning/install-cli.js +14 -2
- package/lib/channels/slack-provisioning/with-curl-on-path.js +6 -1
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-app.js +8 -1
- package/lib/cli/setup-auth.js +11 -2
- package/lib/cli/setup-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +3 -1
- package/lib/commands/agent-kit-help.js +149 -0
- package/lib/commands/agent-kit.js +417 -0
- package/lib/commands/auth-status-user.js +99 -0
- package/lib/commands/auth-status.js +14 -4
- package/lib/commands/channel-add-help.js +5 -5
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- package/lib/commands/datasource-load-export-cli.js +7 -2
- package/lib/commands/datasource-test-trust-cli.js +5 -1
- package/lib/commands/governance-command-action.js +5 -4
- package/lib/commands/identity-membership-role-cache.js +6 -1
- package/lib/commands/lifecycle-command-action.js +16 -15
- package/lib/commands/login-credentials.js +8 -3
- package/lib/commands/login-device.js +14 -5
- package/lib/commands/login.js +14 -1
- package/lib/commands/logout.js +50 -15
- package/lib/commands/repair-auth-apply.js +1 -1
- package/lib/commands/repair-datasource-key-skip.js +39 -0
- package/lib/commands/repair-datasource-keys.js +24 -12
- package/lib/commands/repair-rbac.js +16 -10
- package/lib/commands/role-assistant-copy-output.js +61 -0
- package/lib/commands/role-assistant-copy.js +155 -0
- package/lib/commands/role-assistant-test-output.js +8 -9
- package/lib/commands/role-assistant-test-result-rows.js +42 -0
- package/lib/commands/role-assistant.js +140 -59
- package/lib/commands/search.js +143 -0
- package/lib/commands/test-trust-external.js +7 -5
- package/lib/commands/upload-sidecar-followups.js +4 -1
- package/lib/commands/verify-governance-command-action.js +9 -7
- package/lib/commands/verify-operations-command-action.js +9 -8
- package/lib/commands/verify-operations-skip-e2e.js +131 -0
- package/lib/commands/verify-operations-step-plan.js +6 -33
- package/lib/commands/verify-operations-steps.js +3 -1
- package/lib/commands/verify-trust-command-action.js +6 -5
- package/lib/datasource/capability/relate-operations.js +28 -10
- package/lib/datasource/capability/run-capability-relate.js +48 -25
- package/lib/datasource/datasource-identifier.js +13 -5
- package/lib/deployment/deployer-poll-run.js +117 -35
- package/lib/external-system/deploy-dataplane-published.js +70 -0
- package/lib/external-system/deploy.js +12 -2
- package/lib/external-system/download-role-assistant.js +41 -15
- package/lib/external-system/download.js +8 -3
- package/lib/generator/helpers.js +12 -1
- package/lib/generator/wizard-datasource-key.js +54 -0
- package/lib/generator/wizard.js +55 -54
- package/lib/integration-definition/apply-datasource-keys.js +75 -0
- package/lib/integration-definition/apply-relationships.js +195 -0
- package/lib/integration-definition/apply-static-enterprise.js +232 -0
- package/lib/integration-definition/apply-system-file.js +71 -0
- package/lib/integration-definition/apply-test-endpoint.js +89 -0
- package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
- package/lib/integration-definition/apply.js +78 -59
- package/lib/integration-definition/enrich-openapi-operations.js +36 -10
- package/lib/integration-definition/enrich-openapi-pick.js +87 -0
- package/lib/lifecycle/role-assistant-governance.js +56 -21
- package/lib/programmatic/capability-registry.js +1 -0
- package/lib/programmatic/index.js +2 -0
- package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +4 -1
- package/lib/programmatic/openapi-component-schemas.js +1 -0
- package/lib/programmatic/openapi-descriptions.js +9 -3
- package/lib/programmatic/openapi-envelope-examples.js +7 -0
- package/lib/programmatic/openapi-operation-bindings.js +5 -0
- package/lib/programmatic/openapi-request-schemas.js +5 -0
- package/lib/programmatic/openapi-schema-descriptions-channel.js +8 -5
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/openapi-spec.js +1 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +7 -0
- package/lib/programmatic/run-channel-catalog.js +50 -8
- package/lib/programmatic/run-channel-install-options.js +5 -1
- package/lib/programmatic/run-download.js +41 -0
- package/lib/protection/auth-context.js +3 -1
- package/lib/protection/protection-display.js +3 -2
- package/lib/protection/report-exit.js +50 -0
- package/lib/protection/run-commands.js +2 -0
- package/lib/role-assistant/knowledge-sync-settings-push.js +172 -0
- package/lib/role-assistant/knowledge-sync.js +9 -126
- package/lib/role-assistant/package-validate.js +175 -0
- package/lib/role-assistant/test-case-assertion-row.js +36 -0
- package/lib/role-assistant/test-case-copy-bind.js +77 -0
- package/lib/role-assistant/test-case-copy-expected.js +127 -0
- package/lib/role-assistant/test-case-copy-from-work.js +90 -0
- package/lib/role-assistant/test-case-copy-interactions.js +67 -0
- package/lib/role-assistant/test-case-copy.js +119 -0
- package/lib/role-assistant/test-case-expected-catalog.js +135 -0
- package/lib/role-assistant/test-case-validate.js +88 -0
- package/lib/role-assistant/test-cases-bid.js +117 -4
- package/lib/role-assistant/test-cases-evaluate.js +149 -31
- package/lib/role-assistant/test-cases-evidence.js +44 -5
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +297 -0
- package/lib/role-assistant/test-cases-search-graph.js +122 -0
- package/lib/role-assistant/test-cases-search.js +20 -2
- package/lib/role-assistant/test-cases.js +34 -168
- package/lib/role-assistant/test-pack-map.js +180 -0
- package/lib/role-assistant/test-pack-sync.js +187 -0
- package/lib/role-assistant/test-runner-debug.js +54 -0
- package/lib/role-assistant/test-runner-respond-body.js +36 -0
- package/lib/role-assistant/test-runner-search.js +20 -5
- package/lib/role-assistant/test-runner-start-payload.js +63 -10
- package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
- package/lib/role-assistant/test-runner-workhub.js +45 -21
- package/lib/role-assistant/test-runner.js +53 -10
- package/lib/schema/external-datasource.schema.json +36 -5
- package/lib/schema/external-system.schema.json +20 -2
- package/lib/schema/infra-parameter.schema.json +51 -3
- package/lib/schema/infra.parameter.yaml +476 -40
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- package/lib/schema/type/document-storage.json +1 -1
- package/lib/search/dataplane-context.js +23 -0
- package/lib/search/search-args.js +211 -0
- package/lib/search/search-display.js +238 -0
- package/lib/search/search-errors.js +50 -0
- package/lib/search/search-prompts.js +119 -0
- package/lib/search/search-roles.js +85 -0
- package/lib/search/search-run.js +241 -0
- package/lib/search/search-skills.js +198 -0
- package/lib/utils/api-required-permissions.js +271 -0
- package/lib/utils/api.js +16 -13
- package/lib/utils/authentication-slot-show.js +153 -0
- package/lib/utils/cli-json-exit.js +41 -0
- package/lib/utils/cli-utils.js +23 -5
- package/lib/utils/controller-url.js +78 -4
- package/lib/utils/credential-display.js +43 -1
- package/lib/utils/deployment-errors.js +15 -0
- package/lib/utils/deployment-validation-helpers.js +4 -1
- package/lib/utils/device-code.js +31 -10
- package/lib/utils/error-formatters/error-parser.js +16 -1
- package/lib/utils/error-formatters/permission-errors.js +19 -5
- package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
- package/lib/utils/external-system-readiness-compact-display.js +30 -1
- package/lib/utils/external-system-validators.js +2 -1
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/keycloak-realm-ready.js +5 -2
- package/lib/utils/logger.js +1 -0
- package/lib/utils/paths.js +26 -5
- package/lib/utils/schema-loader.js +37 -0
- package/lib/utils/secrets-helpers.js +2 -2
- package/lib/utils/write-stream-and-wait.js +63 -0
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +3 -2
- package/package.json +20 -6
- package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
- package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
- package/templates/agent-kit/agent-kit.yaml +45 -0
- package/templates/agent-kit/instructions/AGENTKIT.md +104 -0
- package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
- package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
- package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
- package/templates/agent-kit/parity-inventory.yaml +188 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +59 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +52 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +51 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +43 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +65 -0
- package/templates/agent-kit/skills/shared/login.md +16 -0
- package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
- package/templates/agent-kit/workspace/LICENSE.mit +21 -0
- package/templates/agent-kit/workspace/README.md +89 -0
- package/templates/applications/builder-api/Dockerfile +3 -1
- package/templates/applications/dataplane/application.yaml +2 -3
- package/templates/applications/dataplane/env.template +5 -5
- package/templates/applications/dataplane/rbac.yaml +28 -0
- package/templates/applications/keycloak/env.template +3 -3
- package/templates/applications/miso-controller/application.yaml +21 -2
- package/templates/applications/miso-controller/env.template +96 -25
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +3 -0
- package/templates/channels/claude/channel.json +1 -1
- package/templates/channels/claude/install.template.md.hbs +1 -0
- package/templates/channels/claude/integration/claude-system.json +1 -1
- package/templates/channels/slack/channel.json +11 -0
- package/templates/channels/slack/install.template.md.hbs +9 -0
- package/templates/channels/slack/integration/slack-system.json +11 -0
- package/templates/channels/slack/manifest.template.json.hbs +6 -3
- package/templates/channels/teams-bot/channel.json +1 -0
- package/templates/python/docker-compose.hbs +14 -0
- package/templates/typescript/docker-compose.hbs +14 -0
|
@@ -75,7 +75,11 @@ function logUploadReadinessSummaryCompact(ctx) {
|
|
|
75
75
|
const genMcp = publication?.generateMcpContract !== false;
|
|
76
76
|
const tierA = summarizeDatasourceTiersA(publication?.datasources || [], genMcp);
|
|
77
77
|
const systemCfg = manifest?.system || {};
|
|
78
|
-
const statusLabel = resolveConnectedSystemStatus({
|
|
78
|
+
const statusLabel = resolveConnectedSystemStatus({
|
|
79
|
+
command: 'upload',
|
|
80
|
+
publication,
|
|
81
|
+
systemFromDataplane: ctx.systemFromDataplane
|
|
82
|
+
});
|
|
79
83
|
|
|
80
84
|
logCompactHeader({ command: 'upload', systemKey, environment, dataplaneUrl });
|
|
81
85
|
if (forcePublish) {
|
|
@@ -29,12 +29,33 @@ const PILLAR_LABELS = Object.freeze({
|
|
|
29
29
|
governance: 'Governance'
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
+
/** Connected System lifecycle labels — same Draft / Published / Archived as the web. */
|
|
33
|
+
const CONNECTED_SYSTEM_LIFECYCLE_LABELS = Object.freeze({
|
|
34
|
+
draft: 'Draft',
|
|
35
|
+
published: 'Published',
|
|
36
|
+
archived: 'Archived',
|
|
37
|
+
deployed: 'Published'
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Product lifecycle label, or null when the value is not Draft/Published/Archived
|
|
42
|
+
* (controller `active` is not Published).
|
|
43
|
+
* @param {string|null|undefined} status
|
|
44
|
+
* @returns {string|null}
|
|
45
|
+
*/
|
|
46
|
+
function formatConnectedSystemLifecycleLabel(status) {
|
|
47
|
+
const raw = String(status || '').trim().toLowerCase();
|
|
48
|
+
return CONNECTED_SYSTEM_LIFECYCLE_LABELS[raw] || null;
|
|
49
|
+
}
|
|
50
|
+
|
|
32
51
|
/**
|
|
33
52
|
* @param {string|null|undefined} status
|
|
34
53
|
* @returns {string}
|
|
35
54
|
*/
|
|
36
55
|
function formatLifecycleLabel(status) {
|
|
37
56
|
const raw = String(status || 'unknown').trim().toLowerCase();
|
|
57
|
+
const lifecycle = formatConnectedSystemLifecycleLabel(raw);
|
|
58
|
+
if (lifecycle) return lifecycle;
|
|
38
59
|
if (!raw || raw === 'unknown') return 'Unknown';
|
|
39
60
|
return raw.charAt(0).toUpperCase() + raw.slice(1);
|
|
40
61
|
}
|
|
@@ -159,8 +180,14 @@ function resolveManifestAuthMethod(systemCfg) {
|
|
|
159
180
|
* @returns {string}
|
|
160
181
|
*/
|
|
161
182
|
function resolveConnectedSystemStatus(opts = {}) {
|
|
162
|
-
const fromPub = opts.publication?.system?.status;
|
|
163
183
|
const fromGet = opts.systemFromDataplane?.status;
|
|
184
|
+
if (fromGet) {
|
|
185
|
+
return formatLifecycleLabel(fromGet);
|
|
186
|
+
}
|
|
187
|
+
if (opts.command === 'upload') {
|
|
188
|
+
return formatLifecycleLabel('draft');
|
|
189
|
+
}
|
|
190
|
+
const fromPub = opts.publication?.system?.status;
|
|
164
191
|
return formatLifecycleLabel(fromGet || fromPub || opts.status);
|
|
165
192
|
}
|
|
166
193
|
|
|
@@ -307,6 +334,8 @@ function logCompactTip(opts) {
|
|
|
307
334
|
|
|
308
335
|
module.exports = {
|
|
309
336
|
PILLAR_LABELS,
|
|
337
|
+
CONNECTED_SYSTEM_LIFECYCLE_LABELS,
|
|
338
|
+
formatConnectedSystemLifecycleLabel,
|
|
310
339
|
formatLifecycleLabel,
|
|
311
340
|
truncateKeyList,
|
|
312
341
|
formatCredentialPushLine,
|
|
@@ -80,6 +80,7 @@ const CATEGORIES = [
|
|
|
80
80
|
{ name: 'resource-type' },
|
|
81
81
|
{ name: 'role' },
|
|
82
82
|
{ name: 'role-assistant' },
|
|
83
|
+
{ name: 'search' },
|
|
83
84
|
{ name: 'evidence-kind' },
|
|
84
85
|
{ name: 'enterprise-knowledge' },
|
|
85
86
|
{ name: 'identity' },
|
|
@@ -133,7 +134,8 @@ const CATEGORIES = [
|
|
|
133
134
|
{ name: 'dev' },
|
|
134
135
|
{ name: 'secret' },
|
|
135
136
|
{ name: 'npm', term: 'npm config' },
|
|
136
|
-
{ name: 'secure' }
|
|
137
|
+
{ name: 'secure' },
|
|
138
|
+
{ name: 'agent-kit' }
|
|
137
139
|
]
|
|
138
140
|
}
|
|
139
141
|
];
|
|
@@ -82,15 +82,18 @@ async function waitForKeycloakRealmReady(opts = {}) {
|
|
|
82
82
|
const directUrl = directBase ? buildRealmWellKnownUrl(directBase) : null;
|
|
83
83
|
const deadline = Date.now() + timeoutSeconds * 1000;
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
do {
|
|
86
86
|
if (await probeRealmWellKnown(url)) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
if (directUrl && (await probeRealmWellKnown(directUrl))) {
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
+
if (Date.now() >= deadline) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
92
95
|
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
93
|
-
}
|
|
96
|
+
} while (Date.now() < deadline);
|
|
94
97
|
|
|
95
98
|
throw new Error(
|
|
96
99
|
`Keycloak realm "aifabrix" was not ready within ${timeoutSeconds}s (checked ${url}${directUrl ? ` and ${directUrl}` : ''}). ` +
|
package/lib/utils/logger.js
CHANGED
package/lib/utils/paths.js
CHANGED
|
@@ -957,6 +957,24 @@ async function ensureShippedBuilderAppTemplate(appName) {
|
|
|
957
957
|
return true;
|
|
958
958
|
}
|
|
959
959
|
|
|
960
|
+
/**
|
|
961
|
+
* Finds an existing local app workspace without copying shipped templates.
|
|
962
|
+
*
|
|
963
|
+
* @param {string} appName - Application name
|
|
964
|
+
* @param {Object} [options] - Detection options (reserved; options.type is ignored)
|
|
965
|
+
* @returns {{isExternal: boolean, appPath: string, appType: string, baseDir?: string}|null}
|
|
966
|
+
*/
|
|
967
|
+
function findExistingAppType(appName, options = {}) {
|
|
968
|
+
if (!appName || typeof appName !== 'string') {
|
|
969
|
+
return null;
|
|
970
|
+
}
|
|
971
|
+
const externalResult = checkExternalWorkspaceFolder(appName, options);
|
|
972
|
+
if (externalResult) {
|
|
973
|
+
return externalResult;
|
|
974
|
+
}
|
|
975
|
+
return checkBuilderFolder(appName);
|
|
976
|
+
}
|
|
977
|
+
|
|
960
978
|
/**
|
|
961
979
|
* Detects if an app is external type by checking application config.
|
|
962
980
|
* Resolution order: integration/ first, then builder/; if neither exists, throws.
|
|
@@ -971,13 +989,15 @@ async function detectAppType(appName, options = {}) {
|
|
|
971
989
|
if (!appName || typeof appName !== 'string') {
|
|
972
990
|
throw new Error('App name is required and must be a string');
|
|
973
991
|
}
|
|
974
|
-
const
|
|
975
|
-
if (
|
|
976
|
-
|
|
977
|
-
|
|
992
|
+
const existing = findExistingAppType(appName, options);
|
|
993
|
+
if (existing) {
|
|
994
|
+
return existing;
|
|
995
|
+
}
|
|
978
996
|
await ensureShippedBuilderAppTemplate(appName);
|
|
979
997
|
const builderAfterTemplate = checkBuilderFolder(appName);
|
|
980
|
-
if (builderAfterTemplate)
|
|
998
|
+
if (builderAfterTemplate) {
|
|
999
|
+
return builderAfterTemplate;
|
|
1000
|
+
}
|
|
981
1001
|
throw new Error(
|
|
982
1002
|
`App '${appName}' not found in integration/${appName}, enterprise-knowledge/${appName}, role-assistant/${appName}, or builder/${appName}`
|
|
983
1003
|
);
|
|
@@ -1121,6 +1141,7 @@ module.exports = {
|
|
|
1121
1141
|
resolveApplicationConfigPath,
|
|
1122
1142
|
resolveRbacPath,
|
|
1123
1143
|
ensureShippedBuilderAppTemplate,
|
|
1144
|
+
findExistingAppType,
|
|
1124
1145
|
detectAppType,
|
|
1125
1146
|
getResolveAppPath,
|
|
1126
1147
|
resolveIntegrationAppKeyFromCwd,
|
|
@@ -19,6 +19,7 @@ const addFormats = require('ajv-formats');
|
|
|
19
19
|
let externalSystemValidator = null;
|
|
20
20
|
let externalDataSourceValidator = null;
|
|
21
21
|
let roleAssistantSettingsValidator = null;
|
|
22
|
+
let roleAssistantTestCaseValidator = null;
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Reset validators cache (for testing)
|
|
@@ -28,6 +29,7 @@ function resetValidators() {
|
|
|
28
29
|
externalSystemValidator = null;
|
|
29
30
|
externalDataSourceValidator = null;
|
|
30
31
|
roleAssistantSettingsValidator = null;
|
|
32
|
+
roleAssistantTestCaseValidator = null;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
/**
|
|
@@ -172,6 +174,37 @@ function loadRoleAssistantSettingsSchema() {
|
|
|
172
174
|
return roleAssistantSettingsValidator;
|
|
173
175
|
}
|
|
174
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Loads and compiles role-assistant test-case schema.
|
|
179
|
+
* @function loadRoleAssistantTestCaseSchema
|
|
180
|
+
* @returns {Function}
|
|
181
|
+
*/
|
|
182
|
+
function loadRoleAssistantTestCaseSchema() {
|
|
183
|
+
if (roleAssistantTestCaseValidator) {
|
|
184
|
+
return roleAssistantTestCaseValidator;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const schemaPath = path.join(__dirname, '..', 'schema', 'role-assistant-test-case.schema.json');
|
|
188
|
+
let schema;
|
|
189
|
+
try {
|
|
190
|
+
schema = JSON.parse(fsRealSync.readFileSync(schemaPath, 'utf8'));
|
|
191
|
+
} catch (error) {
|
|
192
|
+
try {
|
|
193
|
+
schema = require('../schema/role-assistant-test-case.schema.json');
|
|
194
|
+
} catch {
|
|
195
|
+
if (error && error.code === 'ENOENT') {
|
|
196
|
+
throw new Error(`Role assistant test-case schema not found: ${schemaPath}`);
|
|
197
|
+
}
|
|
198
|
+
throw new Error(`Invalid JSON in role-assistant-test-case.schema.json: ${error.message}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const ajv = new Ajv({ allErrors: true, verbose: true, strict: false, strictSchema: false });
|
|
203
|
+
addFormats(ajv);
|
|
204
|
+
roleAssistantTestCaseValidator = ajv.compile(schema);
|
|
205
|
+
return roleAssistantTestCaseValidator;
|
|
206
|
+
}
|
|
207
|
+
|
|
175
208
|
/**
|
|
176
209
|
* Detect schema type from $id field
|
|
177
210
|
* @param {Object} parsed - Parsed JSON object
|
|
@@ -194,6 +227,9 @@ function detectFromId(parsed) {
|
|
|
194
227
|
if (parsed.$id.includes('role-assistant-settings')) {
|
|
195
228
|
return 'role-assistant-settings';
|
|
196
229
|
}
|
|
230
|
+
if (parsed.$id.includes('role-assistant-test-case')) {
|
|
231
|
+
return 'role-assistant-test-case';
|
|
232
|
+
}
|
|
197
233
|
|
|
198
234
|
return null;
|
|
199
235
|
}
|
|
@@ -388,6 +424,7 @@ module.exports = {
|
|
|
388
424
|
loadExternalSystemSchema,
|
|
389
425
|
loadExternalDataSourceSchema,
|
|
390
426
|
loadRoleAssistantSettingsSchema,
|
|
427
|
+
loadRoleAssistantTestCaseSchema,
|
|
391
428
|
registerExternalDatasourceAjvDependencies,
|
|
392
429
|
detectSchemaType,
|
|
393
430
|
detectSchemaTypeFromParsed,
|
|
@@ -47,7 +47,8 @@ const { resolveBashKvFromProcessEnv } = require('./secrets-bash-kv');
|
|
|
47
47
|
const EMPTY_ALLOWED_KV_FALLBACK = new Set([
|
|
48
48
|
'redis-passwordKeyVault',
|
|
49
49
|
'azure-openaiapi-urlKeyVault',
|
|
50
|
-
'secrets-azureOpenaiApiKeyVault'
|
|
50
|
+
'secrets-azureOpenaiApiKeyVault',
|
|
51
|
+
'miso-controller-secrets-apiKeyVault'
|
|
51
52
|
]);
|
|
52
53
|
|
|
53
54
|
/**
|
|
@@ -486,4 +487,3 @@ module.exports = {
|
|
|
486
487
|
rewriteInfraEndpoints,
|
|
487
488
|
getEnvHosts
|
|
488
489
|
};
|
|
489
|
-
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flush a writable stream chunk without hanging on Jest write mocks.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Shared stdout/stderr write + wait for CLI exits.
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {unknown} writeFn - Stream write implementation
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
15
|
+
function isJestMockWrite(writeFn) {
|
|
16
|
+
return typeof jest !== 'undefined'
|
|
17
|
+
&& typeof jest.isMockFunction === 'function'
|
|
18
|
+
&& jest.isMockFunction(writeFn);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Write `chunk` and resolve after the stream flushes.
|
|
23
|
+
*
|
|
24
|
+
* Piped stdout/stderr on Linux is asynchronous; exiting before the write
|
|
25
|
+
* callback can truncate output. Jest spies that ignore the callback, and
|
|
26
|
+
* native writes inside a Jest worker, must not hang the test.
|
|
27
|
+
*
|
|
28
|
+
* @param {NodeJS.WritableStream} stream - stdout or stderr
|
|
29
|
+
* @param {string} chunk - Bytes to write
|
|
30
|
+
* @returns {Promise<void>}
|
|
31
|
+
*/
|
|
32
|
+
function writeStreamAndWait(stream, chunk) {
|
|
33
|
+
return new Promise(resolve => {
|
|
34
|
+
let settled = false;
|
|
35
|
+
const finish = () => {
|
|
36
|
+
if (settled) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
settled = true;
|
|
40
|
+
resolve();
|
|
41
|
+
};
|
|
42
|
+
if (!stream || typeof stream.write !== 'function') {
|
|
43
|
+
finish();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const writeFn = stream.write;
|
|
47
|
+
try {
|
|
48
|
+
writeFn.call(stream, chunk, finish);
|
|
49
|
+
} catch {
|
|
50
|
+
finish();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (isJestMockWrite(writeFn) && writeFn.length < 2) {
|
|
54
|
+
finish();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (!isJestMockWrite(writeFn) && process.env.JEST_WORKER_ID) {
|
|
58
|
+
setImmediate(finish);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = { writeStreamAndWait };
|
|
@@ -13,7 +13,8 @@ const yaml = require('js-yaml');
|
|
|
13
13
|
const {
|
|
14
14
|
loadExternalSystemSchema,
|
|
15
15
|
loadExternalDataSourceSchema,
|
|
16
|
-
loadRoleAssistantSettingsSchema
|
|
16
|
+
loadRoleAssistantSettingsSchema,
|
|
17
|
+
loadRoleAssistantTestCaseSchema
|
|
17
18
|
} = require('../utils/schema-loader');
|
|
18
19
|
const { formatValidationErrors } = require('../utils/error-formatter');
|
|
19
20
|
const { validateFieldReferences } = require('../datasource/field-reference-validator');
|
|
@@ -60,6 +61,9 @@ function getValidatorForType(normalizedType) {
|
|
|
60
61
|
if (normalizedType === 'role-assistant-settings') {
|
|
61
62
|
return loadRoleAssistantSettingsSchema();
|
|
62
63
|
}
|
|
64
|
+
if (normalizedType === 'role-assistant-test-case') {
|
|
65
|
+
return loadRoleAssistantTestCaseSchema();
|
|
66
|
+
}
|
|
63
67
|
throw new Error(`Unknown file type: ${normalizedType}`);
|
|
64
68
|
}
|
|
65
69
|
|
|
@@ -27,6 +27,7 @@ const {
|
|
|
27
27
|
isRoleAssistantWorkspace,
|
|
28
28
|
isEnterpriseKnowledgeWorkspace
|
|
29
29
|
} = require('../utils/platform-shell-package');
|
|
30
|
+
const { validateRoleAssistantPackage } = require('../role-assistant/package-validate');
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Validates a file path (detects type and validates)
|
|
@@ -335,7 +336,7 @@ function skippedComponentsStep() {
|
|
|
335
336
|
return { valid: true, errors: [], warnings: [], files: [], skipped: true };
|
|
336
337
|
}
|
|
337
338
|
|
|
338
|
-
async function validatePlatformShellPackage(
|
|
339
|
+
async function validatePlatformShellPackage(_appName, baseDir, appPath, _options) {
|
|
339
340
|
if (isEnterpriseKnowledgeWorkspace(baseDir)) {
|
|
340
341
|
return aggregateExternalValidationSteps({
|
|
341
342
|
application: skippedValidationStep(),
|
|
@@ -348,7 +349,7 @@ async function validatePlatformShellPackage(appName, baseDir, appPath, options)
|
|
|
348
349
|
}
|
|
349
350
|
return aggregateExternalValidationSteps({
|
|
350
351
|
application: skippedValidationStep(),
|
|
351
|
-
components: await
|
|
352
|
+
components: await validateRoleAssistantPackage(appPath),
|
|
352
353
|
manifest: skippedValidationStep()
|
|
353
354
|
}, appPath);
|
|
354
355
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aifabrix/builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.55.2",
|
|
4
4
|
"description": "AI Fabrix Builder — CLI and developer scripts (pnpm + af)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -86,28 +86,42 @@
|
|
|
86
86
|
"overrides": {
|
|
87
87
|
"@babel/core": "^7.29.7",
|
|
88
88
|
"@babel/plugin-transform-modules-systemjs": "^7.29.7",
|
|
89
|
-
"
|
|
89
|
+
"baseline-browser-mapping": "^2.11.21",
|
|
90
|
+
"brace-expansion@5": "5.0.9",
|
|
91
|
+
"browserslist": "^4.28.9",
|
|
92
|
+
"fast-uri": "^4.1.4",
|
|
90
93
|
"flatted": "^3.4.2",
|
|
91
94
|
"follow-redirects": "^1.16.0",
|
|
92
95
|
"form-data": "^4.0.6",
|
|
96
|
+
"js-yaml@3": "3.15.2",
|
|
97
|
+
"js-yaml@5": "5.4.1",
|
|
93
98
|
"lodash": "^4.18.1",
|
|
94
99
|
"minimatch": "^10.2.5",
|
|
100
|
+
"multer": "^2.3.0",
|
|
95
101
|
"picomatch": "^4.0.5",
|
|
96
|
-
"qs": "^6.
|
|
102
|
+
"qs": "^6.16.0",
|
|
103
|
+
"smol-toml": "^1.8.0"
|
|
97
104
|
},
|
|
98
105
|
"pnpm": {
|
|
99
106
|
"overrides": {
|
|
100
107
|
"@bcoe/v8-coverage": "^1.0.2",
|
|
101
108
|
"@babel/core": "^7.29.7",
|
|
102
109
|
"@babel/plugin-transform-modules-systemjs": "^7.29.7",
|
|
103
|
-
"
|
|
110
|
+
"baseline-browser-mapping": "^2.11.21",
|
|
111
|
+
"brace-expansion@5": "5.0.9",
|
|
112
|
+
"browserslist": "^4.28.9",
|
|
113
|
+
"fast-uri": "^4.1.4",
|
|
104
114
|
"flatted": "^3.4.2",
|
|
105
115
|
"follow-redirects": "^1.16.0",
|
|
106
116
|
"form-data": "^4.0.6",
|
|
117
|
+
"js-yaml@3": "3.15.2",
|
|
118
|
+
"js-yaml@5": "5.4.1",
|
|
107
119
|
"lodash": "^4.18.1",
|
|
108
120
|
"minimatch": "^10.2.5",
|
|
121
|
+
"multer": "^2.3.0",
|
|
109
122
|
"picomatch": "^4.0.5",
|
|
110
|
-
"qs": "^6.
|
|
123
|
+
"qs": "^6.16.0",
|
|
124
|
+
"smol-toml": "^1.8.0"
|
|
111
125
|
}
|
|
112
126
|
},
|
|
113
127
|
"dependencies": {
|
|
@@ -121,7 +135,7 @@
|
|
|
121
135
|
"handlebars": "^4.7.9",
|
|
122
136
|
"inquirer": "^8.2.5",
|
|
123
137
|
"inquirer-autocomplete-prompt": "^2.0.0",
|
|
124
|
-
"js-yaml": "^4.3.
|
|
138
|
+
"js-yaml": "^4.3.2",
|
|
125
139
|
"ora": "^5.4.1",
|
|
126
140
|
"yaml": "^2.9.0"
|
|
127
141
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
@AGENTS.md
|
|
2
|
+
|
|
3
|
+
Delivery skills: `/aifabrix-plan`, `/aifabrix-connected-system`, `/aifabrix-role-assistant`, `/aifabrix-prove`.
|
|
4
|
+
The skill body lives under `.agents/skills/`. Do not invent a parallel workflow.
|
|
5
|
+
Local vs SSH (tmux, Remote Control): `.agents/skills/shared/hosts.md`.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
schemaVersion: "1"
|
|
2
|
+
kitVersion: "1.1.2"
|
|
3
|
+
minimumBuilderVersion: "2.54.2"
|
|
4
|
+
skills:
|
|
5
|
+
- aifabrix-plan
|
|
6
|
+
- aifabrix-connected-system
|
|
7
|
+
- aifabrix-role-assistant
|
|
8
|
+
- aifabrix-prove
|
|
9
|
+
managed:
|
|
10
|
+
- source: skills
|
|
11
|
+
target: .agents/skills
|
|
12
|
+
mode: tree
|
|
13
|
+
- source: instructions/root.AGENTS.md
|
|
14
|
+
target: AGENTS.md
|
|
15
|
+
mode: managed-section
|
|
16
|
+
- source: instructions/integration.AGENTS.md
|
|
17
|
+
target: integration/AGENTS.md
|
|
18
|
+
mode: managed-section
|
|
19
|
+
- source: instructions/role-assistant.AGENTS.md
|
|
20
|
+
target: role-assistant/AGENTS.md
|
|
21
|
+
mode: managed-section
|
|
22
|
+
- source: instructions/AGENTKIT.md
|
|
23
|
+
target: AGENTKIT.md
|
|
24
|
+
mode: file
|
|
25
|
+
render: hosts
|
|
26
|
+
- source: workspace/README.md
|
|
27
|
+
target: README.md
|
|
28
|
+
mode: if-missing
|
|
29
|
+
optional:
|
|
30
|
+
- source: adapters/cursor/commands
|
|
31
|
+
target: .cursor/commands
|
|
32
|
+
mode: tree
|
|
33
|
+
when: v1-migration
|
|
34
|
+
- source: adapters/claude/root.CLAUDE.md
|
|
35
|
+
target: CLAUDE.md
|
|
36
|
+
mode: managed-section
|
|
37
|
+
when: host-claude
|
|
38
|
+
- source: adapters/claude/nested.CLAUDE.md
|
|
39
|
+
target: integration/CLAUDE.md
|
|
40
|
+
mode: managed-section
|
|
41
|
+
when: host-claude
|
|
42
|
+
- source: adapters/claude/nested.CLAUDE.md
|
|
43
|
+
target: role-assistant/CLAUDE.md
|
|
44
|
+
mode: managed-section
|
|
45
|
+
when: host-claude
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Agent Kit
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
From this git repository (Builder CLI on PATH):
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
aifabrix agent-kit install --host {{hostFlag}}{{#if autoApprove}} --approve-all --yes{{/if}}
|
|
11
|
+
aifabrix agent-kit status
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`--host` may be `all`, `cursor`, `codex`, or `claude`. Shared skills always land in `.agents/skills/`.
|
|
15
|
+
{{#if claude}}
|
|
16
|
+
`claude` also writes `CLAUDE.md` and thin `.claude/skills` pointers.
|
|
17
|
+
{{/if}}
|
|
18
|
+
|
|
19
|
+
## Update
|
|
20
|
+
|
|
21
|
+
When this CLI is newer than the workspace kit, or you add or switch coding hosts:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
aifabrix agent-kit update --host {{hostFlag}}{{#if autoApprove}} --approve-all --yes{{/if}}
|
|
25
|
+
aifabrix agent-kit validate
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Omit `--host` to keep the hosts already recorded. Pass `--host` when the developer changes Cursor / Claude Code / Codex.
|
|
29
|
+
|
|
30
|
+
New workspace instead of an existing repo: `aifabrix agent-kit init <workspaceName> --host {{hostFlag}}`.
|
|
31
|
+
|
|
32
|
+
## Activate hosts
|
|
33
|
+
|
|
34
|
+
Install the coding app, then sign in. How to **run** it locally or over SSH is in `.agents/skills/shared/hosts.md` (linked from every Agent Kit skill).
|
|
35
|
+
{{#if autoApprove}}
|
|
36
|
+
|
|
37
|
+
On TTY, install **asks** which hosts to support (omit `--host`) and which tools to auto-approve. `--approve-all claude` or `--approve-all codex` writes only that host's config. Claude Code also allows `Bash(aifabrix *)` (delivery CLI) and `Read(~/**)` (home Read). Silent (`--yes` / non-TTY) writes them; `--skip-approve-all` skips.
|
|
38
|
+
{{#if claude}}
|
|
39
|
+
- Claude Code writes `.claude/settings.local.json` (gitignored).
|
|
40
|
+
{{/if}}
|
|
41
|
+
{{#if codex}}
|
|
42
|
+
- Codex writes `.codex/config.toml` (gitignored).
|
|
43
|
+
{{/if}}
|
|
44
|
+
{{/if}}
|
|
45
|
+
{{#if cursor}}
|
|
46
|
+
|
|
47
|
+
### Cursor
|
|
48
|
+
|
|
49
|
+
Open this folder in Cursor (this machine, or Cursor Remote SSH). Skills: `/aifabrix-plan`, `/aifabrix-connected-system`, `/aifabrix-role-assistant`, `/aifabrix-prove`.
|
|
50
|
+
{{/if}}
|
|
51
|
+
{{#if claude}}
|
|
52
|
+
|
|
53
|
+
### Claude Code
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
curl -fsSL https://claude.ai/install.sh | bash
|
|
57
|
+
claude auth login
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Run in tmux** from this workspace so closing the terminal does not kill Claude. `--remote-control` is the **same** session on this PC, [claude.ai/code](https://claude.ai/code), and the Claude mobile app (Code). That is not `claude --cloud` (a separate cloud VM). Claude `--tmux` is for worktrees only.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
aifabrix agent-kit start claude --remote-control --approve-all --yes
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
tmux session name defaults to this folder. Remote Control name is `hostname-user-folder` (for example `builder01-dev03-aifabrix-docs`). Override the folder with `--name`. Detach: `Ctrl-b` then `d`. Reattach: `tmux attach -t <folder>`. Several workspaces can run at once. Same account on phone and PC (`claude auth login`, Pro/Max/Team — not an API key). On the phone: Claude app → **Code**. Skills: `/aifabrix-plan` (and the other `/aifabrix-*` names). First `claude` must run inside this workspace, not your home directory. Full notes: `.agents/skills/shared/hosts.md`.
|
|
67
|
+
{{/if}}
|
|
68
|
+
{{#if codex}}
|
|
69
|
+
|
|
70
|
+
### Codex
|
|
71
|
+
|
|
72
|
+
Install the Codex CLI (`@openai/codex`, not the unrelated `codex` package), then sign in with ChatGPT (Plus, Pro, Business, Edu, or Enterprise):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm install -g @openai/codex
|
|
76
|
+
codex login
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Run in tmux** from this workspace so the session stays if you close the terminal:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
aifabrix agent-kit start codex --approve-all --yes
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Detach: `Ctrl-b` then `d`. Reattach: `tmux attach -t <folder>`, or `aifabrix agent-kit start codex` from this workspace. Default session name is this folder. Skills: `$aifabrix-plan` (and the other `$aifabrix-*` names). Codex reads `AGENTS.md`. Full notes: `.agents/skills/shared/hosts.md`.
|
|
86
|
+
{{/if}}
|
|
87
|
+
|
|
88
|
+
## Auth for delivery CLI
|
|
89
|
+
|
|
90
|
+
Do not tell the user to open a terminal for Builder login. Follow `.agents/skills/shared/login.md`.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
aifabrix auth status
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If that is not authenticated, ask for the Miso Controller URL, run device login, and paste the printed authenticate URL into chat.
|
|
97
|
+
|
|
98
|
+
## How to start
|
|
99
|
+
|
|
100
|
+
After this folder is open in the coding host, follow **How to start** in the workspace `README.md` (how to use prompts, then plan → validate/build → publish, then Role Assistant).
|
|
101
|
+
|
|
102
|
+
## Docs
|
|
103
|
+
|
|
104
|
+
Agents load the public index from `AGENTS.md`. Humans: the workspace `README.md` Docs section.
|