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
7 changes: 7 additions & 0 deletions .changeset/patch-refactor-mcp-server-utilities.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

357 changes: 159 additions & 198 deletions .github/workflows/ai-triage-campaign.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/archie.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/artifacts-summary.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/audit-workflows.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/blog-auditor.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/brave.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/changeset.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/ci-doctor.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/cli-consistency-checker.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/cli-version-checker.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/cloclo.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/commit-changes-analyzer.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/copilot-agent-analysis.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/copilot-pr-nlp-analysis.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/copilot-pr-prompt-analysis.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/copilot-session-insights.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/craft.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-code-metrics.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-doc-updater.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-file-diet.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-firewall-report.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-malicious-code-scan.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-multi-device-docs-tester.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-news.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/daily-repo-chronicle.lock.yml

Large diffs are not rendered by default.

360 changes: 162 additions & 198 deletions .github/workflows/daily-team-status.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/dependabot-go-checker.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/dev-hawk.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/dev.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/developer-docs-consolidator.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/dictation-prompt.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/docs-noob-tester.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/duplicate-code-detector.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/example-workflow-analyzer.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/github-mcp-tools-report.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/glossary-maintainer.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/go-logger.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/go-pattern-detector.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/grumpy-reviewer.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/instructions-janitor.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/issue-classifier.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/lockfile-stats.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/mcp-inspector.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/mergefest.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/notion-issue-summary.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/pdf-summary.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/plan.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/poem-bot.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/pr-nitpick-reviewer.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/prompt-clustering-analysis.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/python-data-charts.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/q.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/release-highlights.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/repo-tree-map.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/repository-quality-improver.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/research.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/safe-output-health.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/schema-consistency-checker.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/scout.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/security-fix-pr.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/semantic-function-refactor.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/smoke-claude.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/smoke-codex.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/smoke-copilot.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/smoke-detector.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/static-analysis-report.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/super-linter.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/technical-doc-writer.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/test-assign-milestone-allowed.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/test-claude-assign-milestone.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/test-close-discussion.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/test-codex-assign-milestone.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/test-copilot-assign-milestone.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/test-ollama-threat-detection.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/tidy.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/typist.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/unbloat-docs.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/video-analyzer.lock.yml

Large diffs are not rendered by default.

357 changes: 159 additions & 198 deletions .github/workflows/weekly-issue-summary.lock.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ fuzz:
# Test JavaScript files
.PHONY: test-js
test-js: build-js
cd pkg/workflow/js && npm run test:js
cd pkg/workflow/js && npm run test:js -- --no-file-parallelism

.PHONY: build-js
build-js:
Expand Down
17 changes: 15 additions & 2 deletions pkg/workflow/bundler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var bundlerLog = logger.New("workflow:bundler")
// mainContent is the main JavaScript content that may contain require() calls
// basePath is the base directory path for resolving relative imports (e.g., "js")
func BundleJavaScriptFromSources(mainContent string, sources map[string]string, basePath string) (string, error) {
bundlerLog.Printf("Bundling JavaScript: source_count=%d, base_path=%s", len(sources), basePath)
bundlerLog.Printf("Bundling JavaScript: source_count=%d, base_path=%s, main_content_size=%d bytes", len(sources), basePath, len(mainContent))

// Track already processed files to avoid circular dependencies
processed := make(map[string]bool)
Expand All @@ -37,7 +37,17 @@ func BundleJavaScriptFromSources(mainContent string, sources map[string]string,
return "", err
}

bundlerLog.Printf("Bundling completed: processed_files=%d, output_size=%d bytes", len(processed), len(bundled))
// Log size information about the bundled output
lines := strings.Split(bundled, "\n")
var maxLineLength int
for _, line := range lines {
if len(line) > maxLineLength {
maxLineLength = len(line)
}
}

bundlerLog.Printf("Bundling completed: processed_files=%d, output_size=%d bytes, output_lines=%d, max_line_length=%d chars",
len(processed), len(bundled), len(lines), maxLineLength)
return bundled, nil
}

Expand Down Expand Up @@ -111,6 +121,8 @@ func bundleFromSources(content string, currentPath string, sources map[string]st
return "", fmt.Errorf("required file not found in sources: %s", fullPath)
}

