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
92 changes: 0 additions & 92 deletions AGENTS.md

This file was deleted.

183 changes: 183 additions & 0 deletions DeveloperDashboard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
function DeveloperDashboard() {
const { useState, useCallback, useEffect } = React;
const [activeTab, setActiveTab] = useState('component_manager');
const [newComponentName, setNewComponentName] = useState('');
const [generatedCode, setGeneratedCode] = useState('');
const [scriptTag, setScriptTag] = useState('');
const [manifest, setManifest] = useState({ components: [], tests: [] });
const [selectedComponent, setSelectedComponent] = useState('');
const [generatedTestCode, setGeneratedTestCode] = useState('');

useEffect(() => {
// In a real application, we would fetch a manifest.json file here.
// For now, we will use a hardcoded list of components.
setManifest({
components: ['JulesIntrospector.jsx', 'TestComponent.jsx'],
tests: ['JulesIntrospector.test.jsx']
});
}, []);

const componentTemplate = (name) => `
function ${name}() {
const { useState, useEffect } = React;
return (
<div>
<h1>${name} Component</h1>
<p>This is a new component generated by the Developer Dashboard.</p>
</div>
);
}

// --- Self-Rendering Logic ---
const container = document.getElementById('root');
if (container) {
const root = ReactDOM.createRoot(container);
root.render(React.createElement(${name}));
}
`;

const testTemplate = (name) => `
function ${name}Test() {
const { useEffect } = React;

useEffect(() => {
let success = false;
let message = '${name} did not render correctly';

try {
const component = document.querySelector('h1');
if (component && component.textContent === "${name} Component") {
success = true;
message = '${name} rendered correctly';
}
} catch (e) {
message = \`An error occurred during the test: \${e.message}\`;
}

window.parent.postMessage({
type: 'test-complete',
detail: { success, message }
}, '*');
}, []);

return React.createElement(${name});
}

// --- Self-Rendering Logic ---
const container = document.getElementById('root');
if (container) {
const root = ReactDOM.createRoot(container);
root.render(React.createElement(${name}Test));
}
`;

const handleGenerateCode = useCallback(() => {
if (!newComponentName) {
alert('Please enter a component name.');
return;
}
const componentName = newComponentName.trim();
const boilerplate = componentTemplate(componentName);
setGeneratedCode(boilerplate);
setScriptTag(`<script type="text/babel" src="src/${componentName}.jsx"></script>`);
}, [newComponentName]);

const handleGenerateTestCode = useCallback(() => {
if (!selectedComponent) {
alert('Please select a component to test.');
return;
}
const componentName = selectedComponent.replace('.jsx', '');
const boilerplate = testTemplate(componentName);
setGeneratedTestCode(boilerplate);
}, [selectedComponent]);

const componentsWithoutTests = manifest.components.filter(
c => !manifest.tests.includes(c.replace('.jsx', '.test.jsx'))
);

return (
<div className="min-h-screen bg-gray-900 text-white font-sans p-8">
<h1 className="text-4xl md:text-5xl font-extrabold text-center mb-8">Developer Dashboard</h1>
<div className="flex justify-center border-b border-gray-700 mb-6">
<button onClick={() => setActiveTab('component_manager')} className={`py-3 px-6 text-lg font-medium ${activeTab === 'component_manager' ? 'border-b-4 border-blue-500 text-blue-400' : 'text-gray-500 hover:text-gray-300'}`}>Component Manager</button>
<button onClick={() => setActiveTab('test_generator')} className={`py-3 px-6 text-lg font-medium ${activeTab === 'test_generator' ? 'border-b-4 border-blue-500 text-blue-400' : 'text-gray-500 hover:text-gray-300'}`}>Test Generator</button>
</div>
<div className="w-full max-w-6xl mx-auto">
{activeTab === 'component_manager' && (
<div>
<h2 className="text-3xl font-bold mb-4">Component Manager</h2>
<div className="bg-gray-800 p-6 rounded-lg">
<h3 className="text-2xl font-semibold mb-4">Create New Component</h3>
<div className="flex items-center space-x-4 mb-4">
<input
type="text"
placeholder="Enter Component Name"
value={newComponentName}
onChange={(e) => setNewComponentName(e.target.value)}
className="bg-gray-700 text-white rounded-md px-4 py-2 w-full max-w-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button onClick={handleGenerateCode} className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-md">Generate Code</button>
</div>
{generatedCode && (
<div className="mt-6">
<h4 className="text-xl font-semibold mb-2">Generated Component Code</h4>
<p className="text-sm text-gray-400 mb-2">Copy this code and save it in a new file under `src/&lt;ComponentName&gt;.jsx`</p>
<textarea
readOnly
value={generatedCode}
className="w-full h-72 p-4 font-mono text-sm bg-gray-700 text-white rounded-md border border-gray-600"
/>
<h4 className="text-xl font-semibold mt-6 mb-2">Script Tag for index.html</h4>
<p className="text-sm text-gray-400 mb-2">To run this component, replace the existing component script tag in `index.html` with this one:</p>
<textarea
readOnly
value={scriptTag}
className="w-full p-4 font-mono text-sm bg-gray-700 text-white rounded-md border border-gray-600"
/>
</div>
)}
</div>
</div>
)}
{activeTab === 'test_generator' && (
<div>
<h2 className="text-3xl font-bold mb-4">Test Generator</h2>
<div className="bg-gray-800 p-6 rounded-lg">
<h3 className="text-2xl font-semibold mb-4">Generate Test for Component</h3>
<div className="flex items-center space-x-4 mb-4">
<select
value={selectedComponent}
onChange={(e) => setSelectedComponent(e.target.value)}
className="bg-gray-700 text-white rounded-md px-4 py-2 w-full max-w-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Select a component...</option>
{componentsWithoutTests.map(file => <option key={file} value={file}>{file}</option>)}
</select>
<button onClick={handleGenerateTestCode} className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-md">Generate Test Code</button>
</div>
{generatedTestCode && (
<div className="mt-6">
<h4 className="text-xl font-semibold mb-2">Generated Test Code</h4>
<p className="text-sm text-gray-400 mb-2">Copy this code and save it in a new file under `src/&lt;ComponentName&gt;.test.jsx`</p>
<textarea
readOnly
value={generatedTestCode}
className="w-full h-72 p-4 font-mono text-sm bg-gray-700 text-white rounded-md border border-gray-600"
/>
</div>
)}
</div>
</div>
)}
</div>
</div>
);
}

