forgeos 0.1.0-alpha.19 → 0.1.0-alpha.20

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 (173) hide show
  1. package/.npmignore +4 -0
  2. package/AGENTS.md +2 -2
  3. package/CHANGELOG.md +11 -0
  4. package/adapters/java/target/forge-java-adapter-0.1.0-alpha.11.jar +0 -0
  5. package/adapters/java-spring-boot-starter/target/forge-java-spring-boot-starter-0.1.0-alpha.11.jar +0 -0
  6. package/examples/java-billing/target/java-billing-0.1.0-alpha.11-all.jar +0 -0
  7. package/examples/java-billing/target/java-billing-0.1.0-alpha.11.jar +0 -0
  8. package/package.json +11 -1
  9. package/src/forge/_generated/releaseManifest.json +1 -1
  10. package/src/forge/_generated/releaseManifest.ts +3 -3
  11. package/src/forge/agent-adapters/index.ts +77 -26
  12. package/src/forge/agent-adapters/types.ts +2 -0
  13. package/src/forge/agent-memory/bridge.ts +241 -3
  14. package/src/forge/agent-memory/types.ts +6 -1
  15. package/src/forge/cli/changed.ts +53 -2
  16. package/src/forge/cli/commands.ts +118 -2
  17. package/src/forge/cli/output.ts +44 -1
  18. package/src/forge/cli/parse.ts +2 -0
  19. package/src/forge/cli/verify.ts +21 -2
  20. package/src/forge/compiler/agent-contract/build.ts +2 -2
  21. package/src/forge/compiler/diagnostics/codes.ts +6 -0
  22. package/src/forge/compiler/diagnostics/create.ts +1 -1
  23. package/src/forge/compiler/diagnostics/index.ts +2 -0
  24. package/src/forge/compiler/external-manifest/registry.ts +1 -0
  25. package/src/forge/compiler/external-manifest/types.ts +2 -0
  26. package/src/forge/compiler/external-manifest/validate.ts +39 -1
  27. package/src/forge/compiler/types/cli.ts +1 -0
  28. package/src/forge/impact/index.ts +46 -3
  29. package/src/forge/impact/types.ts +6 -0
  30. package/src/forge/repair/rules/index.ts +2 -2
  31. package/src/forge/runtime/external/bridge.ts +101 -5
  32. package/src/forge/version.ts +1 -1
  33. package/src/forge/workspace/change-summary.ts +10 -3
  34. package/src/forge/workspace/git-summary.ts +162 -4
  35. package/src/forge/_generated/actionSubscriptions.json +0 -1
  36. package/src/forge/_generated/actionSubscriptions.ts +0 -10
  37. package/src/forge/_generated/agentAdapterManifest.json +0 -1
  38. package/src/forge/_generated/agentAdapterManifest.ts +0 -72
  39. package/src/forge/_generated/agentCairGuide.md +0 -138
  40. package/src/forge/_generated/agentContract.json +0 -1
  41. package/src/forge/_generated/agentContract.ts +0 -9217
  42. package/src/forge/_generated/agentQuickstart.md +0 -39
  43. package/src/forge/_generated/agentTools.json +0 -1
  44. package/src/forge/_generated/agentTools.md +0 -16
  45. package/src/forge/_generated/agentTools.ts +0 -12
  46. package/src/forge/_generated/aiContext.ts +0 -125
  47. package/src/forge/_generated/aiModels.json +0 -1
  48. package/src/forge/_generated/aiModels.ts +0 -51
  49. package/src/forge/_generated/aiProviders.json +0 -1
  50. package/src/forge/_generated/aiProviders.ts +0 -23
  51. package/src/forge/_generated/aiRegistry.json +0 -1
  52. package/src/forge/_generated/aiRegistry.ts +0 -65
  53. package/src/forge/_generated/api.json +0 -1
  54. package/src/forge/_generated/api.ts +0 -13
  55. package/src/forge/_generated/appGraph.json +0 -1
  56. package/src/forge/_generated/appGraph.ts +0 -118446
  57. package/src/forge/_generated/appMap.md +0 -59
  58. package/src/forge/_generated/artifactManifest.json +0 -1
  59. package/src/forge/_generated/artifactManifest.ts +0 -7
  60. package/src/forge/_generated/authClaims.json +0 -1
  61. package/src/forge/_generated/authClaims.ts +0 -13
  62. package/src/forge/_generated/authConfig.json +0 -1
  63. package/src/forge/_generated/authConfig.ts +0 -17
  64. package/src/forge/_generated/authContext.ts +0 -23
  65. package/src/forge/_generated/authRegistry.json +0 -1
  66. package/src/forge/_generated/authRegistry.ts +0 -25
  67. package/src/forge/_generated/buildInfo.json +0 -1
  68. package/src/forge/_generated/buildInfo.ts +0 -9
  69. package/src/forge/_generated/capabilityMap.json +0 -1
  70. package/src/forge/_generated/capabilityMap.md +0 -15
  71. package/src/forge/_generated/capabilityMap.ts +0 -17
  72. package/src/forge/_generated/client.ts +0 -374
  73. package/src/forge/_generated/clientApi.ts +0 -10
  74. package/src/forge/_generated/clientManifest.json +0 -1
  75. package/src/forge/_generated/clientManifest.ts +0 -52
  76. package/src/forge/_generated/clientTypes.ts +0 -96
  77. package/src/forge/_generated/configRegistry.json +0 -1
  78. package/src/forge/_generated/configRegistry.ts +0 -4
  79. package/src/forge/_generated/dataGraph.json +0 -1
  80. package/src/forge/_generated/dataGraph.ts +0 -8
  81. package/src/forge/_generated/db.json +0 -1
  82. package/src/forge/_generated/db.ts +0 -2
  83. package/src/forge/_generated/dbSecurityManifest.json +0 -1
  84. package/src/forge/_generated/dbSecurityManifest.ts +0 -15
  85. package/src/forge/_generated/dbSessionContext.json +0 -1
  86. package/src/forge/_generated/dbSessionContext.ts +0 -39
  87. package/src/forge/_generated/deployManifest.json +0 -1
  88. package/src/forge/_generated/deployManifest.ts +0 -14
  89. package/src/forge/_generated/devManifest.json +0 -1
  90. package/src/forge/_generated/devManifest.ts +0 -62
  91. package/src/forge/_generated/envSchema.json +0 -1
  92. package/src/forge/_generated/envSchema.ts +0 -59
  93. package/src/forge/_generated/externalServices.json +0 -1
  94. package/src/forge/_generated/externalServices.ts +0 -9
  95. package/src/forge/_generated/frontendGraph.json +0 -1
  96. package/src/forge/_generated/frontendGraph.ts +0 -27
  97. package/src/forge/_generated/importGuards.json +0 -1
  98. package/src/forge/_generated/importGuards.ts +0 -720
  99. package/src/forge/_generated/index.ts +0 -71
  100. package/src/forge/_generated/liveProductionManifest.json +0 -1
  101. package/src/forge/_generated/liveProductionManifest.ts +0 -23
  102. package/src/forge/_generated/liveProtocol.json +0 -1
  103. package/src/forge/_generated/liveProtocol.ts +0 -21
  104. package/src/forge/_generated/liveQueryRegistry.json +0 -1
  105. package/src/forge/_generated/liveQueryRegistry.ts +0 -9
  106. package/src/forge/_generated/liveTransportConfig.json +0 -1
  107. package/src/forge/_generated/liveTransportConfig.ts +0 -19
  108. package/src/forge/_generated/makeRegistry.json +0 -1
  109. package/src/forge/_generated/makeRegistry.ts +0 -177
  110. package/src/forge/_generated/makeTemplates.json +0 -1
  111. package/src/forge/_generated/makeTemplates.ts +0 -66
  112. package/src/forge/_generated/mockMap.json +0 -1
  113. package/src/forge/_generated/mockMap.ts +0 -7
  114. package/src/forge/_generated/operationPlaybooks.md +0 -167
  115. package/src/forge/_generated/packageGraph.json +0 -1
  116. package/src/forge/_generated/packageGraph.ts +0 -5
  117. package/src/forge/_generated/packageUpgradeRegistry.json +0 -1
  118. package/src/forge/_generated/packageUpgradeRegistry.ts +0 -15
  119. package/src/forge/_generated/permissionMatrix.json +0 -1
  120. package/src/forge/_generated/permissionMatrix.ts +0 -7
  121. package/src/forge/_generated/policyRegistry.json +0 -1
  122. package/src/forge/_generated/policyRegistry.ts +0 -11
  123. package/src/forge/_generated/queryRegistry.json +0 -1
  124. package/src/forge/_generated/queryRegistry.ts +0 -9
  125. package/src/forge/_generated/react.d.ts +0 -22
  126. package/src/forge/_generated/react.ts +0 -29
  127. package/src/forge/_generated/reactManifest.json +0 -1
  128. package/src/forge/_generated/reactManifest.ts +0 -19
  129. package/src/forge/_generated/rlsPolicies.json +0 -1
  130. package/src/forge/_generated/rlsPolicies.sql +0 -34
  131. package/src/forge/_generated/rlsPolicies.ts +0 -6
  132. package/src/forge/_generated/runtimeGraph.json +0 -1
  133. package/src/forge/_generated/runtimeGraph.ts +0 -8
  134. package/src/forge/_generated/runtimeMatrix.json +0 -1
  135. package/src/forge/_generated/runtimeMatrix.ts +0 -5
  136. package/src/forge/_generated/runtimeRegistry.ts +0 -2
  137. package/src/forge/_generated/runtimeRules.md +0 -91
  138. package/src/forge/_generated/secretRegistry.json +0 -1
  139. package/src/forge/_generated/secretRegistry.ts +0 -50
  140. package/src/forge/_generated/secretsContext.ts +0 -11
  141. package/src/forge/_generated/serverApi.ts +0 -11
  142. package/src/forge/_generated/sourceMapManifest.json +0 -1
  143. package/src/forge/_generated/sourceMapManifest.ts +0 -7
  144. package/src/forge/_generated/sqlPlan.json +0 -1
  145. package/src/forge/_generated/sqlPlan.ts +0 -88
  146. package/src/forge/_generated/subscriptionManifest.json +0 -1
  147. package/src/forge/_generated/subscriptionManifest.ts +0 -7
  148. package/src/forge/_generated/symbolicationManifest.json +0 -1
  149. package/src/forge/_generated/symbolicationManifest.ts +0 -17
  150. package/src/forge/_generated/telemetryRegistry.json +0 -1
  151. package/src/forge/_generated/telemetryRegistry.ts +0 -70
  152. package/src/forge/_generated/telemetrySinks.json +0 -1
  153. package/src/forge/_generated/telemetrySinks.ts +0 -11
  154. package/src/forge/_generated/tenantScope.json +0 -1
  155. package/src/forge/_generated/tenantScope.ts +0 -8
  156. package/src/forge/_generated/testGraph.json +0 -1
  157. package/src/forge/_generated/testGraph.ts +0 -4068
  158. package/src/forge/_generated/testPlanRegistry.json +0 -1
  159. package/src/forge/_generated/testPlanRegistry.ts +0 -33
  160. package/src/forge/_generated/uiRoutes.json +0 -1
  161. package/src/forge/_generated/uiRoutes.ts +0 -16
  162. package/src/forge/_generated/uiScenarios.json +0 -1
  163. package/src/forge/_generated/uiScenarios.ts +0 -30
  164. package/src/forge/_generated/uiTestManifest.json +0 -1
  165. package/src/forge/_generated/uiTestManifest.ts +0 -27
  166. package/src/forge/_generated/vue.d.ts +0 -25
  167. package/src/forge/_generated/vue.ts +0 -30
  168. package/src/forge/_generated/vueManifest.json +0 -1
  169. package/src/forge/_generated/vueManifest.ts +0 -19
  170. package/src/forge/_generated/workflowRegistry.json +0 -1
  171. package/src/forge/_generated/workflowRegistry.ts +0 -9
  172. package/src/forge/_generated/workflowSubscriptions.json +0 -1
  173. package/src/forge/_generated/workflowSubscriptions.ts +0 -10
