@enterpriseai/cli 3.19.2 → 3.19.4

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 (139) hide show
  1. package/README.md +28 -0
  2. package/dist/commands/chat.d.ts.map +1 -1
  3. package/dist/commands/chat.js +116 -35
  4. package/dist/commands/chat.js.map +1 -1
  5. package/dist/commands/eai-managed-deploy-customer-source.d.ts.map +1 -1
  6. package/dist/commands/eai-managed-deploy-customer-source.js +24 -0
  7. package/dist/commands/eai-managed-deploy-customer-source.js.map +1 -1
  8. package/dist/commands/eai-managed-deploy-github-dispatch.d.ts.map +1 -1
  9. package/dist/commands/eai-managed-deploy-github-dispatch.js +30 -0
  10. package/dist/commands/eai-managed-deploy-github-dispatch.js.map +1 -1
  11. package/dist/commands/eai-managed-source-move.js +2 -2
  12. package/dist/commands/eai-managed-source-move.js.map +1 -1
  13. package/dist/commands/env.js +15 -2
  14. package/dist/commands/env.js.map +1 -1
  15. package/dist/commands/gofer.js +8 -1
  16. package/dist/commands/gofer.js.map +1 -1
  17. package/dist/commands/init.d.ts +4 -0
  18. package/dist/commands/init.d.ts.map +1 -1
  19. package/dist/commands/init.js +187 -8
  20. package/dist/commands/init.js.map +1 -1
  21. package/dist/commands/login.d.ts.map +1 -1
  22. package/dist/commands/login.js +6 -2
  23. package/dist/commands/login.js.map +1 -1
  24. package/dist/commands/provision.d.ts.map +1 -1
  25. package/dist/commands/provision.js +27 -13
  26. package/dist/commands/provision.js.map +1 -1
  27. package/dist/commands/publicapi.d.ts.map +1 -1
  28. package/dist/commands/publicapi.js +14 -2
  29. package/dist/commands/publicapi.js.map +1 -1
  30. package/dist/commands/resources.d.ts.map +1 -1
  31. package/dist/commands/resources.js +41 -20
  32. package/dist/commands/resources.js.map +1 -1
  33. package/dist/commands/support.d.ts +18 -0
  34. package/dist/commands/support.d.ts.map +1 -0
  35. package/dist/commands/support.js +110 -0
  36. package/dist/commands/support.js.map +1 -0
  37. package/dist/commands/tenant.js +39 -3
  38. package/dist/commands/tenant.js.map +1 -1
  39. package/dist/commands/types.d.ts +12 -1
  40. package/dist/commands/types.d.ts.map +1 -1
  41. package/dist/commands/types.js +172 -35
  42. package/dist/commands/types.js.map +1 -1
  43. package/dist/commands/verify.d.ts.map +1 -1
  44. package/dist/commands/verify.js +89 -44
  45. package/dist/commands/verify.js.map +1 -1
  46. package/dist/commands/vertical.d.ts.map +1 -1
  47. package/dist/commands/vertical.js +163 -15
  48. package/dist/commands/vertical.js.map +1 -1
  49. package/dist/index.js +54 -7
  50. package/dist/index.js.map +1 -1
  51. package/dist/lib/agent-guide.d.ts.map +1 -1
  52. package/dist/lib/agent-guide.js +25 -4
  53. package/dist/lib/agent-guide.js.map +1 -1
  54. package/dist/lib/api.d.ts +25 -4
  55. package/dist/lib/api.d.ts.map +1 -1
  56. package/dist/lib/api.js +152 -39
  57. package/dist/lib/api.js.map +1 -1
  58. package/dist/lib/cloud-env.d.ts +1 -0
  59. package/dist/lib/cloud-env.d.ts.map +1 -1
  60. package/dist/lib/cloud-env.js +28 -15
  61. package/dist/lib/cloud-env.js.map +1 -1
  62. package/dist/lib/config.d.ts +6 -2
  63. package/dist/lib/config.d.ts.map +1 -1
  64. package/dist/lib/config.js +13 -1
  65. package/dist/lib/config.js.map +1 -1
  66. package/dist/lib/eai-managed-deploy-contract.d.ts +4 -0
  67. package/dist/lib/eai-managed-deploy-contract.d.ts.map +1 -1
  68. package/dist/lib/eai-managed-deploy-contract.js.map +1 -1
  69. package/dist/lib/eai-managed-deploy-operation.d.ts.map +1 -1
  70. package/dist/lib/eai-managed-deploy-operation.js +14 -0
  71. package/dist/lib/eai-managed-deploy-operation.js.map +1 -1
  72. package/dist/lib/eai-managed-deploy-state.d.ts.map +1 -1
  73. package/dist/lib/eai-managed-deploy-state.js +15 -1
  74. package/dist/lib/eai-managed-deploy-state.js.map +1 -1
  75. package/dist/lib/eai-managed-source-client-types.d.ts +3 -0
  76. package/dist/lib/eai-managed-source-client-types.d.ts.map +1 -1
  77. package/dist/lib/error-codes.d.ts.map +1 -1
  78. package/dist/lib/error-codes.js +6 -3
  79. package/dist/lib/error-codes.js.map +1 -1
  80. package/dist/lib/object-type-export-filesystem.d.ts +13 -0
  81. package/dist/lib/object-type-export-filesystem.d.ts.map +1 -0
  82. package/dist/lib/object-type-export-filesystem.js +112 -0
  83. package/dist/lib/object-type-export-filesystem.js.map +1 -0
  84. package/dist/lib/object-type-export.d.ts +13 -0
  85. package/dist/lib/object-type-export.d.ts.map +1 -0
  86. package/dist/lib/object-type-export.js +173 -0
  87. package/dist/lib/object-type-export.js.map +1 -0
  88. package/dist/lib/output.d.ts +1 -0
  89. package/dist/lib/output.d.ts.map +1 -1
  90. package/dist/lib/output.js +24 -1
  91. package/dist/lib/output.js.map +1 -1
  92. package/dist/lib/platform-diagnostics.d.ts +21 -0
  93. package/dist/lib/platform-diagnostics.d.ts.map +1 -0
  94. package/dist/lib/platform-diagnostics.js +50 -0
  95. package/dist/lib/platform-diagnostics.js.map +1 -0
  96. package/dist/lib/profile.d.ts +9 -2
  97. package/dist/lib/profile.d.ts.map +1 -1
  98. package/dist/lib/profile.js +139 -4
  99. package/dist/lib/profile.js.map +1 -1
  100. package/dist/lib/schema-builder.d.ts +2 -0
  101. package/dist/lib/schema-builder.d.ts.map +1 -1
  102. package/dist/lib/schema-builder.js +5 -0
  103. package/dist/lib/schema-builder.js.map +1 -1
  104. package/dist/lib/support-context.d.ts +31 -0
  105. package/dist/lib/support-context.d.ts.map +1 -0
  106. package/dist/lib/support-context.js +193 -0
  107. package/dist/lib/support-context.js.map +1 -0
  108. package/dist/lib/support-redaction.d.ts +10 -0
  109. package/dist/lib/support-redaction.d.ts.map +1 -0
  110. package/dist/lib/support-redaction.js +44 -0
  111. package/dist/lib/support-redaction.js.map +1 -0
  112. package/dist/lib/support-report.d.ts +68 -0
  113. package/dist/lib/support-report.d.ts.map +1 -0
  114. package/dist/lib/support-report.js +165 -0
  115. package/dist/lib/support-report.js.map +1 -0
  116. package/package.json +3 -2
  117. package/resources/deploy/eai-app-template/.github/workflows/eai-app.yml +46 -13
  118. package/resources/deploy/eai-app-template/producer-pin.json +8 -8
  119. package/resources/deploy/eai-app-template/scripts/source-unknown-deployment-evidence.mjs +29 -2
  120. package/resources/deploy/eai-app-template/tests/source-unknown-deployment-evidence.test.mjs +99 -1
  121. package/resources/gofer/agents-skills/eai/SKILL.md +20 -0
  122. package/resources/gofer/claude-commands/eai.md +20 -0
  123. package/resources/gofer/claude-skills/eai/SKILL.md +20 -0
  124. package/resources/gofer/commands/0_gofer_start.md +18 -0
  125. package/resources/gofer/commands/gofer_eai_first_run.md +18 -0
  126. package/resources/gofer/copilot-prompts/eai.prompt.md +20 -0
  127. package/resources/gofer/gemini/commands/gofer/eai.md +20 -0
  128. package/resources/gofer/github-skills/eai/SKILL.md +20 -0
  129. package/resources/gofer/grok-skills/eai/SKILL.md +20 -0
  130. package/resources/gofer/instruction-templates/base/agents-base.md +18 -0
  131. package/resources/gofer/instruction-templates/base/claude-base.md +18 -0
  132. package/resources/gofer/instruction-templates/base/copilot-base.md +18 -0
  133. package/resources/gofer/instruction-templates/gofer/gofer-claude.md +4 -0
  134. package/resources/gofer/node-scripts/generate-commands.mjs +26 -0
  135. package/resources/gofer/references/platform/eai-support.md +19 -0
  136. package/resources/gofer/specify-commands/0_gofer_start.md +18 -0
  137. package/resources/gofer/specify-commands/gofer_eai_first_run.md +18 -0
  138. package/resources/gofer/system-skills/eai/SKILL.md +20 -0
  139. package/resources/linked-sources.json +2 -2