// --- Self-Rendering Logic ---
const container = document.getElementById('root');
if (container) {
const root = ReactDOM.createRoot(container);
root.render(React.createElement(DeveloperDashboard));
}
62 changes: 0 additions & 62 deletions README.md

This file was deleted.

24 changes: 12 additions & 12 deletions SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

This project consists of a collection of standalone React components designed to run in a specific, sandboxed "Canvas" environment. They are not part of a traditional Node.js/npm project. Instead of a build step, all dependencies, including React itself, are expected to be loaded at runtime, typically from a Content Delivery Network (CDN).

The components are highly specialized tools for environment introspection, security testing, and advanced agent-based interactions.
The main application is the `DeveloperDashboard.jsx`, which serves as a control panel for developing and managing other components. It includes a "Component Manager" for creating new components from boilerplate and a "Test Generator" for scaffolding test files.

The `JulesIntrospector.jsx` component is a comprehensive introspection tool that combines the functionality of several previous components.

## Core Requirements

Expand All @@ -24,28 +26,26 @@ The components rely on several external libraries being available in the global

**Component-Specific Dependencies:**

- **`GeminiAppJavascriptIntrospector.jsx`**:
- **`JulesIntrospector.jsx`**:
- `acorn`: `https://unpkg.com/acorn/dist/acorn.js`
- `estraverse`: `https://unpkg.com/estraverse/estraverse.js`

- **`GeminiCDNCanary.txt` / `GeminiAppProbeReactApp.txt`**: These components dynamically load various other libraries (e.g., Firebase, JSON5, Peggy.js) as part of their testing function. The host environment must allow script injection and cross-origin requests (or use a proxy like `api.allorigins.win`).

### 3. Configuration (Global Variables)

Several components expect global JavaScript variables to be defined in the `window` scope by the host environment. These are used for backend integration and authentication.

- **`__firebase_config`**: (String or Object) A Firebase configuration object.
- **`__app_id`**: (String) A unique identifier for the application instance.
- **`__initial_auth_token`**: (String) A JWT token for initial Firebase authentication.
- **`GEMINI_API_KEY`**: (String) An API key for the Google Gemini API. This is found as a placeholder in `GeminiAppCanvasAgent.txt` and `GeminiAppProbeReactApp.txt`.
- **`GEMINI_API_KEY`**: (String) An API key for the Google Gemini API.

### 4. Running the Application

### 4. Running a Component (Example)
The application is run by opening the `index.html` file in a web browser. A local web server is required to serve the files.

To run a component, you must:
The `DeveloperDashboard.jsx` component is loaded by default. It dynamically populates its UI by fetching a `manifest.json` file, which lists all available `.jsx` components in the `src/` directory.

1. Rename the component file from `.txt` or `.jsx` to a consistent `.jsx` extension.
2. In the host HTML file, add a `<script type="text/babel">` tag that:
- Imports the component.
- Uses `ReactDOM.createRoot()` and `root.render()` to mount the component into the designated root element.
To update the manifest, run the following command:
`node tools/create_manifest.js`

This setup provides the necessary framework to run and test each of the provided standalone tools.
This setup provides the necessary framework to run and test the provided standalone tools.
Loading