bundlerLog.Printf("Inlining file: %s (size: %d bytes)", fullPath, len(requiredContent))

// Recursively bundle the required file
requiredDir := filepath.Dir(fullPath)
bundledRequired, err := bundleFromSources(requiredContent, requiredDir, sources, processed)
Expand All @@ -120,6 +132,7 @@ func bundleFromSources(content string, currentPath string, sources map[string]st

// Remove exports from the bundled content
cleanedRequired := removeExports(bundledRequired)
bundlerLog.Printf("Processed %s: original_size=%d, after_export_removal=%d", fullPath, len(bundledRequired), len(cleanedRequired))

// Add a comment indicating the inlined file
result.WriteString(fmt.Sprintf("// === Inlined from %s ===\n", requirePath))
Expand Down
86 changes: 69 additions & 17 deletions pkg/workflow/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,31 @@ var validateErrorsScript string
var missingToolScript string

//go:embed js/safe_outputs_mcp_server.cjs
var safeOutputsMCPServerScript string
var safeOutputsMCPServerScriptSource string

var (
safeOutputsMCPServerScript string
safeOutputsMCPServerScriptOnce sync.Once
)

// getSafeOutputsMCPServerScript returns the bundled safe_outputs_mcp_server script
// Bundling is performed on first access and cached for subsequent calls
func getSafeOutputsMCPServerScript() string {
safeOutputsMCPServerScriptOnce.Do(func() {
jsLog.Print("Bundling safe_outputs_mcp_server script")
sources := GetJavaScriptSources()
bundled, err := BundleJavaScriptFromSources(safeOutputsMCPServerScriptSource, sources, "")
if err != nil {
jsLog.Printf("Failed to bundle safe_outputs_mcp_server script, using source as-is: %v", err)
// If bundling fails, use the source as-is
safeOutputsMCPServerScript = safeOutputsMCPServerScriptSource
} else {
jsLog.Printf("Successfully bundled safe_outputs_mcp_server script: %d bytes", len(bundled))
safeOutputsMCPServerScript = bundled
}
})
return safeOutputsMCPServerScript
}

//go:embed js/safe_outputs_tools.json
var safeOutputsToolsJSON string
Expand Down Expand Up @@ -152,25 +176,53 @@ var getRepositoryUrlScript string
//go:embed js/check_permissions_utils.cjs
var checkPermissionsUtilsScript string

//go:embed js/normalize_branch_name.cjs
var normalizeBranchNameScript string

//go:embed js/estimate_tokens.cjs
var estimateTokensScript string

//go:embed js/generate_compact_schema.cjs
var generateCompactSchemaScript string

//go:embed js/write_large_content_to_file.cjs
var writeLargeContentToFileScript string

//go:embed js/get_current_branch.cjs
var getCurrentBranchScript string

//go:embed js/get_base_branch.cjs
var getBaseBranchScript string

//go:embed js/generate_git_patch.cjs
var generateGitPatchJSScript string

// GetJavaScriptSources returns a map of all embedded JavaScript sources
// The keys are the relative paths from the js directory
func GetJavaScriptSources() map[string]string {
return map[string]string{
"sanitize_content.cjs": sanitizeContentScript,
"sanitize_label_content.cjs": sanitizeLabelContentScript,
"sanitize_workflow_name.cjs": sanitizeWorkflowNameScript,
"load_agent_output.cjs": loadAgentOutputScript,
"staged_preview.cjs": stagedPreviewScript,
"safe_output_helpers.cjs": safeOutputHelpersScript,
"safe_output_validator.cjs": safeOutputValidatorScript,
"is_truthy.cjs": isTruthyScript,
"log_parser_bootstrap.cjs": logParserBootstrapScript,
"log_parser_shared.cjs": logParserSharedScript,
"update_activation_comment.cjs": updateActivationCommentScript,
"generate_footer.cjs": generateFooterScript,
"get_tracker_id.cjs": getTrackerIDScript,
"get_repository_url.cjs": getRepositoryUrlScript,
"check_permissions_utils.cjs": checkPermissionsUtilsScript,
"sanitize_content.cjs": sanitizeContentScript,
"sanitize_label_content.cjs": sanitizeLabelContentScript,
"sanitize_workflow_name.cjs": sanitizeWorkflowNameScript,
"load_agent_output.cjs": loadAgentOutputScript,
"staged_preview.cjs": stagedPreviewScript,
"safe_output_helpers.cjs": safeOutputHelpersScript,
"safe_output_validator.cjs": safeOutputValidatorScript,
"is_truthy.cjs": isTruthyScript,
"log_parser_bootstrap.cjs": logParserBootstrapScript,
"log_parser_shared.cjs": logParserSharedScript,
"update_activation_comment.cjs": updateActivationCommentScript,
"generate_footer.cjs": generateFooterScript,
"get_tracker_id.cjs": getTrackerIDScript,
"get_repository_url.cjs": getRepositoryUrlScript,
"check_permissions_utils.cjs": checkPermissionsUtilsScript,
"normalize_branch_name.cjs": normalizeBranchNameScript,
"estimate_tokens.cjs": estimateTokensScript,
"generate_compact_schema.cjs": generateCompactSchemaScript,
"write_large_content_to_file.cjs": writeLargeContentToFileScript,
"get_current_branch.cjs": getCurrentBranchScript,
"get_base_branch.cjs": getBaseBranchScript,
"generate_git_patch.cjs": generateGitPatchJSScript,
}
}

Expand Down Expand Up @@ -617,7 +669,7 @@ func GetLogParserBootstrap() string {

// GetSafeOutputsMCPServerScript returns the JavaScript content for the GitHub Agentic Workflows Safe Outputs MCP server
func GetSafeOutputsMCPServerScript() string {
return safeOutputsMCPServerScript
return getSafeOutputsMCPServerScript()
}

// GetSafeOutputsToolsJSON returns the JSON content for the safe outputs tools definitions
Expand Down
16 changes: 16 additions & 0 deletions pkg/workflow/js/estimate_tokens.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// @ts-check
/// <reference types="@actions/github-script" />

/**
* Estimates token count from text using 4 chars per token estimate
* @param {string} text - The text to estimate tokens for
* @returns {number} Approximate token count
*/
function estimateTokens(text) {
if (!text) return 0;
return Math.ceil(text.length / 4);
}

module.exports = {
estimateTokens,
};
52 changes: 52 additions & 0 deletions pkg/workflow/js/estimate_tokens.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { describe, it, expect } from "vitest";

describe("estimateTokens", () => {
it("should estimate tokens for text", async () => {
const { estimateTokens } = await import("./estimate_tokens.cjs");

expect(estimateTokens("hello")).toBe(2); // 5 chars / 4 = 1.25, ceil = 2
expect(estimateTokens("test")).toBe(1); // 4 chars / 4 = 1
expect(estimateTokens("testing")).toBe(2); // 7 chars / 4 = 1.75, ceil = 2
});

it("should handle empty strings and null", async () => {
const { estimateTokens } = await import("./estimate_tokens.cjs");

expect(estimateTokens("")).toBe(0);
expect(estimateTokens(null)).toBe(0);
expect(estimateTokens(undefined)).toBe(0);
});

it("should handle long text", async () => {
const { estimateTokens } = await import("./estimate_tokens.cjs");

const longText = "a".repeat(1000);
expect(estimateTokens(longText)).toBe(250); // 1000 / 4 = 250
});

it("should round up using Math.ceil", async () => {
const { estimateTokens } = await import("./estimate_tokens.cjs");

expect(estimateTokens("a")).toBe(1); // 1 / 4 = 0.25, ceil = 1
expect(estimateTokens("ab")).toBe(1); // 2 / 4 = 0.5, ceil = 1
expect(estimateTokens("abc")).toBe(1); // 3 / 4 = 0.75, ceil = 1
expect(estimateTokens("abcd")).toBe(1); // 4 / 4 = 1
expect(estimateTokens("abcde")).toBe(2); // 5 / 4 = 1.25, ceil = 2
});

it("should handle multi-byte characters", async () => {
const { estimateTokens } = await import("./estimate_tokens.cjs");

// Note: This uses string length, not byte length
expect(estimateTokens("😀")).toBe(1); // 1 char (even though it's 4 bytes)
expect(estimateTokens("你好世界")).toBe(1); // 4 chars / 4 = 1
});

it("should handle whitespace and special characters", async () => {
const { estimateTokens } = await import("./estimate_tokens.cjs");

expect(estimateTokens(" ")).toBe(1); // 3 spaces / 4 = 0.75, ceil = 1
expect(estimateTokens("\n\n\n\n")).toBe(1); // 4 newlines / 4 = 1
expect(estimateTokens("!@#$%")).toBe(2); // 5 special chars / 4 = 1.25, ceil = 2
});
});
43 changes: 43 additions & 0 deletions pkg/workflow/js/generate_compact_schema.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// @ts-check
/// <reference types="@actions/github-script" />

/**
* Generates a compact schema description from JSON content
* @param {string} content - The JSON content to analyze
* @returns {string} Compact schema description for jq/agent
*/
function generateCompactSchema(content) {
try {
const parsed = JSON.parse(content);

// Generate a compact schema based on the structure
if (Array.isArray(parsed)) {
if (parsed.length === 0) {
return "[]";
}
// For arrays, describe the first element's structure
const firstItem = parsed[0];
if (typeof firstItem === "object" && firstItem !== null) {
const keys = Object.keys(firstItem);
return `[{${keys.join(", ")}}] (${parsed.length} items)`;
}
return `[${typeof firstItem}] (${parsed.length} items)`;
} else if (typeof parsed === "object" && parsed !== null) {
// For objects, list top-level keys
const keys = Object.keys(parsed);
if (keys.length > 10) {
return `{${keys.slice(0, 10).join(", ")}, ...} (${keys.length} keys)`;
}
return `{${keys.join(", ")}}`;
}

return `${typeof parsed}`;
} catch {
// If not valid JSON, return generic description
return "text content";
}
}

module.exports = {
generateCompactSchema,
};
86 changes: 86 additions & 0 deletions pkg/workflow/js/generate_compact_schema.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { describe, it, expect } from "vitest";

describe("generateCompactSchema", () => {
it("should handle empty arrays", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

expect(generateCompactSchema("[]")).toBe("[]");
});

it("should describe array of objects", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

const json = JSON.stringify([
{ id: 1, name: "test", value: 10 },
{ id: 2, name: "test2", value: 20 },
]);
expect(generateCompactSchema(json)).toBe("[{id, name, value}] (2 items)");
});

it("should describe array of primitives", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

expect(generateCompactSchema("[1, 2, 3]")).toBe("[number] (3 items)");
expect(generateCompactSchema('["a", "b", "c"]')).toBe("[string] (3 items)");
expect(generateCompactSchema("[true, false]")).toBe("[boolean] (2 items)");
});

it("should describe objects with few keys", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

const json = JSON.stringify({ id: 1, name: "test", value: 10 });
expect(generateCompactSchema(json)).toBe("{id, name, value}");
});

