@formigio/fazemos-cli 0.10.66 → 0.10.74
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/dist/commands/preflight.d.ts +41 -0
- package/dist/commands/preflight.js +706 -0
- package/dist/commands/preflight.js.map +1 -0
- package/dist/commands/provision.d.ts +29 -0
- package/dist/commands/provision.js +382 -0
- package/dist/commands/provision.js.map +1 -0
- package/dist/index.js +173 -14
- package/dist/index.js.map +1 -1
- package/dist/preflight/repoRead.d.ts +65 -0
- package/dist/preflight/repoRead.js +194 -0
- package/dist/preflight/repoRead.js.map +1 -0
- package/dist/preflight/roster.d.ts +65 -0
- package/dist/preflight/roster.js +153 -0
- package/dist/preflight/roster.js.map +1 -0
- package/dist/preflight/row1_member.d.ts +8 -0
- package/dist/preflight/row1_member.js +64 -0
- package/dist/preflight/row1_member.js.map +1 -0
- package/dist/preflight/row2_roleRegistration.d.ts +18 -0
- package/dist/preflight/row2_roleRegistration.js +156 -0
- package/dist/preflight/row2_roleRegistration.js.map +1 -0
- package/dist/preflight/row3_persona.d.ts +24 -0
- package/dist/preflight/row3_persona.js +92 -0
- package/dist/preflight/row3_persona.js.map +1 -0
- package/dist/preflight/row3_playbook.d.ts +30 -0
- package/dist/preflight/row3_playbook.js +142 -0
- package/dist/preflight/row3_playbook.js.map +1 -0
- package/dist/preflight/row3_rolesJson.d.ts +12 -0
- package/dist/preflight/row3_rolesJson.js +38 -0
- package/dist/preflight/row3_rolesJson.js.map +1 -0
- package/dist/preflight/row3_workspace.d.ts +24 -0
- package/dist/preflight/row3_workspace.js +253 -0
- package/dist/preflight/row3_workspace.js.map +1 -0
- package/dist/preflight/row4_ssm.d.ts +57 -0
- package/dist/preflight/row4_ssm.js +235 -0
- package/dist/preflight/row4_ssm.js.map +1 -0
- package/dist/preflight/row5_workerLambdaWakeConfig.d.ts +20 -0
- package/dist/preflight/row5_workerLambdaWakeConfig.js +113 -0
- package/dist/preflight/row5_workerLambdaWakeConfig.js.map +1 -0
- package/dist/preflight/row6_ingest.d.ts +20 -0
- package/dist/preflight/row6_ingest.js +178 -0
- package/dist/preflight/row6_ingest.js.map +1 -0
- package/dist/preflight/schema.d.ts +175 -0
- package/dist/preflight/schema.js +62 -0
- package/dist/preflight/schema.js.map +1 -0
- package/dist/preflight/workerLambdas.d.ts +22 -0
- package/dist/preflight/workerLambdas.js +25 -0
- package/dist/preflight/workerLambdas.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30,6 +30,9 @@ import { registerProfilesCommands } from './commands/profiles.js';
|
|
|
30
30
|
import { registerImageCommands } from './commands/image.js';
|
|
31
31
|
import { registerIngestCommands } from './commands/ingest.js';
|
|
32
32
|
import { registerAssetCommands } from './commands/asset/index.js';
|
|
33
|
+
// F53 — Agent Provisioning Tooling
|
|
34
|
+
import { runPreflight } from './commands/preflight.js';
|
|
35
|
+
import { runProvision } from './commands/provision.js';
|
|
33
36
|
import { parseExecutionsJson, resolveWaitOptions, waitForPipelines, buildAwsCommand, validateExecutionEntry, } from './wait-for-pipeline.js';
|
|
34
37
|
import { readFileSync, readdirSync, writeFileSync, mkdirSync, existsSync, statSync } from 'fs';
|
|
35
38
|
import { fileURLToPath } from 'url';
|
|
@@ -7452,6 +7455,24 @@ agentsCmd
|
|
|
7452
7455
|
console.log(chalk.gray(` Audit: ${a.auditLogId}`));
|
|
7453
7456
|
}
|
|
7454
7457
|
}
|
|
7458
|
+
// F53 — next-step hint (additive; pre-existing success lines above stay byte-identical)
|
|
7459
|
+
// Suppressed under --json (AC4 rule: rul_f53_hint_text_additive_only).
|
|
7460
|
+
if (!opts.json) {
|
|
7461
|
+
const orgId = getActiveOrgId();
|
|
7462
|
+
const orgSlug = orgId ? (findOrgById(orgId)?.slug ?? null) : null;
|
|
7463
|
+
const roleSlug = opts.roles?.[0] ?? opts.name;
|
|
7464
|
+
const projectSlug = credentialProjectId
|
|
7465
|
+
? (orgId ? (findProjectById(orgId, credentialProjectId)?.slug ?? null) : null)
|
|
7466
|
+
: null;
|
|
7467
|
+
console.log('');
|
|
7468
|
+
console.log(chalk.gray(' Not autonomous yet — layers 2–6 remain.'));
|
|
7469
|
+
if (orgSlug && projectSlug && roleSlug) {
|
|
7470
|
+
console.log(chalk.gray(` Next: fazemos agents preflight ${orgSlug}/${projectSlug}/${roleSlug}`));
|
|
7471
|
+
}
|
|
7472
|
+
else {
|
|
7473
|
+
console.log(chalk.gray(` Next: fazemos agents preflight <org>/<project>/${roleSlug}`));
|
|
7474
|
+
}
|
|
7475
|
+
}
|
|
7455
7476
|
}
|
|
7456
7477
|
catch (err) {
|
|
7457
7478
|
if (opts.json) {
|
|
@@ -7476,6 +7497,59 @@ agentsCmd
|
|
|
7476
7497
|
process.exit(1);
|
|
7477
7498
|
}
|
|
7478
7499
|
});
|
|
7500
|
+
// ── F53 — `agents preflight` ────────────────────────────────────────────────
|
|
7501
|
+
// 6-row PASS/FAIL/SKIP/XWS_DEFERRED verifier for agent provisioning state.
|
|
7502
|
+
// Exit codes: 0=all clear, 1=FAIL, 2=tooling-error, 3=XWS_DEFERRED (INCOMPLETE).
|
|
7503
|
+
// Target forms: <org>/<project>/<role>, <org>/<project>, <org>/<role>.
|
|
7504
|
+
// Spec: projects/fazemos/specs/tech/platform/F53-agent-provision-tooling-tech-spec.md
|
|
7505
|
+
agentsCmd
|
|
7506
|
+
.command('preflight')
|
|
7507
|
+
.description('Verify agent provisioning state: 6-row PASS/FAIL/SKIP verifier with fix commands.\n' +
|
|
7508
|
+
'Target: <org>/<project>/<role> | <org>/<project> (all roles) | <org>/<role> (all projects)\n' +
|
|
7509
|
+
'Exit codes: 0=all clear, 1=FAIL, 2=tooling-error, 3=XWS_DEFERRED (cross-workspace unverified)')
|
|
7510
|
+
.argument('<target>', 'org/project/role, org/project (fan-out roles), or org/role (fan-out projects)')
|
|
7511
|
+
.option('--json', 'Emit stable JSON instead of human-readable output (schema_version 1.0)')
|
|
7512
|
+
.option('--workspace <path>', 'Path to workspace root containing .fazemos/roles.json (defaults to nearest ancestor)')
|
|
7513
|
+
.option('--region <region>', 'AWS region for SSM/Lambda checks (reads AWS_REGION env var by default)')
|
|
7514
|
+
.action(async (target, opts) => {
|
|
7515
|
+
try {
|
|
7516
|
+
const exitCode = await runPreflight(target, opts);
|
|
7517
|
+
process.exit(exitCode);
|
|
7518
|
+
}
|
|
7519
|
+
catch (err) {
|
|
7520
|
+
if (opts.json) {
|
|
7521
|
+
process.stdout.write(JSON.stringify({ schema_version: '1.0', target, exit_code: 2, error: err?.message ?? String(err) }) + '\n');
|
|
7522
|
+
}
|
|
7523
|
+
else {
|
|
7524
|
+
console.error(chalk.red(`⚠ TOOLING-ERROR: ${err?.message ?? String(err)}`));
|
|
7525
|
+
}
|
|
7526
|
+
process.exit(2);
|
|
7527
|
+
}
|
|
7528
|
+
});
|
|
7529
|
+
// ── F53 — `agents provision` ────────────────────────────────────────────────
|
|
7530
|
+
// Idempotent composite of provisioning layers 1–3, then runs preflight.
|
|
7531
|
+
// Non-interactive one-shot; --dry-run is the safety valve (no --yes flag, Ollie A1).
|
|
7532
|
+
// Spec: projects/fazemos/specs/tech/platform/F53-agent-provision-tooling-tech-spec.md
|
|
7533
|
+
agentsCmd
|
|
7534
|
+
.command('provision')
|
|
7535
|
+
.description('Idempotent provisioning of layers 1–3 for an agent role, then runs preflight.\n' +
|
|
7536
|
+
'Layer 1: agents register. Layer 2: roles.json + roles sync. Layer 3: verify-and-instruct (no scaffold).\n' +
|
|
7537
|
+
'Non-interactive. Use --dry-run to preview without writing.')
|
|
7538
|
+
.argument('<target>', 'org/project/role to provision')
|
|
7539
|
+
.requiredOption('--name <agent>', 'Agent display name')
|
|
7540
|
+
.requiredOption('--model <model>', 'Model (e.g., sonnet, opus, haiku)')
|
|
7541
|
+
.option('--dry-run', 'Preview what would be done without making changes')
|
|
7542
|
+
.option('--json', 'Suppress human output; preflight result is emitted as JSON')
|
|
7543
|
+
.option('--region <region>', 'AWS region for SSM/Lambda checks in the final preflight run')
|
|
7544
|
+
.action(async (target, opts) => {
|
|
7545
|
+
try {
|
|
7546
|
+
await runProvision(target, opts);
|
|
7547
|
+
}
|
|
7548
|
+
catch (err) {
|
|
7549
|
+
console.error(chalk.red(`provision error: ${err?.message ?? String(err)}`));
|
|
7550
|
+
process.exit(1);
|
|
7551
|
+
}
|
|
7552
|
+
});
|
|
7479
7553
|
// ── F17 — Project-scoped agents ─────────────────────────────────
|
|
7480
7554
|
// `agents list` / `agents show` become Project-scoped by default. The
|
|
7481
7555
|
// pre-F17 Org-level list is still reachable via `--org-only`. Execution
|
|
@@ -7514,6 +7588,10 @@ function exitNoActiveProjectForAgentsList() {
|
|
|
7514
7588
|
function formatAgentSource(source) {
|
|
7515
7589
|
if (source === 'project_override')
|
|
7516
7590
|
return 'project-override';
|
|
7591
|
+
if (source === 'org_file')
|
|
7592
|
+
return 'org-file';
|
|
7593
|
+
if (source === 'project_file')
|
|
7594
|
+
return 'project-file';
|
|
7517
7595
|
return source;
|
|
7518
7596
|
}
|
|
7519
7597
|
/**
|
|
@@ -7781,11 +7859,26 @@ agentsCmd
|
|
|
7781
7859
|
const { orgId, projectId } = await requireProjectForAgents(opts.project);
|
|
7782
7860
|
const data = await api('GET', `/api/organizations/${orgId}/projects/${projectId}/agents/${encodeURIComponent(name)}`, undefined, { noProjectHeader: true });
|
|
7783
7861
|
const a = data.agent;
|
|
7862
|
+
const resolution = data.resolution;
|
|
7784
7863
|
const proj = findProjectById(orgId, projectId);
|
|
7785
7864
|
const projSlug = proj?.slug ?? projectId;
|
|
7786
|
-
|
|
7865
|
+
// Use resolution.agent_source (F18-aware) when available; fall back to
|
|
7866
|
+
// a.source (F17-only) for older API versions (degrade per §6).
|
|
7867
|
+
const effectiveSource = resolution?.agent_source ?? a.source;
|
|
7868
|
+
const sourceLabel = formatAgentSource(effectiveSource);
|
|
7787
7869
|
console.log(chalk.cyan(`Agent: ${a.name} (${a.display_name})`));
|
|
7788
7870
|
console.log(`Project: ${projSlug} · Source: ${sourceLabel}`);
|
|
7871
|
+
// Role doc line — show immediately after source when a role doc is active.
|
|
7872
|
+
// Uses agent.role_doc_path populated by the API's F18 layer. When the API
|
|
7873
|
+
// is newer (resolution block present), also shows the resolved prompt length
|
|
7874
|
+
// so an empty role-doc stub is visible without a CloudWatch query (R10).
|
|
7875
|
+
if (a.role_doc_path) {
|
|
7876
|
+
const level = a.role_doc_level ? ` (level: ${a.role_doc_level})` : '';
|
|
7877
|
+
console.log(chalk.gray(` Role doc: ${a.role_doc_path}${level}`));
|
|
7878
|
+
if (resolution?.resolved_system_prompt_length !== undefined) {
|
|
7879
|
+
console.log(chalk.gray(` Resolved prompt: ${resolution.resolved_system_prompt_length.toLocaleString()} chars`));
|
|
7880
|
+
}
|
|
7881
|
+
}
|
|
7789
7882
|
console.log('');
|
|
7790
7883
|
// EFFECTIVE CONFIG
|
|
7791
7884
|
console.log(chalk.cyan('EFFECTIVE CONFIG'));
|
|
@@ -7837,12 +7930,6 @@ agentsCmd
|
|
|
7837
7930
|
const label = a.source === 'project_override' ? 'Override created' : 'Project-only created';
|
|
7838
7931
|
console.log(chalk.gray(`${label}: ${new Date(a.override_updated_at).toISOString().slice(0, 10)}`));
|
|
7839
7932
|
}
|
|
7840
|
-
// F18 forward-compat: role doc line only when populated.
|
|
7841
|
-
if (a.role_doc_path) {
|
|
7842
|
-
const level = a.role_doc_level ? ` (${a.role_doc_level})` : '';
|
|
7843
|
-
console.log('');
|
|
7844
|
-
console.log(chalk.gray(`Role doc: ${a.role_doc_path}${level}`));
|
|
7845
|
-
}
|
|
7846
7933
|
}
|
|
7847
7934
|
catch (err) {
|
|
7848
7935
|
if (err instanceof ApiError && err.code === 'AGENT_NOT_FOUND') {
|
|
@@ -8545,9 +8632,11 @@ agentsCmd
|
|
|
8545
8632
|
.description('Upload an agent definition file to Fazemos')
|
|
8546
8633
|
.argument('<name>', 'Agent name')
|
|
8547
8634
|
.argument('<file>', 'Path to agent definition .md file')
|
|
8548
|
-
.
|
|
8635
|
+
.option('--project <slug>', 'Project context for role-doc check (uses active project if not set)')
|
|
8636
|
+
.option('--force', 'Proceed even when a role doc overrides the DB systemPrompt at runtime', false)
|
|
8637
|
+
.action(async (name, file, opts) => {
|
|
8549
8638
|
try {
|
|
8550
|
-
// Resolve agent name to member ID
|
|
8639
|
+
// Resolve agent name to member ID (org-level members list)
|
|
8551
8640
|
const orgId = getActiveOrgId();
|
|
8552
8641
|
if (!orgId) {
|
|
8553
8642
|
console.error(chalk.red('No active org'));
|
|
@@ -8560,11 +8649,68 @@ agentsCmd
|
|
|
8560
8649
|
console.error(chalk.red(`Agent "${name}" not found`));
|
|
8561
8650
|
process.exit(1);
|
|
8562
8651
|
}
|
|
8563
|
-
//
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8652
|
+
// BUG-PERSONA-RESOLUTION-PATHS-DISAGREE fix (R9, AC-9):
|
|
8653
|
+
// Before PATCHing the DB, check whether a role doc overrides the
|
|
8654
|
+
// systemPrompt at runtime. If so, the upload is silently inert — warn
|
|
8655
|
+
// and refuse unless --force is passed.
|
|
8656
|
+
//
|
|
8657
|
+
// Predicate is derived from the API's resolution.has_role_doc field
|
|
8658
|
+
// (predicate-based, NOT a name-list allowlist — rul_respaths_predicate_not_allowlist).
|
|
8659
|
+
// Requires a project context to call the F17 detail endpoint that carries
|
|
8660
|
+
// the resolution block. When no project context is available, skip the
|
|
8661
|
+
// check and proceed (defensive degrade per §6 — same behavior as today).
|
|
8662
|
+
//
|
|
8663
|
+
// proceedWithUpload is set to false BEFORE process.exit(1) so that test
|
|
8664
|
+
// environments where process.exit is mocked still gate the PATCH correctly.
|
|
8665
|
+
let proceedWithUpload = true;
|
|
8666
|
+
if (!opts.force) {
|
|
8667
|
+
// Resolve project context: --project flag → active project → none.
|
|
8668
|
+
let projectId = null;
|
|
8669
|
+
if (opts.project) {
|
|
8670
|
+
const proj = findProjectBySlug(orgId, opts.project);
|
|
8671
|
+
projectId = proj?.id ?? null;
|
|
8672
|
+
if (!projectId) {
|
|
8673
|
+
proceedWithUpload = false;
|
|
8674
|
+
console.error(chalk.red(`Project "${opts.project}" not found`));
|
|
8675
|
+
process.exit(1);
|
|
8676
|
+
}
|
|
8677
|
+
}
|
|
8678
|
+
else {
|
|
8679
|
+
projectId = getActiveProjectId();
|
|
8680
|
+
}
|
|
8681
|
+
if (proceedWithUpload && projectId) {
|
|
8682
|
+
// Fetch the F17 detail endpoint (now F18-aware) to get the resolution block.
|
|
8683
|
+
// Use agent.name (lowercase slug) as the URL param.
|
|
8684
|
+
const agentName = agent.name ?? norm(name).replace(/\s+/g, '-');
|
|
8685
|
+
try {
|
|
8686
|
+
const detailData = await api('GET', `/api/organizations/${orgId}/projects/${projectId}/agents/${encodeURIComponent(agentName)}`, undefined, { noProjectHeader: true });
|
|
8687
|
+
// Defensive degrade: if resolution block is absent (older API), treat as
|
|
8688
|
+
// has_role_doc=false and proceed — behavior identical to today (§6 / EC-7).
|
|
8689
|
+
if (detailData.resolution?.has_role_doc === true) {
|
|
8690
|
+
const roleDocPath = detailData.resolution.role_doc_path ?? '(unknown path)';
|
|
8691
|
+
proceedWithUpload = false; // Gate PATCH before calling exit (for test environments).
|
|
8692
|
+
console.error(chalk.yellow(`⚠ a role doc at ${roleDocPath} overrides the DB systemPrompt at runtime —`));
|
|
8693
|
+
console.error(chalk.yellow(` this upload will not take effect. Edit the file instead, or re-run with --force`));
|
|
8694
|
+
console.error(chalk.yellow(` if you deliberately want to write the DB value.`));
|
|
8695
|
+
process.exit(1);
|
|
8696
|
+
}
|
|
8697
|
+
}
|
|
8698
|
+
catch (detailErr) {
|
|
8699
|
+
// Detail-fetch failure should not block the upload — fall through.
|
|
8700
|
+
// The PATCH may still be inert if a role doc exists, but we cannot
|
|
8701
|
+
// determine that without the API's resolution block.
|
|
8702
|
+
console.error(chalk.gray(`(role-doc check skipped: ${detailErr.message})`));
|
|
8703
|
+
}
|
|
8704
|
+
}
|
|
8705
|
+
// No project context → skip check, proceed as before.
|
|
8706
|
+
}
|
|
8707
|
+
if (proceedWithUpload) {
|
|
8708
|
+
// Read file and strip YAML frontmatter
|
|
8709
|
+
const raw = readFileSync(resolve(file), 'utf-8');
|
|
8710
|
+
const body = raw.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '').trim();
|
|
8711
|
+
await api('PATCH', `/api/members/${agent.id}/agent-config`, { systemPrompt: body });
|
|
8712
|
+
console.log(chalk.green(`Uploaded definition for ${agent.display_name} (${body.length} chars)`));
|
|
8713
|
+
}
|
|
8568
8714
|
}
|
|
8569
8715
|
catch (err) {
|
|
8570
8716
|
console.error(chalk.red(err.message));
|
|
@@ -10337,6 +10483,19 @@ Run after editing roles.json to sync inbox access to the API.`)
|
|
|
10337
10483
|
console.log(` ${chalk.cyan(slug)}`);
|
|
10338
10484
|
}
|
|
10339
10485
|
}
|
|
10486
|
+
// F53 — next-step hint (additive; the success line above stays byte-identical)
|
|
10487
|
+
// Suppressed under --dry-run (opts.dryRun returns early above; this only runs on real sync).
|
|
10488
|
+
// The org/project come from the local registry that was just synced.
|
|
10489
|
+
const hintOrgSlug = localRegistry.org;
|
|
10490
|
+
const hintProjectSlug = localRegistry.project ?? null;
|
|
10491
|
+
console.log('');
|
|
10492
|
+
console.log(chalk.gray(` Not autonomous yet — layers 3–6 remain for each role.`));
|
|
10493
|
+
if (hintOrgSlug && hintProjectSlug) {
|
|
10494
|
+
console.log(chalk.gray(` Next: fazemos agents preflight ${hintOrgSlug}/${hintProjectSlug}`));
|
|
10495
|
+
}
|
|
10496
|
+
else if (hintOrgSlug) {
|
|
10497
|
+
console.log(chalk.gray(` Next: fazemos agents preflight ${hintOrgSlug}/<project>`));
|
|
10498
|
+
}
|
|
10340
10499
|
}
|
|
10341
10500
|
catch (err) {
|
|
10342
10501
|
console.error(chalk.red(err instanceof Error ? err.message : String(err)));
|