@formigio/fazemos-cli 0.10.67 → 0.10.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/approvals.d.ts +1 -1
  2. package/dist/approvals.js +50 -19
  3. package/dist/approvals.js.map +1 -1
  4. package/dist/commands/preflight.d.ts +41 -0
  5. package/dist/commands/preflight.js +706 -0
  6. package/dist/commands/preflight.js.map +1 -0
  7. package/dist/commands/provision.d.ts +29 -0
  8. package/dist/commands/provision.js +382 -0
  9. package/dist/commands/provision.js.map +1 -0
  10. package/dist/index.js +124 -5
  11. package/dist/index.js.map +1 -1
  12. package/dist/pause.js +42 -11
  13. package/dist/pause.js.map +1 -1
  14. package/dist/preflight/repoRead.d.ts +65 -0
  15. package/dist/preflight/repoRead.js +194 -0
  16. package/dist/preflight/repoRead.js.map +1 -0
  17. package/dist/preflight/roster.d.ts +65 -0
  18. package/dist/preflight/roster.js +153 -0
  19. package/dist/preflight/roster.js.map +1 -0
  20. package/dist/preflight/row1_member.d.ts +8 -0
  21. package/dist/preflight/row1_member.js +64 -0
  22. package/dist/preflight/row1_member.js.map +1 -0
  23. package/dist/preflight/row2_roleRegistration.d.ts +18 -0
  24. package/dist/preflight/row2_roleRegistration.js +156 -0
  25. package/dist/preflight/row2_roleRegistration.js.map +1 -0
  26. package/dist/preflight/row3_persona.d.ts +24 -0
  27. package/dist/preflight/row3_persona.js +92 -0
  28. package/dist/preflight/row3_persona.js.map +1 -0
  29. package/dist/preflight/row3_playbook.d.ts +30 -0
  30. package/dist/preflight/row3_playbook.js +142 -0
  31. package/dist/preflight/row3_playbook.js.map +1 -0
  32. package/dist/preflight/row3_rolesJson.d.ts +12 -0
  33. package/dist/preflight/row3_rolesJson.js +38 -0
  34. package/dist/preflight/row3_rolesJson.js.map +1 -0
  35. package/dist/preflight/row3_workspace.d.ts +24 -0
  36. package/dist/preflight/row3_workspace.js +253 -0
  37. package/dist/preflight/row3_workspace.js.map +1 -0
  38. package/dist/preflight/row4_ssm.d.ts +57 -0
  39. package/dist/preflight/row4_ssm.js +235 -0
  40. package/dist/preflight/row4_ssm.js.map +1 -0
  41. package/dist/preflight/row5_workerLambdaWakeConfig.d.ts +20 -0
  42. package/dist/preflight/row5_workerLambdaWakeConfig.js +113 -0
  43. package/dist/preflight/row5_workerLambdaWakeConfig.js.map +1 -0
  44. package/dist/preflight/row6_ingest.d.ts +20 -0
  45. package/dist/preflight/row6_ingest.js +178 -0
  46. package/dist/preflight/row6_ingest.js.map +1 -0
  47. package/dist/preflight/schema.d.ts +175 -0
  48. package/dist/preflight/schema.js +62 -0
  49. package/dist/preflight/schema.js.map +1 -0
  50. package/dist/preflight/workerLambdas.d.ts +22 -0
  51. package/dist/preflight/workerLambdas.js +25 -0
  52. package/dist/preflight/workerLambdas.js.map +1 -0
  53. 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';
@@ -209,7 +212,23 @@ program
209
212
  // env var > the persisted active env. Lets one command (or, via the env var,
210
213
  // a whole session) target a different environment without a shared-disk
211
214
  // `fazemos env` switch that would clobber a concurrent session.
212
- .option('--env <name>', 'Environment to use for this invocation (overrides FAZEMOS_ENV and the persisted active env)');
215
+ .option('--env <name>', 'Environment to use for this invocation (overrides FAZEMOS_ENV and the persisted active env)')
216
+ // SECURITY / CORRECTNESS: refuse stray operands, program-wide.
217
+ //
218
+ // Commander defaults allowExcessArguments to TRUE, which silently swallows
219
+ // any operand a command didn't declare. Two live consequences we hit:
220
+ //
221
+ // 1. `fazemos pause resume --reason x` ran the PARENT pause action — a
222
+ // fleet-wide control-plane write — because `resume` matched no
223
+ // subcommand and was simply dropped. Exit 0.
224
+ // 2. `fazemos use journeyjuntos/fazemos` silently ignored the argument
225
+ // (it takes -o/-p) and printed the current context instead, so the
226
+ // caller believed they had switched scope when they had not.
227
+ //
228
+ // Set BEFORE any .command() registration: Command.command() calls
229
+ // copyInheritedSettings(), which copies _allowExcessArguments, so every
230
+ // subcommand registered after this line inherits the strict behavior.
231
+ .allowExcessArguments(false);
213
232
  // ── Directory-scoped default org/project (.fazemos.json) ─────