package/.npmignore CHANGED
@@ -5,5 +5,9 @@ node_modules/
5
5
  .forge/
6
6
  tests/
7
7
  examples/
8
+ src/forge/_generated/**
9
+ !src/forge/_generated/
10
+ !src/forge/_generated/releaseManifest.json
11
+ !src/forge/_generated/releaseManifest.ts
8
12
  *.tgz
9
13
  npm-debug.log*
package/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- // @forge-generated generator=0.1.0-alpha.19 input=dbb833f96a636461139c36db2e4f1cd158f782313aa1bea3c8d19f33f0945538 content=9b490444cd3dadb6f2c06484033cbcafd219bacb1570b1149c31320a9d929b4e
1
+ // @forge-generated generator=0.1.0-alpha.20 input=a0a760df40f02ebbcf3138bab4133a51f5a69548cba44b7ee4ec711ce57af5c6 content=0d493cf0e41b71cb652d5e0e1b0c1f83d2a1281b748321f0b00f0773ba93074e
2
2
  # AGENTS.md
3
3
 
4
4
  <!-- forge-generated:start -->
@@ -79,7 +79,7 @@ Template apps may ignore `src/forge/_generated/**` and `forge.lock` in git to re
79
79
  ## Runtime rules
80
80
 
81
81
  - Do not import network packages inside `command`, `query`, or `liveQuery`.
82
- - Do not use `process.env` directly.
82
+ - Do not read secrets or server runtime config through `process.env` in Forge runtime code; use `ctx.secrets` or generated config context. Public frontend bridge env such as `NEXT_PUBLIC_*` and `NUXT_PUBLIC_*` is allowed in web bridge files.
83
83
  - Do not access cross-tenant data.
84
84
  - Commands must use `ctx.emit` for side effects.
85
85
  - Actions and workflows handle side effects after commit.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # forgeos
2
2
 
3
+ ## 0.1.0-alpha.20
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix generated-change diagnostics, Codex hook queue handling, and external stdio command parsing.
8
+
9
+ - Classify generated `AGENTS.md` blocks and `.forge/agent/context.json` as derived artifacts in `forge changed`/`forge status`.
10
+ - Skip probe, invalid, and out-of-workspace queued hook events during Agent Memory drain, and bound queue inspection for large hook queues.
11
+ - Preserve empty stdio command arguments, diagnose malformed command strings, and support structured `service.commandArgs` in external manifests.
12
+ - Include the basic example client demo in typecheck coverage.
13
+
3
14
  ## Unreleased
4
15
 
5
16
  ## 0.1.0-alpha.19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forgeos",
3
- "version": "0.1.0-alpha.19",
3
+ "version": "0.1.0-alpha.20",
4
4
  "description": "Agent-native application framework and compiler for building Forge apps without a mandatory dashboard.",
5
5
  "type": "module",
6
6
  "files": [
@@ -12,6 +12,9 @@
12
12
  "packages/eslint-plugin-forge/",
13
13
  "schemas/",
14
14
  "src/",
15
+ "!src/forge/_generated/**",
16
+ "src/forge/_generated/releaseManifest.json",
17
+ "src/forge/_generated/releaseManifest.ts",
15
18
  "templates/",
16
19
  "README.md",
17
20
  "CHANGELOG.md",
@@ -24,6 +27,10 @@
24
27
  "src"
25
28
  ]
26
29
  },
30
+ "workspaces": [
31
+ ".",
32
+ "packages/*"
33
+ ],
27
34
  "bin": {
28
35
  "forge": "bin/forge.mjs"
29
36
  },
@@ -106,5 +113,8 @@
106
113
  "@types/react-test-renderer": "^19.1.0",
107
114
  "fast-check": "^3.23.2",
108
115
  "react-test-renderer": "^19.2.7"
116
+ },
117
+ "overrides": {
118
+ "read-yaml-file": "^3.0.0"
109
119
  }
110
120
  }
@@ -1 +1 @@
1
- {"defaultProvider":"local","diagnostics":[],"env":{"deployEnv":"FORGE_DEPLOY_ENV","deployId":"FORGE_DEPLOY_ID","publicReleaseId":"NEXT_PUBLIC_FORGE_RELEASE_ID","releaseId":"FORGE_RELEASE_ID"},"gitSha":"unknown","optionalProviders":["local","sentry-compatible","sentry","glitchtip","bugsink","otel","custom"],"packageName":"forgeos","packageVersion":"0.1.0-alpha.19","releaseId":"forgeos@0.1.0-alpha.19+unknown","schemaVersion":"0.1.0"}
1
+ {"defaultProvider":"local","diagnostics":[],"env":{"deployEnv":"FORGE_DEPLOY_ENV","deployId":"FORGE_DEPLOY_ID","publicReleaseId":"NEXT_PUBLIC_FORGE_RELEASE_ID","releaseId":"FORGE_RELEASE_ID"},"gitSha":"unknown","optionalProviders":["local","sentry-compatible","sentry","glitchtip","bugsink","otel","custom"],"packageName":"forgeos","packageVersion":"0.1.0-alpha.20","releaseId":"forgeos@0.1.0-alpha.20+unknown","schemaVersion":"0.1.0"}
@@ -1,4 +1,4 @@
1
- // @forge-generated generator=0.1.0-alpha.19 input=dbb833f96a636461139c36db2e4f1cd158f782313aa1bea3c8d19f33f0945538 content=6e5c993e1f8b229e74d2493cff5f16f4075e2a197a5fab9bb6bd9fd901aad63d
1
+ // @forge-generated generator=0.1.0-alpha.20 input=a0a760df40f02ebbcf3138bab4133a51f5a69548cba44b7ee4ec711ce57af5c6 content=3c1af03eecebf9f9b009d8a4a2e08079c9853fca2c742eed3ea3d5b8b68a57b7
2
2
  export const releaseManifest = {
3
3
  "defaultProvider": "local",
4
4
  "diagnostics": [],
@@ -19,7 +19,7 @@ export const releaseManifest = {
19
19
  "custom"
20
20
  ],
21
21
  "packageName": "forgeos",
22
- "packageVersion": "0.1.0-alpha.19",
23
- "releaseId": "forgeos@0.1.0-alpha.19+unknown",
22
+ "packageVersion": "0.1.0-alpha.20",
23
+ "releaseId": "forgeos@0.1.0-alpha.20+unknown",
24
24
  "schemaVersion": "0.1.0"
25
25
  } as const;
@@ -43,6 +43,7 @@ import type { AgentMemoryEventRecord } from "../agent-memory/types.ts";
43
43
  import {
44
44
  formatAgentMemoryHuman,
45
45
  formatAgentMemoryJson,
46
+ inspectAgentMemoryQueueFile,
46
47
  runAgentMemoryCommand,
47
48
  type AgentMemoryCommandResult,
48
49
  } from "../agent-memory/bridge.ts";
@@ -193,7 +194,7 @@ export function buildAgentContext(contract: AgentContract): AgentContext {
193
194
  },
194
195
  knownPitfalls: [
195
196
  "Do not edit src/forge/_generated/** directly.",
196
- "Do not use process.env directly in app code.",
197
+ "Do not read secrets or server runtime config through process.env in Forge runtime code; public frontend bridge env is allowed.",
197
198
  "Do not import network packages in command/query/liveQuery.",
198
199
  "Preserve tenant isolation and policy declarations.",
199
200
  "Use forge make, forge feature, forge refactor, forge impact, and forge repair before hand-editing architecture.",
@@ -487,7 +488,7 @@ function buildCursorFiles(_contract: AgentContract, options: { rules: boolean })
487
488
  `# ForgeOS Security Rules
488
489
 
489
490
  - Never include secret values in generated files, logs, or adapter exports.
490
- - Use \`ctx.secrets\`; do not read \`process.env\` directly in app code.
491
+ - Use \`ctx.secrets\` or generated config context for runtime secrets/config; public frontend bridge env is allowed.
491
492
  - Preserve tenant-scoped reads and writes.
492
493
  - Run \`forge policy check --strict-policies\` after access changes.`,
493
494
  ),
@@ -537,7 +538,7 @@ Critical rules:
537
538
  - Commands cannot use network packages, secrets, or AI.
538
539
  - Queries/liveQueries are read-only.
539
540
  - Use \`ctx.emit\` for side effects.
540
- - Use \`ctx.secrets\`, never \`process.env\`.
541
+ - Use \`ctx.secrets\` or generated config context for runtime secrets/config; public frontend bridge env is allowed.
541
542
  `;
542
543
  return [
543
544
  { path: "CLAUDE.md", content: claude },
@@ -951,6 +952,13 @@ function eventIsForgeHookCanary(event: AgentMemoryEventRecord): boolean {
951
952
  return eventPayload(event).forgeHookCanary === "FORGE_HOOK_SMOKE_CANARY";
952
953
  }
953
954
 
955
+ function eventIsForgeHookProbe(event: AgentMemoryEventRecord): boolean {
956
+ const payload = eventPayload(event);
957
+ return payload.forgeHookProbe === true ||
958
+ payload._parseError === true ||
959
+ payload._invalidPayload === true;
960
+ }
961
+
954
962
  function eventHasUsefulSignal(event: AgentMemoryEventRecord): boolean {
955
963
  const bindings = eventBindings(event);
956
964
  const files = bindings.files;
@@ -969,6 +977,7 @@ function eventHasUsefulSignal(event: AgentMemoryEventRecord): boolean {
969
977
  function eventIsNativeHookEvent(event: AgentMemoryEventRecord): boolean {
970
978
  return (
971
979
  !eventIsForgeHookCanary(event) &&
980
+ !eventIsForgeHookProbe(event) &&
972
981
  event.integrationKind === "native-hook" &&
973
982
  event.trustLevel === "direct-hook"
974
983
  );
@@ -1025,6 +1034,17 @@ function hookApprovalNextActions(target: AgentAdapterTarget, canarySignals = 0):
1025
1034
  ];
1026
1035
  }
1027
1036
 
1037
+ function inspectQueuedHookSignals(workspaceRoot: string, installTarget: string | null) {
1038
+ if (installTarget !== "codex") {
1039
+ return undefined;
1040
+ }
1041
+ return inspectAgentMemoryQueueFile({
1042
+ workspaceRoot,
1043
+ watchFile: join(workspaceRoot, ".forge", "agent", "events.ndjson"),
1044
+ source: "codex",
1045
+ });
1046
+ }
1047
+
1028
1048
  function stringArray(value: unknown): string[] {
1029
1049
  return Array.isArray(value)
1030
1050
  ? value.filter((item): item is string => typeof item === "string" && item.length > 0)
@@ -1288,6 +1308,7 @@ async function readAgentHookStatus(options: AgentCommandOptions): Promise<AgentH
1288
1308
  : true;
1289
1309
  const hookFiles = hookInstallFilesPresent(options.workspaceRoot, installResult);
1290
1310
  const memory = await readHookMemoryStatus(options.workspaceRoot, source, options.limit ?? 25);
1311
+ const queuedHooks = inspectQueuedHookSignals(options.workspaceRoot, installTarget);
1291
1312
  const usefulEvents = memory.events.filter(eventHasUsefulSignal);
1292
1313
  const nativeEvents = memory.events.filter(eventIsNativeHookEvent);
1293
1314
  const canaryEvents = memory.events.filter(eventIsForgeHookCanary);
@@ -1295,9 +1316,11 @@ async function readAgentHookStatus(options: AgentCommandOptions): Promise<AgentH
1295
1316
  const bridgeWritable = installOk;
1296
1317
  const deltaWritable = memory.diagnostics.length === 0;
1297
1318
  const visibleInMemory = memory.events.length > 0;
1298
- const usefulSignals = usefulEvents.length;
1299
- const nativeSignals = nativeEvents.length;
1300
- const canarySignals = canaryEvents.length;
1319
+ const queuedEvents = queuedHooks?.events ?? 0;
1320
+ const usefulSignals = usefulEvents.length + (queuedHooks?.usefulSignals ?? 0);
1321
+ const nativeSignals = nativeEvents.length + (queuedHooks?.nativeSignals ?? 0);
1322
+ const canarySignals = canaryEvents.length + (queuedHooks?.canarySignals ?? 0);
1323
+ const visibleHookSignals = visibleInMemory || queuedEvents > 0;
1301
1324
  const approvalStatus = hookApprovalStatusFor(target, installed, nativeSignals, deltaWritable);
1302
1325
  const approvalRequired = approvalStatus === "waiting-for-user-trust";
1303
1326
  const trustedHookSignals = target === "codex" ? nativeSignals > 0 : true;
@@ -1317,22 +1340,24 @@ async function readAgentHookStatus(options: AgentCommandOptions): Promise<AgentH
1317
1340
  const usesLightweightRunner = codexHookInspection?.usesLightweightRunner === true;
1318
1341
  const hookCommandHealthy = installTarget !== "codex" || (usesLightweightRunner && !usesLegacyForgeCli);
1319
1342
  const hookVersionHealthy = installTarget !== "codex" || !usesLightweightRunner || codexVersionMatch?.matches === true;
1320
- const ok = installed && bridgeWritable && deltaWritable && visibleInMemory && usefulSignals > 0 && trustedHookSignals && !approvalRequired && hookCommandHealthy && hookVersionHealthy;
1343
+ const ok = installed && bridgeWritable && deltaWritable && visibleHookSignals && usefulSignals > 0 && trustedHookSignals && !approvalRequired && hookCommandHealthy && hookVersionHealthy;
1321
1344
  const nextActions = ok
1322
- ? [
1345
+ ? uniqueCommands([
1346
+ ...(queuedEvents > 0 ? [`forge agent ingest ${source} --file .forge/agent/events.ndjson --json`] : []),
1323
1347
  `forge agent memory --entry ${source} --json`,
1324
1348
  `forge agent context --current --json`,
1325
- ]
1326
- : [
1349
+ ])
1350
+ : uniqueCommands([
1327
1351
  ...(!installed ? [`forge agent install ${installTarget} --json`] : []),
1328
1352
  ...(usesLegacyForgeCli ? [`forge agent install ${installTarget} --force --json`] : []),
1329
1353
  ...(codexVersionMatch && !codexVersionMatch.matches ? [`forge agent install ${installTarget} --force --json`] : []),
1330
1354
  ...(approvalRequired ? hookApprovalNextActions(target, canarySignals) : []),
1331
- ...(installed && deltaWritable && !visibleInMemory ? [`forge agent hooks smoke --target ${target} --json`] : []),
1332
- ...(visibleInMemory && usefulSignals === 0 ? [`forge agent ingest ${source} --event PostToolUse --json`] : []),
1355
+ ...(installed && deltaWritable && !visibleHookSignals ? [`forge agent hooks smoke --target ${target} --json`] : []),
1356
+ ...(visibleHookSignals && usefulSignals === 0 ? [`forge agent ingest ${source} --event PostToolUse --json`] : []),
1333
1357
  ...(!deltaWritable ? ["forge delta status --json", "forge delta repair --dry-run --json"] : []),
1358
+ ...(queuedEvents > 0 ? [`forge agent ingest ${source} --file .forge/agent/events.ndjson --json`] : []),
1334
1359
  ...(usesLightweightRunner ? [`forge agent ingest ${source} --watch --file .forge/agent/events.ndjson --json`] : []),
1335
- ];
1360
+ ]);
1336
1361
 
1337
1362
  return {
1338
1363
  ok,
@@ -1343,6 +1368,7 @@ async function readAgentHookStatus(options: AgentCommandOptions): Promise<AgentH
1343
1368
  deltaWritable,
1344
1369
  visibleInMemory,
1345
1370
  recentEvents: memory.events.length,
1371
+ queuedEvents,
1346
1372
  usefulSignals,
1347
1373
  nativeSignals,
1348
1374
  canarySignals,
@@ -1372,15 +1398,21 @@ async function readAgentHookStatus(options: AgentCommandOptions): Promise<AgentH
1372
1398
  },
1373
1399
  {
1374
1400
  name: "visible-in-memory",
1375
- ok: visibleInMemory,
1401
+ ok: visibleHookSignals,
1376
1402
  message: visibleInMemory
1377
1403
  ? `${memory.events.length} recent ${source} events visible for this workspace`
1404
+ : queuedEvents > 0
1405
+ ? `${queuedEvents} queued ${source} hook event(s) visible for this workspace and waiting for ingest`
1378
1406
  : memory.ignoredOutOfWorkspaceEvents > 0
1379
1407
  ? `ignored ${memory.ignoredOutOfWorkspaceEvents} ${source} event(s) from other workspaces`
1380
1408
  : "no hook events visible in memory yet",
1381
1409
  evidence: {
1382
1410
  workspaceRoot: memory.workspaceRoot,
1383
1411
  ignoredOutOfWorkspaceEvents: memory.ignoredOutOfWorkspaceEvents,
1412
+ queuedEvents,
1413
+ queuedNativeSignals: queuedHooks?.nativeSignals ?? 0,
1414
+ queuedCanarySignals: queuedHooks?.canarySignals ?? 0,
1415
+ queuedLatestEventAt: queuedHooks?.latestEventAt,
1384
1416
  },
1385
1417
  },
1386
1418
  {
@@ -1409,11 +1441,13 @@ async function readAgentHookStatus(options: AgentCommandOptions): Promise<AgentH
1409
1441
  : !deltaWritable
1410
1442
  ? "trusted Codex native hook signals cannot be verified until Agent Memory is readable"
1411
1443
  : nativeSignals > 0
1412
- ? `${nativeSignals} trusted Codex native hook signal(s) visible`
1444
+ ? `${nativeSignals} trusted Codex native hook signal(s) visible or queued`
1413
1445
  : "Codex has not emitted a trusted native hook signal yet",
1414
1446
  evidence: {
1415
1447
  nativeSignals,
1416
1448
  canarySignals,
1449
+ queuedNativeSignals: queuedHooks?.nativeSignals ?? 0,
1450
+ queuedCanarySignals: queuedHooks?.canarySignals ?? 0,
1417
1451
  memoryReadable: deltaWritable,
1418
1452
  trustBoundary: target === "codex" ? "codex-desktop-hook-approval" : "not-required",
1419
1453
  },
@@ -1508,13 +1542,17 @@ export async function runAgentDoctor(options: AgentCommandOptions): Promise<Agen
1508
1542
  ? hookInstallFilesPresent(options.workspaceRoot, installResult)
1509
1543
  : { planned: [], missing: [] };
1510
1544
  const memory = await readHookMemoryStatus(options.workspaceRoot, source, options.limit ?? 25);
1545
+ const queuedHooks = inspectQueuedHookSignals(options.workspaceRoot, installTarget);
1511
1546
  const memoryDiagnostics = memory.diagnostics;
1512
1547
  const recentEvents = memory.events;
1513
1548
  const usefulEvents = recentEvents.filter(eventHasUsefulSignal);
1514
1549
  const nativeEvents = recentEvents.filter(eventIsNativeHookEvent);
1515
1550
  const canaryEvents = recentEvents.filter(eventIsForgeHookCanary);
1516
- const nativeSignals = nativeEvents.length;
1517
- const canarySignals = canaryEvents.length;
1551
+ const queuedEvents = queuedHooks?.events ?? 0;
1552
+ const visibleHookSignals = recentEvents.length > 0 || queuedEvents > 0;
1553
+ const usefulSignals = usefulEvents.length + (queuedHooks?.usefulSignals ?? 0);
1554
+ const nativeSignals = nativeEvents.length + (queuedHooks?.nativeSignals ?? 0);
1555
+ const canarySignals = canaryEvents.length + (queuedHooks?.canarySignals ?? 0);
1518
1556
  const adapterState = check.missing.length > 0 ? "missing" : check.stale.length > 0 ? "stale" : "ready";
1519
1557
  const installed = !installTarget || hookFiles.missing.length === 0;
1520
1558
  const memoryReadable = memoryDiagnostics.length === 0;
@@ -1552,11 +1590,13 @@ export async function runAgentDoctor(options: AgentCommandOptions): Promise<Agen
1552
1590
  },
1553
1591
  {
1554
1592
  name: "recent-memory",
1555
- ok: (!installTarget || recentEvents.length > 0) && memoryDiagnostics.length === 0,
1593
+ ok: (!installTarget || visibleHookSignals) && memoryDiagnostics.length === 0,
1556
1594
  message: memoryDiagnostics.length > 0
1557
1595
  ? "agent memory store is unavailable"
1558
1596
  : recentEvents.length > 0
1559
1597
  ? `${recentEvents.length} recent ${source} memory events for this workspace`
1598
+ : queuedEvents > 0
1599
+ ? `${queuedEvents} queued ${source} hook event(s) for this workspace are waiting for ingest`
1560
1600
  : memory.ignoredOutOfWorkspaceEvents > 0
1561
1601
  ? `ignored ${memory.ignoredOutOfWorkspaceEvents} ${source} event(s) from other workspaces`
1562
1602
  : "no recent agent memory events found",
@@ -1569,6 +1609,10 @@ export async function runAgentDoctor(options: AgentCommandOptions): Promise<Agen
1569
1609
  capturedAt: event.capturedAt,
1570
1610
  workspaceRoot: eventWorkspaceRoot(event),
1571
1611
  })),
1612
+ queuedEvents,
1613
+ queuedNativeSignals: queuedHooks?.nativeSignals ?? 0,
1614
+ queuedCanarySignals: queuedHooks?.canarySignals ?? 0,
1615
+ queuedLatestEventAt: queuedHooks?.latestEventAt,
1572
1616
  },
1573
1617
  },
1574
1618
  {
@@ -1584,9 +1628,9 @@ export async function runAgentDoctor(options: AgentCommandOptions): Promise<Agen
1584
1628
  },
1585
1629
  {
1586
1630
  name: "useful-signals",
1587
- ok: !installTarget || usefulEvents.length > 0,
1588
- message: usefulEvents.length > 0
1589
- ? `${usefulEvents.length} events include files, entries, commands, tools, status, or proofs`
1631
+ ok: !installTarget || usefulSignals > 0,
1632
+ message: usefulSignals > 0
1633
+ ? `${usefulSignals} events include files, entries, commands, tools, status, or proofs`
1590
1634
  : "events do not yet include useful files, entries, commands, tools, status, or proofs",
1591
1635
  },
1592
1636
  {
@@ -1597,11 +1641,13 @@ export async function runAgentDoctor(options: AgentCommandOptions): Promise<Agen
1597
1641
  : !memoryReadable
1598
1642
  ? "trusted Codex native hook signals cannot be verified until Agent Memory is readable"
1599
1643
  : nativeSignals > 0
1600
- ? `${nativeSignals} trusted Codex native hook signal(s) visible`
1644
+ ? `${nativeSignals} trusted Codex native hook signal(s) visible or queued`
1601
1645
  : "Codex has not emitted a trusted native hook signal yet",
1602
1646
  evidence: {
1603
1647
  nativeSignals,
1604
1648
  canarySignals,
1649
+ queuedNativeSignals: queuedHooks?.nativeSignals ?? 0,
1650
+ queuedCanarySignals: queuedHooks?.canarySignals ?? 0,
1605
1651
  memoryReadable,
1606
1652
  trustBoundary: target === "codex" ? "codex-desktop-hook-approval" : "not-required",
1607
1653
  },
@@ -1625,8 +1671,9 @@ export async function runAgentDoctor(options: AgentCommandOptions): Promise<Agen
1625
1671
  ...(installTarget && hookFiles.missing.length > 0 ? [`forge agent install ${installTarget} --json`] : []),
1626
1672
  ...(approvalRequired ? hookApprovalNextActions(target, canarySignals) : []),
1627
1673
  ...(memoryDiagnostics.length > 0 ? ["forge delta status --json", "forge delta repair --dry-run --json"] : []),
1628
- ...(installTarget && recentEvents.length === 0 && memoryDiagnostics.length === 0 ? [`forge agent hooks smoke --target ${target} --json`] : []),
1629
- ...(installTarget && recentEvents.length > 0 && usefulEvents.length === 0 ? [`forge agent ingest ${source} --event PostToolUse --json`] : []),
1674
+ ...(installTarget && !visibleHookSignals && memoryDiagnostics.length === 0 ? [`forge agent hooks smoke --target ${target} --json`] : []),
1675
+ ...(installTarget && visibleHookSignals && usefulSignals === 0 ? [`forge agent ingest ${source} --event PostToolUse --json`] : []),
1676
+ ...(queuedEvents > 0 ? [`forge agent ingest ${source} --file .forge/agent/events.ndjson --json`] : []),
1630
1677
  ];
1631
1678
  return {
1632
1679
  ok,
@@ -1637,10 +1684,13 @@ export async function runAgentDoctor(options: AgentCommandOptions): Promise<Agen
1637
1684
  approvalRequired,
1638
1685
  approvalStatus,
1639
1686
  recentEvents: recentEvents.length,
1640
- usefulSignals: usefulEvents.length,
1687
+ queuedEvents,
1688
+ usefulSignals,
1641
1689
  nativeSignals,
1642
1690
  canarySignals,
1643
- ...(recentEvents.at(-1)?.capturedAt ? { lastEventAt: recentEvents.at(-1)?.capturedAt } : {}),
1691
+ ...(recentEvents.at(-1)?.capturedAt || queuedHooks?.latestEventAt
1692
+ ? { lastEventAt: queuedHooks?.latestEventAt ?? recentEvents.at(-1)?.capturedAt }
1693
+ : {}),
1644
1694
  },
1645
1695
  checks,
1646
1696
  nextActions,
@@ -2313,6 +2363,7 @@ export function formatAgentHuman(result: Awaited<ReturnType<typeof runAgentComma
2313
2363
  `canary signals: ${result.canarySignals}`,
2314
2364
  `approval: ${result.approvalStatus}`,
2315
2365
  ...("recentEvents" in result ? [`recent events: ${result.recentEvents}`] : []),
2366
+ ...("queuedEvents" in result ? [`queued events: ${result.queuedEvents ?? 0}`] : []),
2316
2367
  ...(result.lastSignal ? [`last signal: ${result.lastSignal.kind}${result.lastSignal.summary ? ` - ${result.lastSignal.summary}` : ""}`] : []),
2317
2368
  ...(result.nextActions.length > 0 ? ["", "Next:", ...result.nextActions.map((command) => ` ${command}`)] : []),
2318
2369
  ].join("\n") + "\n";
@@ -149,6 +149,7 @@ export interface AgentDoctorResult {
149
149
  approvalRequired: boolean;
150
150
  approvalStatus: AgentHookApprovalStatus;
151
151
  recentEvents: number;
152
+ queuedEvents?: number;
152
153
  usefulSignals: number;
153
154
  nativeSignals: number;
154
155
  canarySignals: number;
@@ -275,6 +276,7 @@ export interface AgentHooksStatusResult {
275
276
  deltaWritable: boolean;
276
277
  visibleInMemory: boolean;
277
278
  recentEvents: number;
279
+ queuedEvents?: number;
278
280
  usefulSignals: number;
279
281
  nativeSignals: number;
280
282
  canarySignals: number;