@@ -34,6 +34,7 @@ export declare function resolveTemplateClonePlan(templateSource: string, version
34
34
  export declare function buildTemplateInstallArgs(from: string): string[];
35
35
  export declare function canRunTemplateScripts(from: string, trustTemplateScripts: boolean): boolean;
36
36
  export declare function consumeLastInitBinding(): InitTenantAppBinding | undefined;
37
+ /** Scaffolds an app and its managed guidance, with optional AI tool selection for generated instructions. */
37
38
  export declare const initCommand: Command;
38
39
  export interface CreateCommandOptions {
39
40
  from: string;
@@ -79,6 +80,7 @@ export declare function resolveCreateCompletionPublicApiUrl(publicApiUrl: string
79
80
  * the operator's choice on a state-changing app create.
80
81
  */
81
82
  export declare function resolveCreateTenantContext(publicApiUrl: string, options: CreateCommandOptions): ReturnType<typeof resolveActiveTenantContext>;
83
+ /** Builds init arguments from create's validated binding, onboarding answers, and selected AI tool. */
82
84
  export declare function buildForwardedInitArgs(nameArg: string | undefined, options: CreateCommandOptions, answers?: CreateOnboardingAnswers, tenantId?: string): string[];
83
85
  /**
84
86
  * Next-step copy for guided create. A failed or unchecked builder readiness must
@@ -104,6 +106,8 @@ interface ExistingAppSelection {
104
106
  }
105
107
  /** Select one exact app enrollment and derive its recorded runtime tenant. */
106
108
  export declare function selectExistingAppSelection(payload: unknown, requestedAppKey: string): ExistingAppSelection;
109
+ /** Serialize init writers; existing-target rename is atomic, not a filesystem compare-and-swap. */
110
+ export declare function updateInitProjectFile(targetDir: string, name: ".gitignore" | ".env.local", update: (content: Buffer) => Buffer, mode?: number): Promise<void>;
107
111
  export declare function isMissingGitIdentity(error: unknown): boolean;
108
112
  export declare function describeGitCommitFailure(error: unknown): string;
109
113
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,8 @@ import { execFile } from "node:child_process";
6
6
  import { createRequire } from "node:module";
7
7
  import { tmpdir } from "node:os";
8
8
  import { promisify } from "node:util";
9
- import { readFile, writeFile, access, mkdir, rm, cp, mkdtemp, chmod, realpath, } from "node:fs/promises";
9
+ import { constants } from "node:fs";
10
+ import { readFile, writeFile, access, mkdir, rm, cp, mkdtemp, chmod, realpath, lstat, open, link, rename, unlink, } from "node:fs/promises";
10
11
  import { basename, join, resolve } from "node:path";
11
12
  import { randomBytes } from "node:crypto";
12
13
  import ora from "ora";
@@ -19,7 +20,7 @@ import { browserLogin, isAuthenticated, loadTokens, resolveAuthConfig, storeToke
19
20
  import { publicApiUrlForHomeRegion, resolveActiveTenantContext, resolveMainCompanyTenantId, resolvePublicApiUrl, } from "../lib/tenant-context.js";
20
21
  import { buildTenantHierarchy, promptForTenantFromHierarchy, } from "../lib/tenant-hierarchy.js";
21
22
  import { isManagedPublicRequestTimeout, parseApiError, readManagedPublicResponseText, PlatformAPIClient, } from "../lib/api.js";
22
- import { findProjectRoot, patchEnvFile } from "../lib/config.js";
23
+ import { entraScopeEnvPatch, findProjectRoot, patchEnvContent } from "../lib/config.js";
23
24
  import { pullCloudEnvValues } from "../lib/cloud-env.js";
24
25
  import { findGuidance } from "../lib/error-guidance/match.js";
25
26
  import { formatGuidanceText } from "../lib/error-guidance/render.js";
@@ -319,6 +320,7 @@ export function consumeLastInitBinding() {
319
320
  lastInitBinding = undefined;
320
321
  return binding;
321
322
  }
323
+ /** Scaffolds an app and its managed guidance, with optional AI tool selection for generated instructions. */
322
324
  export const initCommand = new Command("init")
323
325
  .description("Scaffold a new application")
324
326
  .argument("[name]", "Name for the app (kebab-case)")
@@ -340,6 +342,7 @@ export const initCommand = new Command("init")
340
342
  .option("--binding-receipt-nonce <uuid>", "Fresh UUID binding this invocation to its private receipt")
341
343
  .option("--app-key <key>", "Bind the local project to an existing app instead of creating a new app")
342
344
  .option("--template-version <tag>", "Scaffold from a specific published app-template release (for example v1.2.0)")
345
+ .option("--tool <tool>", "AI tool to prepare for: codex, claude, vscode, grok, or antigravity")
343
346
  .option("--no-splash", "Skip the interactive EAI wordmark")
344
347
  .addHelpText("after", `
345
348
  Gofer AI CLI assets are installed by default:
@@ -356,6 +359,7 @@ repo or local path.
356
359
  Use --no-gofer only when you need a bare app scaffold.
357
360
  `)
358
361
  .action(async (nameArg, options) => {
362
+ const aiTool = validateCreateAiTool(options.tool);
359
363
  if ((options.bindingReceipt !== undefined || options.bindingReceiptNonce !== undefined)
360
364
  && (!options.skipPrompts || !nameArg))
361
365
  throw new Error("Init binding receipts require a named --skip-prompts invocation.");
@@ -525,13 +529,16 @@ Use --no-gofer only when you need a bare app scaffold.
525
529
  // Step 3: Generate .env.local with placeholders
526
530
  const envSpinner = startEaiStep("Generating .env.local...");
527
531
  try {
532
+ await ensureLocalEnvIgnored(targetDir);
528
533
  const envContent = generateEnvFile(initOptions);
529
- await writeFile(join(targetDir, ".env.local"), envContent, "utf-8");
534
+ await updateInitProjectFile(targetDir, ".env.local", () => Buffer.from(envContent), 0o600);
530
535
  await hydrateEnvFromLoginContext(targetDir, initOptions.name, initOptions.parentTenantId, initOptions.tenantId, initOptions.tenantHomeRegion, initOptions.appKey);
531
536
  envSpinner.succeed("Generated .env.local");
532
537
  }
533
- catch (_err) {
538
+ catch (err) {
534
539
  envSpinner.fail("Failed to generate .env.local");
540
+ out.error(errMsg(err));
541
+ process.exit(1);
535
542
  }
536
543
  // Step 4: Generate Object Types scaffold
537
544
  const typesSpinner = startEaiStep("Creating Object Types scaffold...");
@@ -697,6 +704,9 @@ Use --no-gofer only when you need a bare app scaffold.
697
704
  out.nestedDim(`Run ${chalk.cyan("eai provision entra")} inside the project to set up Entra authentication.`);
698
705
  }
699
706
  out.nestedDim(`Template: ${templatePlan.displaySource}`);
707
+ if (aiTool) {
708
+ out.nestedInfo(`AI tool: ${CREATE_AI_TOOL_LABELS[aiTool]}. Run \`eai start\` in the project to open your AI workspace.`);
709
+ }
700
710
  if (options.gofer) {
701
711
  out.nestedDim("Gofer: run eai start to open this project in a detected AI workspace with the public EAI skill.");
702
712
  }
@@ -820,6 +830,7 @@ export function resolveCreateTenantContext(publicApiUrl, options) {
820
830
  tenantId: options.companyTenant || options.tenant,
821
831
  });
822
832
  }
833
+ /** Builds init arguments from create's validated binding, onboarding answers, and selected AI tool. */
823
834
  export function buildForwardedInitArgs(nameArg, options, answers, tenantId) {
824
835
  const appName = answers?.name || nameArg;
825
836
  const args = [];
@@ -862,6 +873,9 @@ export function buildForwardedInitArgs(nameArg, options, answers, tenantId) {
862
873
  if (options.packageProfile) {
863
874
  args.push("--package-profile", options.packageProfile);
864
875
  }
876
+ const aiTool = answers?.aiTool || validateCreateAiTool(options.tool);
877
+ if (aiTool)
878
+ args.push("--tool", aiTool);
865
879
  return args;
866
880
  }
867
881
  async function runCreatePreflight() {
@@ -1103,24 +1117,27 @@ async function provisionEntraInline(targetDir, appName, tenantId, publicApiUrl)
1103
1117
  out.warn(`The app registration ${result.clientId} exists, but the workspace allowlist was not updated. Run \`eai provision entra --force --debug\` after platform access is fixed.`);
1104
1118
  return false;
1105
1119
  }
1120
+ const scopeEnv = entraScopeEnvPatch(result.scopes);
1106
1121
  if (result.clientSecret) {
1107
- await patchEnvFile(targetDir, {
1122
+ await patchInitEnvFile(targetDir, {
1108
1123
  ENTRA_CLIENT_ID: result.clientId,
1109
1124
  ENTRA_CLIENT_SECRET: result.clientSecret,
1110
1125
  AUTH_URL: authEndpointUrl,
1111
1126
  NEXTAUTH_URL: authSiteUrl,
1112
1127
  AUTH_TRUST_HOST: "true",
1128
+ ...scopeEnv,
1113
1129
  });
1114
1130
  spinner.succeed(`Entra app registration ${result.existing ? "confirmed" : "created"}: ${chalk.dim(result.clientId)}`);
1115
1131
  out.warn("The client secret has been written to .env.local and cannot be retrieved again.");
1116
1132
  return true;
1117
1133
  }
1118
1134
  if (result.existing) {
1119
- await patchEnvFile(targetDir, {
1135
+ await patchInitEnvFile(targetDir, {
1120
1136
  ENTRA_CLIENT_ID: result.clientId,
1121
1137
  AUTH_URL: authEndpointUrl,
1122
1138
  NEXTAUTH_URL: authSiteUrl,
1123
1139
  AUTH_TRUST_HOST: "true",
1140
+ ...scopeEnv,
1124
1141
  });
1125
1142
  const hydratedSecret = await hydrateCloudSecret(targetDir, appName);
1126
1143
  spinner.succeed(`Entra app registration confirmed: ${chalk.dim(result.clientId)}`);
@@ -1155,7 +1172,7 @@ async function hydrateCloudSecret(targetDir, appName) {
1155
1172
  if (!secret) {
1156
1173
  return false;
1157
1174
  }
1158
- await patchEnvFile(targetDir, { ENTRA_CLIENT_SECRET: secret });
1175
+ await patchInitEnvFile(targetDir, { ENTRA_CLIENT_SECRET: secret });
1159
1176
  return true;
1160
1177
  }
1161
1178
  catch {
@@ -1503,6 +1520,9 @@ async function hydrateEnvFromLoginContext(targetDir, appName, parentTenantId, pl
1503
1520
  const envKey = appName.replace(/-/g, "_").toUpperCase();
1504
1521
  const regionalPublicApiUrl = publicApiUrlForHomeRegion(tenantHomeRegion);
1505
1522
  const profileName = getActiveProfile();
1523
+ // Persist only the selector. Private profile auth/API settings and CLI tokens
1524
+ // remain in the user's local CLI configuration, outside the app repository.
1525
+ patches.EAI_PROFILE = profileName;
1506
1526
  const profileConfig = await loadProfileConfig(profileName);
1507
1527
  if (profileConfig?.publicApiUrl) {
1508
1528
  patches.BASE_URL_PUBLIC_API = profileConfig.publicApiUrl;
@@ -1552,7 +1572,147 @@ async function hydrateEnvFromLoginContext(targetDir, appName, parentTenantId, pl
1552
1572
  patches.NEXT_PUBLIC_EAI_APP_KEY = appKey;
1553
1573
  }
1554
1574
  if (Object.keys(patches).length > 0) {
1555
- await patchEnvFile(targetDir, patches);
1575
+ await patchInitEnvFile(targetDir, patches);
1576
+ }
1577
+ }
1578
+ /** Apply every init hydration/provisioning patch through the protected credential writer. */
1579
+ async function patchInitEnvFile(targetDir, patches) {
1580
+ await updateInitProjectFile(targetDir, ".env.local", content => Buffer.from(patchEnvContent(content.toString("utf8"), patches)), 0o600);
1581
+ }
1582
+ async function ensureLocalEnvIgnored(targetDir) {
1583
+ await updateInitProjectFile(targetDir, ".gitignore", (content) => {
1584
+ // Last-match precedence also protects custom templates which unignore env files.
1585
+ const separator = content.length && content[content.length - 1] !== 10 ? "\n" : "";
1586
+ return Buffer.concat([content, Buffer.from(`${separator}\n# Local app credentials and EAI CLI profile selector\n/.env.local\n/.env.local.eai-*.tmp\n`)]);
1587
+ });
1588
+ }
1589
+ /** Serialize init writers; existing-target rename is atomic, not a filesystem compare-and-swap. */
1590
+ export async function updateInitProjectFile(targetDir, name, update, mode) {
1591
+ const root = await realpath(targetDir);
1592
+ const parent = await lstat(root);
1593
+ const lockPath = join(root, `${name}.eai-init.lock`);
1594
+ const lock = await open(lockPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | (constants.O_NOFOLLOW || 0), 0o600);
1595
+ const ownedLock = await lock.stat();
1596
+ const assertLock = async () => {
1597
+ const current = await lstat(lockPath);
1598
+ if (!current.isFile() || current.nlink !== 1 || current.dev !== ownedLock.dev || current.ino !== ownedLock.ino) {
1599
+ throw new Error(`Project ${name} initialization lock changed; inspect the project files before retrying.`);
1600
+ }
1601
+ };
1602
+ const releaseOwnedLock = async () => {
1603
+ await lock.close();
1604
+ try {
1605
+ const current = await lstat(lockPath);
1606
+ if (current.isFile() && current.nlink === 1 && current.dev === ownedLock.dev && current.ino === ownedLock.ino)
1607
+ await unlink(lockPath);
1608
+ }
1609
+ catch (error) {
1610
+ if (error.code !== "ENOENT")
1611
+ throw error;
1612
+ }
1613
+ };
1614
+ try {
1615
+ await assertLock();
1616
+ await updateLockedInitProjectFile(root, parent, name, update, mode, assertLock);
1617
+ }
1618
+ finally {
1619
+ await releaseOwnedLock();
1620
+ }
1621
+ }
1622
+ async function updateLockedInitProjectFile(root, parent, name, update, mode, assertLock) {
1623
+ const path = join(root, name);
1624
+ const maxBytes = 1024 * 1024;
1625
+ const unsafe = () => new Error(`Project ${name} must be an unlinked regular file within 1 MiB.`);
1626
+ const sameFile = (left, right) => left.dev === right.dev && left.ino === right.ino
1627
+ && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs
1628
+ && left.mode === right.mode && right.isFile() && right.nlink === 1;
1629
+ const statLeaf = async () => {
1630
+ try {
1631
+ return await lstat(path);
1632
+ }
1633
+ catch (error) {
1634
+ if (error.code === "ENOENT")
1635
+ return null;
1636
+ throw error;
1637
+ }
1638
+ };
1639
+ const original = await statLeaf();
1640
+ if (original && (!original.isFile() || original.isSymbolicLink() || original.nlink !== 1 || original.size > maxBytes))
1641
+ throw unsafe();
1642
+ let content = Buffer.alloc(0);
1643
+ if (original) {
1644
+ const file = await open(path, constants.O_RDONLY | (constants.O_NOFOLLOW || 0) | (constants.O_NONBLOCK || 0));
1645
+ try {
1646
+ const opened = await file.stat();
1647
+ if (!sameFile(original, opened))
1648
+ throw unsafe();
1649
+ const buffer = Buffer.alloc(maxBytes + 1);
1650
+ let length = 0;
1651
+ while (length < buffer.length) {
1652
+ const { bytesRead } = await file.read(buffer, length, buffer.length - length, null);
1653
+ if (!bytesRead)
1654
+ break;
1655
+ length += bytesRead;
1656
+ }
1657
+ if (length !== original.size || length > maxBytes || !sameFile(original, await file.stat()))
1658
+ throw unsafe();
1659
+ content = buffer.subarray(0, length);
1660
+ }
1661
+ finally {
1662
+ await file.close();
1663
+ }
1664
+ }
1665
+ const assertUnchanged = async () => {
1666
+ const current = await statLeaf();
1667
+ const parentAfter = await lstat(root);
1668
+ if ((original ? !current || !sameFile(original, current) : current !== null)
1669
+ || parent.dev !== parentAfter.dev || parent.ino !== parentAfter.ino || !parentAfter.isDirectory()) {
1670
+ throw new Error(`Project ${name} changed during initialization; retry after checking the project files.`);
1671
+ }
1672
+ };
1673
+ await assertUnchanged();
1674
+ const updated = update(content);
1675
+ const temporary = join(root, `${name}.eai-${randomBytes(16).toString("hex")}.tmp`);
1676
+ const file = await open(temporary, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | (constants.O_NOFOLLOW || 0), 0o600);
1677
+ const ownedTemporary = await file.stat();
1678
+ const removeOwnedTemporary = async () => {
1679
+ try {
1680
+ const current = await lstat(temporary);
1681
+ if (current.isFile() && current.dev === ownedTemporary.dev && current.ino === ownedTemporary.ino)
1682
+ await unlink(temporary);
1683
+ }
1684
+ catch (error) {
1685
+ if (error.code !== "ENOENT")
1686
+ throw error;
1687
+ }
1688
+ };
1689
+ try {
1690
+ await file.writeFile(updated);
1691
+ await file.chmod(mode ?? (original ? original.mode & 0o777 : 0o666 & ~process.umask()));
1692
+ await file.sync();
1693
+ const written = await file.stat();
1694
+ if (!sameFile(written, await lstat(temporary)))
1695
+ throw unsafe();
1696
+ await assertLock();
1697
+ await assertUnchanged();
1698
+ // link publishes an absent target without replacing a concurrent occupant.
1699
+ // Existing targets are rechecked under the cooperative lock, then renamed.
1700
+ if (original)
1701
+ await rename(temporary, path);
1702
+ else {
1703
+ await link(temporary, path);
1704
+ await removeOwnedTemporary();
1705
+ }
1706
+ const published = await statLeaf();
1707
+ const parentAfter = await lstat(root);
1708
+ if (!published || !sameFile(await file.stat(), published)
1709
+ || parent.dev !== parentAfter.dev || parent.ino !== parentAfter.ino || !parentAfter.isDirectory()) {
1710
+ throw new Error(`Project ${name} publication could not be verified; inspect the project files before retrying.`);
1711
+ }
1712
+ }
1713
+ finally {
1714
+ await file.close();
1715
+ await removeOwnedTemporary();
1556
1716
  }
1557
1717
  }
1558
1718
  function toDisplayName(name) {
@@ -2298,6 +2458,25 @@ await client.resources.create('MyType', { title: 'Hello' });
2298
2458
  | \`eai deploy trigger\` | Trigger deployment |
2299
2459
  | \`eai verify\` | Platform connectivity check |
2300
2460
  | \`eai doctor\` | Diagnose issues |
2461
+ | \`eai support\` | Review and approve a support report |
2462
+
2463
+ ## Support after an unresolved EAI error
2464
+
2465
+ After an \`eai\` command fails, run \`eai errors explain <code-or-reason> --format json\`.
2466
+ Follow its diagnostics, approval requirements, and fixes once. Stop at its retry limit.
2467
+ If the command still fails, prepare a report with
2468
+ \`eai support --source harness --tool <current-tool> --format json\`.
2469
+ Use \`codex\`, \`claude\`, \`vscode\`, \`grok\`, or \`antigravity\` for \`<current-tool>\`.
2470
+ This command previews the locally redacted bundle in a noninteractive harness.
2471
+ Show the person the bundle summary and ask for explicit consent in the chat.
2472
+ Only after they approve that bundle, repeat the command with \`--yes --no-open\` and give them the returned link.
2473
+ If the bundle changes, show it again and ask for fresh consent. Never assume consent or run \`--yes\` automatically.
2474
+ Keep secrets, tokens, raw logs, and local \`.env\` values out of the chat.
2475
+ The CLI creates the draft; the AI never calls the support API itself.
2476
+ Report content stays in the draft body. The Support link fragment carries only its id and token.
2477
+ If sign-in is unavailable, give the person the plain Support page link returned by the CLI.
2478
+ In the welcome reply, say: If anything fails, say "get help" or type \`eai support\`; I can prepare a report for you to approve.
2479
+ If the person asks for help with a silent failure, start with the same report preview.
2301
2480
 
2302
2481
  ## App Delivery Checklist
2303
2482