214
233
  //
215
234
  // Before any command action runs, discover the nearest `.fazemos.json`
@@ -254,8 +273,14 @@ async function applyDirContext(topCommand) {
254
273
  setOrgOverride(await resolveOrgIdMaybeSlug(org));
255
274
  }
256
275
  catch {
257
- // Unresolved org slug leave unset; the command's own "no active org"
258
- // check or the API will report the problem with full context.
276
+ // Do NOT fail silently. Leaving the override unset means the command
277
+ // runs against whatever `orgs switch` last persisted machine-globally
278
+ // for a READ the API error eventually hints at it, but for a WRITE the
279
+ // command simply SUCCEEDS IN THE WRONG ORG. Say so, on stderr, so the
280
+ // operator can see the scope they think they pinned was not applied.
281
+ console.error(chalk.yellow(`Warning: .fazemos.json pins org '${org}' but it could not be resolved ` +
282
+ `(offline, wrong --env, stale cache, or a typo'd slug). ` +
283
+ `Falling back to the machine-global active org — verify with 'fazemos whoami' before writing.`));
259
284
  }
260
285
  }
261
286
  if (project) {
@@ -266,12 +291,22 @@ async function applyDirContext(topCommand) {
266
291
  else {
267
292
  // Resolves against the active org, which now reflects the org override.
268
293
  const projectId = await resolveProjectIdBySlug(project);
269
- if (projectId)
294
+ if (projectId) {
270
295
  setProjectOverride(projectId);
296
+ }
297
+ else {
298
+ // Resolver MISS, not a throw — the old code fell through here in
299
+ // silence, which is how a pinned scope quietly became the global one.
300
+ console.error(chalk.yellow(`Warning: .fazemos.json pins project '${project}' but no such project ` +
301
+ `exists in the active org. Falling back to the machine-global active project.`));
302
+ }
271
303
  }
272
304
  }
273
305
  catch {
274
- // Unresolved project slugleave unset; surfaced downstream.
306
+ // Same hazard as the org branch above warn rather than silently
307
+ // inheriting the machine-global project.
308
+ console.error(chalk.yellow(`Warning: .fazemos.json pins project '${project}' but it could not be resolved. ` +
309
+ `Falling back to the machine-global active project — verify with 'fazemos whoami' before writing.`));
275
310
  }
276
311
  }
277
312
  }
@@ -7452,6 +7487,24 @@ agentsCmd
7452
7487
  console.log(chalk.gray(` Audit: ${a.auditLogId}`));
7453
7488
  }
7454
7489
  }
7490
+ // F53 — next-step hint (additive; pre-existing success lines above stay byte-identical)
7491
+ // Suppressed under --json (AC4 rule: rul_f53_hint_text_additive_only).
7492
+ if (!opts.json) {
7493
+ const orgId = getActiveOrgId();
7494
+ const orgSlug = orgId ? (findOrgById(orgId)?.slug ?? null) : null;
7495
+ const roleSlug = opts.roles?.[0] ?? opts.name;
7496
+ const projectSlug = credentialProjectId
7497
+ ? (orgId ? (findProjectById(orgId, credentialProjectId)?.slug ?? null) : null)
7498
+ : null;
7499
+ console.log('');
7500
+ console.log(chalk.gray(' Not autonomous yet — layers 2–6 remain.'));
7501
+ if (orgSlug && projectSlug && roleSlug) {
7502
+ console.log(chalk.gray(` Next: fazemos agents preflight ${orgSlug}/${projectSlug}/${roleSlug}`));
7503
+ }
7504
+ else {
7505
+ console.log(chalk.gray(` Next: fazemos agents preflight <org>/<project>/${roleSlug}`));
7506
+ }
7507
+ }
7455
7508
  }
7456
7509
  catch (err) {
7457
7510
  if (opts.json) {
@@ -7476,6 +7529,59 @@ agentsCmd
7476
7529
  process.exit(1);
7477
7530
  }
7478
7531
  });
