Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 1 addition & 31 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,4 @@ jobs:
- run: npm ci

- run: npm run build

# Guards the evals/jumbo CLI contract: builds jumbo from THIS commit's source
# and runs the evals against it (not a published binary), so a primitive
# refactor that breaks the CLI surface the evals depend on fails the PR here.
evals:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '22'
cache: 'npm'

# Build jumbo from source → dist/cli.js (the binary the evals will exercise).
- run: npm ci
- run: npm run build

# Evals as an independent nested project, run against the freshly-built jumbo.
- run: npm ci
working-directory: evals
# Eval self-consistency (does not invoke jumbo).
- run: npm test
working-directory: evals
# The evals/jumbo CLI contract guard — exercises real jumbo (from source)
# through the surface the evals depend on. This is what catches a primitive
# refactor that would otherwise silently rot the evals.
- run: npm run smoke:jumbo
working-directory: evals

48 changes: 36 additions & 12 deletions src/infrastructure/context/project/init/AntigravityConfigurer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,25 +219,32 @@ export class AntigravityConfigurer implements IConfigurer {
try {
const content = await fs.readFile(settingsPath, "utf-8");
if (content.trim()) {
const settings = JSON.parse(content);
const parsedSettings = JSON.parse(content) as unknown;
if (!AntigravityConfigurer.isObject(parsedSettings)) {
return;
}
const settings = parsedSettings;

// Remove jumbo-specific hooks
if (settings.hooks) {
if (AntigravityConfigurer.isObject(settings.hooks)) {
for (const eventType of Object.keys(settings.hooks)) {
const matchers = settings.hooks[eventType];
if (Array.isArray(matchers)) {
settings.hooks[eventType] = matchers
.map((matcher: any) => {
if (matcher && Array.isArray(matcher.hooks)) {
matcher.hooks = matcher.hooks.filter((hook: any) => {
return hook && !(typeof hook.command === "string" && hook.command.includes("jumbo"));
const cleanedMatchers = matchers
.map((matcher: unknown) => {
if (AntigravityConfigurer.isObject(matcher) && Array.isArray(matcher.hooks)) {
matcher.hooks = matcher.hooks.filter((hook: unknown) => {
return AntigravityConfigurer.shouldKeepLegacyHook(hook);
});
}
return matcher;
})
.filter((matcher: any) => matcher && Array.isArray(matcher.hooks) && matcher.hooks.length > 0);
.filter((matcher: unknown) => {
return AntigravityConfigurer.isObject(matcher) && Array.isArray(matcher.hooks) && matcher.hooks.length > 0;
});
settings.hooks[eventType] = cleanedMatchers;

if (settings.hooks[eventType].length === 0) {
if (cleanedMatchers.length === 0) {
delete settings.hooks[eventType];
}
}
Expand All @@ -248,11 +255,12 @@ export class AntigravityConfigurer implements IConfigurer {
}

// Remove jumbo-specific allowed tools
if (settings.tools && Array.isArray(settings.tools.allowed)) {
settings.tools.allowed = settings.tools.allowed.filter((tool: string) => {
if (AntigravityConfigurer.isObject(settings.tools) && Array.isArray(settings.tools.allowed)) {
const allowedTools = settings.tools.allowed.filter((tool: unknown) => {
return typeof tool === "string" && !tool.includes("jumbo") && !tool.includes("antigravity-hook.mjs");
});
if (settings.tools.allowed.length === 0) {
settings.tools.allowed = allowedTools;
if (allowedTools.length === 0) {
delete settings.tools.allowed;
}
}
Expand Down Expand Up @@ -323,4 +331,20 @@ export class AntigravityConfigurer implements IConfigurer {
private getHookRunnerPath(projectRoot: string): string {
return path.join(projectRoot, ".agents", "jumbo", "antigravity-hook.mjs");
}

private static isObject(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value);
}

private static shouldKeepLegacyHook(hook: unknown): boolean {
if (!hook) {
return false;
}

if (AntigravityConfigurer.isObject(hook) && typeof hook.command === "string") {
return !hook.command.includes("jumbo");
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class GoalListOutputBuilder {
}
}

let output = lines.join("\n");
const output = lines.join("\n");

this.builder.addPrompt(output);
return this.builder.build();
Expand Down
2 changes: 1 addition & 1 deletion src/presentation/cli/commands/project/init/project.init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ export async function projectInit(

// Determine project details and primitives based on mode
let projectDetails: ProjectInitOptions;
let primitives: PrimitiveOptions = {
const primitives: PrimitiveOptions = {
audiences: [],
audiencePains: [],
valuePropositions: [],
Expand Down
5 changes: 0 additions & 5 deletions tui-dev.tsx

This file was deleted.

Loading