self modifying website
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <title>C:\PLASTIC.EXE - Self-Modifying System</title>
7 <style>
8 @import url("https://fonts.googleapis.com/css2?family=Courier+Prime:wght@400;700&display=swap");
9
10 body {
11 background: #f0f0f0;
12 font-family: "Courier Prime", "Courier New", monospace;
13 color: #000000;
14 margin: 0;
15 padding: 20px;
16 line-height: 1.2;
17 font-size: 14px;
18 }
19
20 .terminal {
21 background: #ffffff;
22 border: 2px solid #808080;
23 box-shadow:
24 inset -2px -2px #c0c0c0,
25 inset 2px 2px #404040;
26 max-width: 800px;
27 margin: 0 auto;
28 padding: 0;
29 }
30
31 .title-bar {
32 background: #c0c0c0;
33 color: #000000;
34 padding: 4px 8px;
35 font-weight: bold;
36 border-bottom: 1px solid #808080;
37 font-size: 12px;
38 }
39
40 .content {
41 padding: 10px;
42 background: #ffffff;
43 }
44
45 .prompt {
46 color: #000000;
47 margin: 0;
48 }
49
50 .cursor {
51 background: #000000;
52 color: #ffffff;
53 animation: blink 1s infinite;
54 }
55
56 @keyframes blink {
57 0%,
58 50% {
59 opacity: 1;
60 }
61 51%,
62 100% {
63 opacity: 0;
64 }
65 }
66
67 h1 {
68 color: #000000;
69 font-size: 24px;
70 margin: 10px 0;
71 text-transform: uppercase;
72 }
73
74 h2 {
75 color: #000000;
76 font-size: 16px;
77 margin: 15px 0 5px 0;
78 text-transform: uppercase;
79 }
80
81 .command {
82 color: #ffffff;
83 background: #808080;
84 padding: 2px 4px;
85 display: inline-block;
86 margin: 2px;
87 }
88
89 .button {
90 background: #c0c0c0;
91 color: #000000;
92 border: 2px outset #c0c0c0;
93 padding: 4px 8px;
94 font-family: inherit;
95 font-size: 12px;
96 cursor: pointer;
97 margin: 5px 2px;
98 display: inline-block;
99 text-decoration: none;
100 text-transform: uppercase;
101 }
102
103 .button:active {
104 border: 2px inset #c0c0c0;
105 }
106
107 .button:hover {
108 background: #d0d0d0;
109 }
110
111 .editor {
112 width: calc(100% - 20px);
113 height: 150px;
114 background: #0000ff;
115 color: #ffffff;
116 font-family: inherit;
117 margin: 10px 0;
118 padding: 10px;
119 border: 2px inset #c0c0c0;
120 font-size: 12px;
121 resize: none;
122 }
123
124 .status-bar {
125 background: #c0c0c0;
126 color: #000000;
127 padding: 2px 8px;
128 border-top: 1px solid #808080;
129 font-size: 11px;
130 display: flex;
131 justify-content: space-between;
132 }
133
134 .file-listing {
135 margin: 10px 0;
136 }
137
138 .file-line {
139 margin: 2px 0;
140 font-family: inherit;
141 }
142
143 .dir {
144 color: #000080;
145 }
146
147 .exe {
148 color: #000000;
149 }
150
151 .txt {
152 color: #000000;
153 }
154
155 .error {
156 color: #ffffff;
157 background: #ff0000;
158 padding: 2px 4px;
159 }
160
161 ul {
162 margin: 5px 0;
163 padding-left: 20px;
164 }
165
166 li {
167 margin: 2px 0;
168 }
169
170 .separator {
171 color: #808080;
172 margin: 10px 0;
173 }
174
175 .ascii-art {
176 color: #000000;
177 font-size: 10px;
178 line-height: 1;
179 white-space: pre;
180 margin: 10px 0;
181 }
182 </style>
183 </head>
184 <body>
185 <div class="terminal">
186 <div class="title-bar">
187 C:\PLASTIC.EXE - [Self-Modifying System v2.1]
188 </div>
189
190 <div class="content">
191 <p class="prompt">C:\PLASTIC> DIR</p>
192
193 <div class="file-listing">
194 <div class="file-line">
195 Volume in drive C is PLASTIC-SYS
196 </div>
197 <div class="file-line">Directory of C:\PLASTIC</div>
198 <div class="file-line"></div>
199 <div class="file-line">
200 <span class="dir">SYSTEM <DIR></span> 12-15-95
201 3:42p
202 </div>
203 <div class="file-line">
204 <span class="exe">PLASTIC EXE</span> 24,576 12-15-95
205 3:42p
206 </div>
207 <div class="file-line">
208 <span class="txt">README TXT</span> 1,024 12-15-95 3:42p
209 </div>
210 <div class="file-line">
211 <span class="txt">CONFIG SYS</span> 512 12-15-95 3:42p
212 </div>
213 <div class="file-line">4 File(s) 26,112 bytes</div>
214 <div class="file-line">524,288 bytes free</div>
215 </div>
216
217 <p class="prompt">C:\PLASTIC> PLASTIC.EXE</p>
218
219 <pre class="ascii-art">
220██████╗ ██╗ █████╗ ███████╗████████╗██╗ ██████╗
221██╔══██╗██║ ██╔══██╗██╔════╝╚══██╔══╝██║██╔════╝
222██████╔╝██║ ███████║███████╗ ██║ ██║██║
223██╔═══╝ ██║ ██╔══██║╚════██║ ██║ ██║██║
224██║ ███████╗██║ ██║███████║ ██║ ██║╚██████╗
225╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝</pre
226 >
227
228 <h2>System Information:</h2>
229 <p>PLASTIC v2.1 - Self-Modifying Code System</p>
230 <p>Copyright (C) 1995 DUNKIRK Corp.</p>
231 <p>
232 All rights reserved. Licensed to: REGISTERED USER under MIT
233 </p>
234
235 <div class="separator">
236 ════════════════════════════════════════════════════════════
237 </div>
238
239 <h2>About This System:</h2>
240 <p>
241 PLASTIC.EXE is an experimental self-modifying executable
242 that allows real-time code injection and system
243 modification. WARNING: Use at your own risk. System may
244 become unstable.
245 </p>
246
247 <h2>Experimental Code Generator:</h2>
248 <p>Describe changes to make to the page:</p>
249 <textarea
250 class="editor"
251 id="codeEditor"
252 placeholder="e.g., 'Add a retro calculator widget', 'Change theme to green terminal', or 'Completely redesign as a DOS file manager'"
253 ></textarea>
254 <div class="button" onclick="generateAndExecute()">
255 GENERATE & EXECUTE
256 </div>
257 <div class="button" onclick="clearEditor()">CLEAR</div>
258 <div
259 id="statusDisplay"
260 style="color: #000080; margin-top: 10px"
261 ></div>
262
263 <h2>System Features:</h2>
264 <ul>
265 <li>
266 Real-time <span class="command">EXEC</span> code
267 modification
268 </li>
269 <li>Compatible with DOS 6.22 and Windows 95</li>
270 <li>640K memory optimized</li>
271 <li>No TSR conflicts detected</li>
272 <li>Supports EGA/VGA graphics modes</li>
273 </ul>
274
275 <h2>System Commands:</h2>
276 <p>
277 <span class="command">HELP</span>
278 <span class="command">DIR</span>
279 <span class="command">EDIT</span>
280 <span class="command">RUN</span>
281 <span class="command">EXIT</span>
282 </p>
283
284 <div class="separator">
285 ════════════════════════════════════════════════════════════
286 </div>
287
288 <p>Runtime: 00:13:37 | Memory: 589K free | CPU: 80486DX-33</p>
289 <p class="error">
290 WARNING: Unauthorized modification may corrupt system files
291 </p>
292
293 <p class="prompt">C:\PLASTIC> <span class="cursor">_</span></p>
294 </div>
295
296 <div class="status-bar">
297 <span>F1=Help F2=Save F3=Load F10=Menu</span>
298 <span>12:34 PM</span>
299 </div>
300 </div>
301
302 <script>
303 // Tool call system for AI to interact with the page
304 window.toolCallbacks = {
305 replaceElement: function(selector, newHTML) {
306 const element = document.querySelector(selector);
307 if (element) {
308 element.outerHTML = newHTML;
309 return { success: true, message: `Replaced element: ${selector}` };
310 }
311 return { success: false, message: `Element not found: ${selector}` };
312 },
313
314 updateElement: function(selector, newContent) {
315 const element = document.querySelector(selector);
316 if (element) {
317 element.innerHTML = newContent;
318 return { success: true, message: `Updated element: ${selector}` };
319 }
320 return { success: false, message: `Element not found: ${selector}` };
321 },
322
323 addElement: function(parentSelector, newHTML, position = 'beforeend') {
324 const parent = document.querySelector(parentSelector);
325 if (parent) {
326 parent.insertAdjacentHTML(position, newHTML);
327 return { success: true, message: `Added element to: ${parentSelector}` };
328 }
329 return { success: false, message: `Parent not found: ${parentSelector}` };
330 },
331
332 removeElement: function(selector) {
333 const element = document.querySelector(selector);
334 if (element) {
335 element.remove();
336 return { success: true, message: `Removed element: ${selector}` };
337 }
338 return { success: false, message: `Element not found: ${selector}` };
339 },
340
341 updateStyle: function(selector, styleObj) {
342 const element = document.querySelector(selector);
343 if (element) {
344 Object.assign(element.style, styleObj);
345 return { success: true, message: `Updated styles for: ${selector}` };
346 }
347 return { success: false, message: `Element not found: ${selector}` };
348 },
349
350 executeJS: function(code) {
351 try {
352 const result = eval(code);
353 return { success: true, message: 'JavaScript executed', result: result };
354 } catch (error) {
355 return { success: false, message: `JS Error: ${error.message}` };
356 }
357 }
358 };
359
360 function executeToolCall(toolCall) {
361 const { function: func, arguments: args } = toolCall;
362 console.log('Executing tool call:', func, args);
363
364 if (window.toolCallbacks[func]) {
365 try {
366 // Handle different function signatures
367 if (func === 'removeElement') {
368 // removeElement expects just a selector
369 const selector = args.selector || Object.keys(args)[0] || Object.values(args)[0];
370 return window.toolCallbacks[func](selector);
371 } else if (func === 'updateStyle' && args.styleObj) {
372 return window.toolCallbacks[func](args.selector, args.styleObj);
373 } else if (func === 'executeJS') {
374 return window.toolCallbacks[func](args.code);
375 } else if (func === 'updateElement') {
376 return window.toolCallbacks[func](args.selector, args.newContent);
377 } else if (func === 'replaceElement') {
378 return window.toolCallbacks[func](args.selector, args.newHTML);
379 } else if (func === 'addElement') {
380 return window.toolCallbacks[func](args.parentSelector, args.newHTML, args.position);
381 } else {
382 // Fallback: use all argument values in order
383 return window.toolCallbacks[func](...Object.values(args));
384 }
385 } catch (error) {
386 return { success: false, message: `Error executing ${func}: ${error.message}` };
387 }
388 }
389 return { success: false, message: `Unknown tool: ${func}` };
390 }
391
392 async function generateAndExecute() {
393 const userPrompt = document.getElementById("codeEditor").value;
394 const statusDiv = document.getElementById("statusDisplay");
395
396 if (userPrompt.trim() === "") {
397 statusDiv.textContent = "ERROR: No description provided";
398 return;
399 }
400
401 statusDiv.textContent = "CONNECTING TO AI SYSTEM...";
402
403 try {
404 const currentPageHTML = document.documentElement.outerHTML;
405
406 const response = await fetch(
407 "https://ai.hackclub.com/chat/completions",
408 {
409 method: "POST",
410 headers: {
411 "Content-Type": "application/json",
412 },
413 body: JSON.stringify({
414 messages: [
415 {
416 role: "user",
417 content: `Here is the current HTML page:\n\n${currentPageHTML}\n\nUser request: "${userPrompt}"\n\nIMPORTANT: You must respond with ONLY one of these two formats:\n\nFORMAT 1 - Tool calls (for precise modifications):\n{"tool_calls": [{"function": "functionName", "arguments": {"param": "value"}}]}\n\nFORMAT 2 - Raw HTML (to append to page):\n<div>Your HTML content here</div>\n\nDO NOT include any explanatory text, markdown formatting, or additional commentary. Respond with ONLY the JSON or HTML.\n\nAvailable tools with correct argument formats:\n1. removeElement: {"function": "removeElement", "arguments": {"selector": ".class-name"}}\n2. updateElement: {"function": "updateElement", "arguments": {"selector": ".class-name", "newContent": "new content"}}\n3. replaceElement: {"function": "replaceElement", "arguments": {"selector": ".class-name", "newHTML": "<div>new html</div>"}}\n4. addElement: {"function": "addElement", "arguments": {"parentSelector": ".parent", "newHTML": "<div>content</div>", "position": "beforeend"}}\n5. updateStyle: {"function": "updateStyle", "arguments": {"selector": ".class-name", "styleObj": {"color": "#000000"}}}\n6. executeJS: {"function": "executeJS", "arguments": {"code": "console.log('hello');"}}\n\nUse DOS/retro aesthetic with flat colors: #000000 (black), #ffffff (white), #c0c0c0 (gray), #000080 (blue), #ff0000 (red). Use monospace fonts.`,
418 },
419 ],
420 }),
421 },
422 );
423
424 if (!response.ok) {
425 throw new Error(
426 `HTTP ${response.status}: ${response.statusText}`,
427 );
428 }
429
430 statusDiv.textContent = "AI PROCESSING...";
431
432 const data = await response.json();
433 console.log("API Response:", data);
434
435 let generatedContent;
436 if (
437 data.choices &&
438 data.choices[0] &&
439 data.choices[0].message
440 ) {
441 generatedContent = data.choices[0].message.content;
442 } else if (data.content) {
443 generatedContent = data.content;
444 } else if (data.response) {
445 generatedContent = data.response;
446 } else if (typeof data === "string") {
447 generatedContent = data;
448 } else {
449 throw new Error("Unexpected API response format");
450 }
451
452 statusDiv.textContent = "EXECUTING COMMANDS...";
453
454 // Clean up response and extract JSON if present
455 let cleanResponse = generatedContent.trim();
456
457 // Remove markdown formatting
458 cleanResponse = cleanResponse
459 .replace(/```json\n?/g, "")
460 .replace(/```\n?/g, "");
461
462 // Try to extract JSON from mixed content
463 const jsonMatch = cleanResponse.match(/\{[\s\S]*"tool_calls"[\s\S]*\}/);
464 if (jsonMatch) {
465 cleanResponse = jsonMatch[0];
466 }
467
468 console.log('Cleaned response:', cleanResponse);
469
470 // Check if response contains tool calls
471 try {
472 const toolResponse = JSON.parse(cleanResponse);
473 if (toolResponse.tool_calls && Array.isArray(toolResponse.tool_calls)) {
474 // Execute tool calls
475 const results = [];
476 for (const toolCall of toolResponse.tool_calls) {
477 const result = executeToolCall(toolCall);
478 results.push(result);
479 console.log('Tool call result:', result);
480 }
481 statusDiv.textContent = `EXECUTED ${results.length} COMMANDS`;
482
483 // Send feedback to AI about tool results
484 setTimeout(() => sendToolFeedback(userPrompt, results), 100);
485 } else {
486 throw new Error("Invalid tool call format");
487 }
488 } catch (jsonError) {
489 console.log('JSON parse error:', jsonError);
490 console.log('Raw response:', generatedContent);
491 console.log('Attempting to parse as HTML...');
492
493 // Not JSON, treat as HTML code
494 let cleanCode = generatedContent
495 .replace(/```html\n?/g, "")
496 .replace(/```\n?/g, "");
497
498 statusDiv.textContent = "INJECTING CODE...";
499 document.querySelector(".content").innerHTML += cleanCode;
500 statusDiv.textContent = "CODE EXECUTION SUCCESSFUL";
501 }
502
503 document.getElementById("codeEditor").value = "";
504
505 // Clear status after 3 seconds
506 setTimeout(() => {
507 statusDiv.textContent = "";
508 }, 3000);
509 } catch (error) {
510 statusDiv.textContent = `SYSTEM ERROR: ${error.message}`;
511 console.error("Error:", error);
512 }
513 }
514
515 function clearEditor() {
516 document.getElementById("codeEditor").value = "";
517 document.getElementById("statusDisplay").textContent = "";
518 }
519
520 async function sendToolFeedback(originalPrompt, toolResults) {
521 const statusDiv = document.getElementById("statusDisplay");
522
523 try {
524 statusDiv.textContent = "SENDING FEEDBACK TO AI...";
525
526 const currentPageHTML = document.documentElement.outerHTML;
527 const resultsText = toolResults.map(r =>
528 `${r.success ? '✓' : '✗'} ${r.message}${r.result ? ` (result: ${r.result})` : ''}`
529 ).join('\n');
530
531 const response = await fetch(
532 "https://ai.hackclub.com/chat/completions",
533 {
534 method: "POST",
535 headers: {
536 "Content-Type": "application/json",
537 },
538 body: JSON.stringify({
539 messages: [
540 {
541 role: "user",
542 content: `Previous request: "${originalPrompt}"\n\nTool execution results:\n${resultsText}\n\nCurrent page state:\n${currentPageHTML}\n\nBased on the tool results, do you need to make any follow-up modifications? If everything looks good, respond with "COMPLETE". If you need to make adjustments, respond with tool calls or HTML.\n\nIMPORTANT: Respond with ONLY one of these formats:\n- "COMPLETE" (if satisfied)\n- {"tool_calls": [...]} (for modifications)\n- Raw HTML (to append content)\n\nDO NOT include explanatory text.`,
543 },
544 ],
545 }),
546 },
547 );
548
549 if (!response.ok) {
550 throw new Error(`HTTP ${response.status}: ${response.statusText}`);
551 }
552
553 const data = await response.json();
554 let followUpContent;
555
556 if (data.choices && data.choices[0] && data.choices[0].message) {
557 followUpContent = data.choices[0].message.content;
558 } else if (data.content) {
559 followUpContent = data.content;
560 } else if (data.response) {
561 followUpContent = data.response;
562 } else {
563 throw new Error("Unexpected API response format");
564 }
565
566 followUpContent = followUpContent.trim();
567 console.log('Follow-up response:', followUpContent);
568
569 if (followUpContent === "COMPLETE") {
570 statusDiv.textContent = "AI SATISFIED - TASK COMPLETE";
571 setTimeout(() => statusDiv.textContent = "", 3000);
572 return;
573 }
574
575 // Process follow-up commands
576 statusDiv.textContent = "AI MAKING ADJUSTMENTS...";
577
578 // Try to parse as tool calls
579 try {
580 const jsonMatch = followUpContent.match(/\{[\s\S]*"tool_calls"[\s\S]*\}/);
581 if (jsonMatch) {
582 const toolResponse = JSON.parse(jsonMatch[0]);
583 if (toolResponse.tool_calls && Array.isArray(toolResponse.tool_calls)) {
584 const followUpResults = [];
585 for (const toolCall of toolResponse.tool_calls) {
586 const result = executeToolCall(toolCall);
587 followUpResults.push(result);
588 console.log('Follow-up tool result:', result);
589 }
590 statusDiv.textContent = `AI EXECUTED ${followUpResults.length} ADJUSTMENTS`;
591 }
592 } else {
593 // Treat as HTML
594 let cleanCode = followUpContent
595 .replace(/```html\n?/g, "")
596 .replace(/```\n?/g, "");
597 document.querySelector(".content").innerHTML += cleanCode;
598 statusDiv.textContent = "AI ADDED FOLLOW-UP CONTENT";
599 }
600 } catch (error) {
601 console.log('Follow-up parsing error:', error);
602 statusDiv.textContent = "AI FEEDBACK ERROR";
603 }
604
605 setTimeout(() => statusDiv.textContent = "", 4000);
606
607 } catch (error) {
608 statusDiv.textContent = `FEEDBACK ERROR: ${error.message}`;
609 console.error('Feedback error:', error);
610 setTimeout(() => statusDiv.textContent = "", 3000);
611 }
612 }
613
614 // Handle Ctrl+Enter in textarea
615 document.addEventListener("DOMContentLoaded", function () {
616 document
617 .getElementById("codeEditor")
618 .addEventListener("keydown", function (e) {
619 if (e.ctrlKey && e.key === "Enter") {
620 e.preventDefault();
621 generateAndExecute();
622 }
623 });
624 });
625
626 // Update time in status bar
627 setInterval(() => {
628 const now = new Date();
629 const timeStr = now.toLocaleTimeString([], {
630 hour: "2-digit",
631 minute: "2-digit",
632 });
633 const statusBarTime = document.querySelector(
634 ".status-bar span:last-child",
635 );
636 if (statusBarTime) {
637 statusBarTime.textContent = timeStr;
638 }
639 }, 1000);
640 </script>
641 </body>
642</html>