7532
+ // ── F53 — `agents preflight` ────────────────────────────────────────────────
7533
+ // 6-row PASS/FAIL/SKIP/XWS_DEFERRED verifier for agent provisioning state.
7534
+ // Exit codes: 0=all clear, 1=FAIL, 2=tooling-error, 3=XWS_DEFERRED (INCOMPLETE).
7535
+ // Target forms: <org>/<project>/<role>, <org>/<project>, <org>/<role>.
7536
+ // Spec: projects/fazemos/specs/tech/platform/F53-agent-provision-tooling-tech-spec.md
7537
+ agentsCmd
7538
+ .command('preflight')
7539
+ .description('Verify agent provisioning state: 6-row PASS/FAIL/SKIP verifier with fix commands.\n' +
7540
+ 'Target: <org>/<project>/<role> | <org>/<project> (all roles) | <org>/<role> (all projects)\n' +
7541
+ 'Exit codes: 0=all clear, 1=FAIL, 2=tooling-error, 3=XWS_DEFERRED (cross-workspace unverified)')
7542
+ .argument('<target>', 'org/project/role, org/project (fan-out roles), or org/role (fan-out projects)')
7543
+ .option('--json', 'Emit stable JSON instead of human-readable output (schema_version 1.0)')
7544
+ .option('--workspace <path>', 'Path to workspace root containing .fazemos/roles.json (defaults to nearest ancestor)')
7545
+ .option('--region <region>', 'AWS region for SSM/Lambda checks (reads AWS_REGION env var by default)')
7546
+ .action(async (target, opts) => {
7547
+ try {
7548
+ const exitCode = await runPreflight(target, opts);
7549
+ process.exit(exitCode);
7550
+ }
7551
+ catch (err) {
7552
+ if (opts.json) {
7553
+ process.stdout.write(JSON.stringify({ schema_version: '1.0', target, exit_code: 2, error: err?.message ?? String(err) }) + '\n');
7554
+ }
7555
+ else {
7556
+ console.error(chalk.red(`⚠ TOOLING-ERROR: ${err?.message ?? String(err)}`));
7557
+ }
7558
+ process.exit(2);
7559
+ }
7560
+ });
7561
+ // ── F53 — `agents provision` ────────────────────────────────────────────────
7562
+ // Idempotent composite of provisioning layers 1–3, then runs preflight.
7563
+ // Non-interactive one-shot; --dry-run is the safety valve (no --yes flag, Ollie A1).
7564
+ // Spec: projects/fazemos/specs/tech/platform/F53-agent-provision-tooling-tech-spec.md
7565
+ agentsCmd
7566
+ .command('provision')
7567
+ .description('Idempotent provisioning of layers 1–3 for an agent role, then runs preflight.\n' +
7568
+ 'Layer 1: agents register. Layer 2: roles.json + roles sync. Layer 3: verify-and-instruct (no scaffold).\n' +
7569
+ 'Non-interactive. Use --dry-run to preview without writing.')
7570
+ .argument('<target>', 'org/project/role to provision')
7571
+ .requiredOption('--name <agent>', 'Agent display name')
7572
+ .requiredOption('--model <model>', 'Model (e.g., sonnet, opus, haiku)')
7573
+ .option('--dry-run', 'Preview what would be done without making changes')
7574
+ .option('--json', 'Suppress human output; preflight result is emitted as JSON')
7575
+ .option('--region <region>', 'AWS region for SSM/Lambda checks in the final preflight run')
7576
+ .action(async (target, opts) => {
7577
+ try {
7578
+ await runProvision(target, opts);
7579
+ }
7580
+ catch (err) {
7581
+ console.error(chalk.red(`provision error: ${err?.message ?? String(err)}`));
7582
+ process.exit(1);
7583
+ }
7584
+ });
7479
7585
  // ── F17 — Project-scoped agents ─────────────────────────────────
7480
7586
  // `agents list` / `agents show` become Project-scoped by default. The
7481
7587
  // pre-F17 Org-level list is still reachable via `--org-only`. Execution
@@ -10409,6 +10515,19 @@ Run after editing roles.json to sync inbox access to the API.`)
10409
10515
  console.log(` ${chalk.cyan(slug)}`);
10410
10516
  }
10411
10517
  }
10518
+ // F53 — next-step hint (additive; the success line above stays byte-identical)
10519
+ // Suppressed under --dry-run (opts.dryRun returns early above; this only runs on real sync).
10520
+ // The org/project come from the local registry that was just synced.
10521
+ const hintOrgSlug = localRegistry.org;
10522
+ const hintProjectSlug = localRegistry.project ?? null;
10523
+ console.log('');
10524
+ console.log(chalk.gray(` Not autonomous yet — layers 3–6 remain for each role.`));
10525
+ if (hintOrgSlug && hintProjectSlug) {
10526
+ console.log(chalk.gray(` Next: fazemos agents preflight ${hintOrgSlug}/${hintProjectSlug}`));
10527
+ }
10528
+ else if (hintOrgSlug) {
10529
+ console.log(chalk.gray(` Next: fazemos agents preflight ${hintOrgSlug}/<project>`));
10530
+ }
10412
10531
  }
10413
10532
  catch (err) {
10414
10533
  console.error(chalk.red(err instanceof Error ? err.message : String(err)));