it("should describe objects with many keys", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

const obj = {};
for (let i = 0; i < 15; i++) {
obj[`key${i}`] = i;
}
const json = JSON.stringify(obj);
const schema = generateCompactSchema(json);
expect(schema).toMatch(/^\{key0, key1, .+\.\.\.\} \(15 keys\)$/);
});

it("should handle primitives", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

expect(generateCompactSchema("123")).toBe("number");
expect(generateCompactSchema('"hello"')).toBe("string");
expect(generateCompactSchema("true")).toBe("boolean");
expect(generateCompactSchema("null")).toBe("object"); // JSON.parse(null) is object
});

it("should handle invalid JSON", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

expect(generateCompactSchema("not valid json")).toBe("text content");
expect(generateCompactSchema("")).toBe("text content");
expect(generateCompactSchema("{invalid}")).toBe("text content");
});

it("should handle nested structures", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

const json = JSON.stringify({
users: [{ id: 1, name: "test" }],
meta: { total: 1 },
});
expect(generateCompactSchema(json)).toBe("{users, meta}");
});

it("should handle single item arrays", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

expect(generateCompactSchema("[1]")).toBe("[number] (1 items)");
expect(generateCompactSchema('[{"id": 1}]')).toBe("[{id}] (1 items)");
});

it("should handle empty objects", async () => {
const { generateCompactSchema } = await import("./generate_compact_schema.cjs");

expect(generateCompactSchema("{}")).toBe("{}");
});
});
Loading
Loading