News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_zhulien

Julian's Long List of Ideas Thread

Started by zhulien, 17:54, 12 February 25

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

zhulien

The line numbers are only in the line editor so you can edit and insert etc.  A fullscreen editor would remove the line numbers and put them back after exiting the fullscreen editor. Since I'm beautifying the JS code automatically it is a tiny more involved than just stripping the numbers - I'd probably beautify it with tabs for fullscreen, not spaces like the line editor.

There are two reasons it's JS and not something else - JS came almost for free without much development and AI LLMs seem to be good at JS, and unfortunately not as good at some others especially they are bad at assembly language.

It seems AI agents are a bit dumb when you tell them to it's "a line editor" only, I found i had to tell manus.im and another "it's a line editor just like 80s BASIC but using JavaScript instead" and it got it.  All this i will put in a programming prompt text file at some stage along with more detailed instructions in a single file - it takes manus some time to go through all the separate pages.  When it realises it's a line editor though it usually zips through.

bits of the JS framework are here: https://8bitology.net/poc/

zhulien

#51
I was doing some more coding the other day with Primal (my kernel) and had an interesting problem - that was, with my current memory routines how to deal with 4mb+ RAM to access all 256 16kb blocks plus internal memory with a single byte.  I came up with a solution,  I now have 3 heaps - An application heap, a system heap and a buffers heap.  keeping the API currently almost as it was, I added a Heap selector which lets me change heaps then use the other APIs like bankselect etc... for 4mb+ systems, I gave 3mb+ to applications, and 512kb to system and buffers each.  For 2mb+ systems, half that, until down to 128kb systems (that's 64kb extra ram - so 128kb total), they only have the 3 heaps are merged.  This sharing of heaps as a fallback works extremely well on paper at least - meaning if there is an abundance of RAM, the system can guarantee it's own RAM and RAM for buffers, but if there is not much RAM, they fall back to a single heap where it's more a typical CPC program (shared space for program, jumpblock, buffers).  The loader now defaults to working with unexpanded 464 or 664 and gives about 35kb available shared after the kernel is loaded no longer requiring an expanded memory driver.  I'm not yet overwriting the firmware jumpblock - but in time I will to use all RAM up to #C000.  But I also created a virtual memory variant for unexpanded machines which gives 1 x 64kb+ heap and 2 x 64kbMemory heaps - which will work fine on M4 or other Mass Storage - obviously not useable for Tapes or Floppy Discs.  This Virtual Memory isn't best for expanded machines but of course will work... a more intelligent virtual memory version would be best, that is to use a LIFO model for swapping files into physical expansion RAM - maybe in future I will code this.

Actually I could create a 4th pseudo-heap which is like a reserved, do not use heap - so that if someone was e.g. using an AMSDOS RAM expansion, we can not corrupt it, but

Next. to recode my Malloc (SysHeapAlloc) and Free (SysHeapFree) to use a better system than the slow iterate through banks, then iterate through lists - it takes quite a bit of time (fractions of a second though) to find a free block after e.g. 500 filled blocks.

I'm going to reinvestigate my RAT (RAM Allocation Table idea) - I think that is likely best, it's definitely the fastest, but it does have byte-aligned blocks which are the minimum memory allocation size even if you want smaller.

It isn't runnable yet, some code can be stepped through.

Latest Coding Status here:
https://docs.google.com/spreadsheets/d/14JQa3cTEd9fIz9lyoQRkzVc5xBz5FhEdr_DC41xPkJs/edit?usp=sharing

zhulien

#52
For all you adventuring "Text Adventure" (that's Interactive Fiction for all you newbies) fanatics, I have released Potent JS Adventure Creation Framework which lets you create some pretty cool Text Adventure games in JavaScript.  It is available for download at the Cyborg Unicorn website or if you follow the links from https://potentjs.com where you can also play a sample game created with it. You can create text adventure games with multiple playable characters. Think a RPG adventure game where you can be every member of the party which interesting puzzles they each can contibute to solve.

Now on github:

https://github.com/PrimalNinja/cyborgwiki
https://github.com/PrimalNinja/potentjsacf

zhulien

It's cool what a tiny bit of JS can do...

Initialising.

Ready.

In the shadow-shrouded realm of Delos, where the moon dipped into darkness and the wind whispered secrets to the trees, Xusia, the evil sorcerer, wove a web of deceit and malice. With a cackle that sent shivers through the land, he snatched Alana, the radiant starlight maiden, destined to be Talon's bride in mere days.

You are Alana.

I lie captive in the darkness of Xusia's lair, the cold stone beneath me a harsh reminder of my fate. You took me, Xusia, but why? What purpose do I serve in your twisted games? The hours tick by, each one a slow crawl of uncertainty. My thoughts are consumed by Talon, the one I'm to marry in just a few short days. Will he come for me? Does he even know I'm trapped here? I scan my prison, searching for any weakness, any chance to escape. The iron bars, the locked door, the guards patrolling outside... but I won't give up. I have to hold on to hope, to the thought of Talon's strong arms and his gentle touch. Maybe, just maybe, he'll find a way to rescue me before our wedding day. Until then, I'll plot, I'll plan, and I'll wait... for Talon, or for my chance to break free.

You are in a room with a red door to the south.

You can see: Xusia

> look

You are in a room with a red door to the south.

You can see: Xusia

> look xusia

Xusia is very scary.

> look door

The door is red.

It is closed.

> i

You are carrying:

├─ back pack
└─ dagger
> take dagger

You have the dagger already.

> look backpack

The back pack is a typical nylon type used by most school students.

It is closed.

> open backpack

You open the back pack.

> look backpack

The back pack is a typical nylon type used by most school students.

It is open.

It contains:

- rock

> get rock

You get the rock.

> i

You are carrying:

├─ back pack
├─ dagger
└─ rock
> look

You are in a room with a red door to the south.

You can see: Xusia

> talon

You are now Talon.

You burst through the door, expecting to be greeted by Alana's warm smile, but instead, you're met with an eerie silence. You call out, 'Honey, I'm home!' but there's no response. That's when you see Alana's little brother, his face frantic with worry, running towards you. 'Help! Help! Alana's been kidnapped by Xusia!' he cries, tugging at your leg.

Without hesitation, you grip your trusty Tri-Sword, its familiar weight a comfort in the face of danger. Our wedding is just a few days away, and you won't let Xusia ruin it. You set off towards Xusia's lair, determination burning within you. As you enter the dark, foreboding caverns, you feel a sudden, searing pain in the back of your neck. Everything goes dark, and you crumple to the ground.

When you come to, your head throbs, and your vision blurs. You're disoriented, but as your senses return, you realize you're in Xusia's lair, and... where's Alana? You struggle against your restraints, a growing sense of urgency and fear driving you. What has Xusia done to her? You need to find out, and fast. You glance around, taking stock of your surroundings, searching for any opportunity to escape and rescue your beloved Alana before it's too late.

You are in a room with a red door to the north.

You can see: black box, sword

> get swword

I don't see that here.

> get sword

You get the sword.

> get box

You get the black box.

> i

You are carrying:

├─ sword
└─ black box
> look box

The box is made of wood and painted black, it feels quite strong.

It is closed.

> open box

You open the black box.

> look box

The box is made of wood and painted black, it feels quite strong.

It is open.

It contains:

- red key

> get key

You get the red key.

> look box

The box is made of wood and painted black, it feels quite strong.

It is open.

It is empty.

> i

You are carrying:

├─ sword
├─ black box
└─ red key
> open door

The door is locked.

> unlock door

You unlock the door.

> open door

You open the door.

> go door

You enter the red door.

You are in a room with a red door to the south.

You can see: Alana, Xusia

> look alana

Such a beautiful lass.

> look xusia

Xusia is very scary.

> kiss alana

You put your hands on Alana's hips and give her a long intimate kiss.

> kiss xusia

Yuk! That's gross.

> alana

You are now Alana.

You are in a room with a red door to the south.

You can see: Xusia, Talon

> i

You are carrying:

├─ back pack
├─ dagger
└─ rock
> put dagger into bag

I don't see that here.

> put rock in bag

I don't see that here.

> i

You are carrying:

├─ back pack
├─ dagger
└─ rock
> put dagger into backpack

You put the dagger into the back pack.

> put rock into backpack

You put the rock into the back pack.

> i

You are carrying:

└─ back pack
   ├─ dagger
   └─ rock
> look back pack

The back pack is a typical nylon type used by most school students.

It is open.

It contains:

- dagger

- rock

> close back pack

You close the back pack.

> i

You are carrying:

└─ back pack
> give back pack to talon

You give the back pack to Talon.

> talon

You are now Talon.

You are in a room with a red door to the south.

You can see: Alana, Xusia

> i

You are carrying:

├─ sword
├─ black box
├─ red key
└─ back pack
> open box

The black box is already open.

> i

You are carrying:

├─ sword
├─ black box
├─ red key
└─ back pack
> open back pack

You open the back pack.

> o

I don't see that here.

> i

You are carrying:

├─ sword
├─ black box
├─ red key
└─ back pack
   ├─ dagger
   └─ rock
> look xusia

Xusia is very scary.

> kill xusia

After a long and hard-fought battle, you kill Xusia with the Tri-Sword.

I hold Alana's hand tight, feeling her warmth and love radiating towards me. The memory of Xusia's defeat still fresh in my mind, I'm grateful to have saved the woman I love. As we walk towards our future, I glance at Alana, her beauty and strength captivating me.

With Xusia's darkness vanquished, our path is clear. Our wedding awaits, and I'm eager to start our life together. Alana's smile lights up the world, and I'm honored to be her partner, her protector, and her love.

I look into her eyes, and she sees the sincerity in mine. 'I'll always protect you, Alana,' I promise, my voice filled with conviction. 'Together, we'll face whatever comes next, side by side.'

With Alana by my side, I know we'll conquer any challenge. Our love will flourish, and our bond will grow stronger with each passing day. As we step into our new life, I'm excited to see what the future holds for us, together.

> look xusia

Xusia is dead.

The following catches your attention:

- gold pouch

> get pouch

I don't see that here.

> get pouch from xusia

You take the gold pouch from the Xusia.

> i

You are carrying:

├─ sword
├─ black box
├─ red key
├─ back pack
│  ├─ dagger
│  └─ rock
└─ gold pouch
   └─ gold pieces
> put pouch into box

You put the gold pouch into the black box.

> i

You are carrying:

├─ sword
├─ black box
│  └─ gold pouch
│     └─ gold pieces
├─ red key
└─ back pack
   ├─ dagger
   └─ rock
> put box into back pack

You put the black box into the back pack.

> i

You are carrying:

├─ sword
├─ red key
└─ back pack
   ├─ dagger
   ├─ rock
   └─ black box
      └─ gold pouch
         └─ gold pieces
> close back pack

You close the back pack.

> i

You are carrying:

├─ sword
├─ red key
└─ back pack
> get gold

You get the gold pieces.

> i

You are carrying:

├─ sword
├─ red key
├─ back pack
└─ gold pieces
> look gold

Oooh, nice and shiny. Now you can afford a fantastic honeymoon!

> kiss alana

You put your hands on Alana's hips and give her a long intimate kiss.

> alana

You are now Alana.

You are in a room with a red door to the south.

You can see: Xusia, Talon

> kiss talon

You put your arms around Talon and give him a long intimate kiss.

> i

You are not carrying anything.

> alana

You are now Alana.

You are in a room with a red door to the south.

You can see: Xusia, Talon

> i

You are not carrying anything.

> take alana

You can't take the Alana.

> i

You are not carrying anything.

> talon

You are now Talon.

You are in a room with a red door to the south.

You can see: Alana, Xusia

> i

You are carrying:

├─ sword
├─ red key
├─ back pack
└─ gold pieces
> l

You are in a room with a red door to the south.

You can see: Alana, Xusia

> take xusia

You can't take the Xusia.

> i

You are carrying:

├─ sword
├─ red key
├─ back pack
└─ gold pieces
> open back pack

You open the back pack.

> i

You are carrying:

├─ sword
├─ red key
├─ back pack
│  ├─ dagger
│  ├─ rock
│  └─ black box
│     └─ gold pouch
└─ gold pieces
> put the key into the backpack

You put the red key into the back pack.

> i

You are carrying:

├─ sword
├─ back pack
│  ├─ dagger
│  ├─ rock
│  ├─ black box
│  │  └─ gold pouch
│  └─ red key
└─ gold pieces
> put the key into the black box

You're not carrying that.

> get the key

You get the red key.

> put the key into the black box

You put the red key into the black box.

> i

You are carrying:

├─ sword
├─ back pack
│  ├─ dagger
│  ├─ rock
│  └─ black box
│     ├─ gold pouch
│     └─ red key
└─ gold pieces

ervin

Tri-sword?
Xusia?

Sounds like the Sword and the Sorcerer.
GREAT movie!  :)

zhulien

Quote from: ervin on 08:52, 08 July 25Tri-sword?
Xusia?

Sounds like the Sword and the Sorcerer.
GREAT movie!  :)
It's The Sorcerer and the Sword  :D

zhulien

I have started coding CyborgDesktop which you can try my first days work at

https://cyborgshell.com/

just type run desktop.js

Imagine, just like the shell where you can login on your xbox, your phone, you PC, your Mac and seamlessly walk around and use them all and develop or type in your latest novel where-ever you happen to be - for those that don't like CLIs can use a desktop.  

Soon will be applications that you can code in there, for now, the only working bit is the Terminal which shows the shell in the desktop in a window.  But... lots of cool features to come.

zhulien

For those who like OSs, my Cyborg Desktop is now progressing.  Why another desktop - ok another not immediately CPC-related thing... 

cyborgdesktop.com  (yes, it takes you to another instance of CyborgShell.  type "run desktop.js"

This is a tabletop operating system.  it is very colourful as i get the gist of it working.  You press the people button and you can arrange people around the table, that allows for different screen regions to be setup - as the root, you can be at the side or the end, doesn't matter, but it affects how the regions are initialised.  You can change the orientation of anyone.  For now, only the shell is there, you can open it from any user, and it will open in their orientation.  You can drag it to any other user, and it will change to their orientation.

The purpose?  Multiple, but when I make the regions transparent and some applications instead of terminal, then you can perhaps have a tabletop D&D game on your 70 inch touchscreen TV with a nice seamless OS to interact with.

Other than in the movies, i couldn't find any solution to this yet.  Now imagine i allow multiple players to play The Sorcerer and the Sword... that might be one of the first games on it.  At least as a POC.

Applications for such an OS?  Multi-user live or non-live music creation / editing tool?  Sit around the desk at school and teach kids how to program?  Tabletop games? etc.

mv

When I start https://cyborgshell.com/ and type run desktop.js, a "splash screen" appears and disappears and it shows "Sorry! Something went wrong.". And there is an error in the console:  "Google Maps JavaScript API error: RefererNotAllowedMapError".

A map with the city of Melbourne is shown for https://cyborgdesktop.com/ .

Ah, maybe I should try the "Users" button at the botton...

zhulien

Quote from: mv on 23:53, 22 July 25When I start https://cyborgshell.com/ and type run desktop.js, a "splash screen" appears and disappears and it shows "Sorry! Something went wrong.". And there is an error in the console:  "Google Maps JavaScript API error: RefererNotAllowedMapError".

A map with the city of Melbourne is shown for https://cyborgdesktop.com/ .

Ah, maybe I should try the "Users" button at the botton...
yes, cyborgshell.com domain is not configured to have google maps, cyborgdesktop.com is

i just removed the desktop for now from cyborgshell and updated it on cyborgdesktop to handle multitouch better. you can add multiple users, then each user can freely drag their windows around at the same time as each other.

the purpose isn't really to be a google map, but imagine moreso a tiled dungeon, where anyone can drag their things around freely.  imagine the windows aren't so big but, are like a transparent base on a graphical character which you can drag.  Of course there are real google maps use cases, but tabletop gaming might be more fun.  to allow people to type at the same time, i need to code my own onscreen keyboard - for some strange reasons, most browsers - even the ones that do support multitouch - all the latest ones do... do not let you type on multiple keyboards at once. if i can imagine a game with almost no typing, and i suspect that some nice game design is best without typing, all will be good without an onscreen keyboard.

zhulien


zhulien

i will likely deploy this over the next day... you best to NOT put your API key in there, but!!! if you are running a local ai, you can of course adapt the plugins to run locally.  this is an example of cascading AI interaction with transformers.

Quoteproject load aitest
File loaded: aitest_prompt.txt
File loaded: aitest_story.txt
File loaded: aitest_chinese.txt
File loaded: aitest_japanese.txt
File loaded: chatgpt.xfrm
File loaded: tochinese.xfrm
File loaded: tojapanese.xfrm
Project loaded: aitest
Ready
files
Project name: aitest
Project filename: aitest.prj
Files:
  1 *  aitest_prompt.txt 129 bytes/3 lines (text/javascript:text)
  2    aitest_story.txt 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm
  3    aitest_chinese.txt 12 bytes/1 lines (text/javascript:text) Linked to 2:tochinese.xfrm
  4    aitest_japanese.txt 27 bytes/1 lines (text/javascript:text) Linked to 2:tojapanese.xfrm
  5    chatgpt.xfrm [PLUGIN] 6323 bytes/221 lines (text/javascript transformer:text)
  6    tochinese.xfrm [PLUGIN] 2790 bytes/91 lines (text/javascript transformer:text)
  7    tojapanese.xfrm [PLUGIN] 2793 bytes/91 lines (text/javascript transformer:text)
* current file, D dirty file
Ready
list
    10 // AI IGNORE
    20 AI PROMPT write me a 3 paragraph story about a little kitten that got lost and tried to find it's way home.
    30 AI END
Ready
edit 10
10 // AI IGNORE x
Ready
ChatGPT processed 1 prompt(s)
Text translated to Chinese
Text translated to Japanese
files
Project name: aitest
Project filename: aitest.prj
Files:
  1 *D aitest_prompt.txt 131 bytes/3 lines (text/javascript:text)
  2  D aitest_story.txt 1490 bytes/6 lines (text/javascript:text) Linked to 1:chatgpt.xfrm
  3  D aitest_chinese.txt 442 bytes/5 lines (text/javascript:text) Linked to 2:tochinese.xfrm
  4  D aitest_japanese.txt 647 bytes/5 lines (text/javascript:text) Linked to 2:tojapanese.xfrm
  5    chatgpt.xfrm [PLUGIN] 6323 bytes/221 lines (text/javascript transformer:text)
  6    tochinese.xfrm [PLUGIN] 2790 bytes/91 lines (text/javascript transformer:text)
  7    tojapanese.xfrm [PLUGIN] 2793 bytes/91 lines (text/javascript transformer:text)
* current file, D dirty file
Ready
file 2
Ready
list
    10 // AI IGNORE x
    20 Whiskers, a tiny gray kitten with bright green eyes, woke up one sunny afternoon to find herself alone in a vast garden. The tall flowers swayed gently in the breeze, and the chirping birds filled the air with cheerful melodies. Curious and adventurous, she had wandered too far from her cozy home in search of a butterfly. Now, with no familiar scents or sounds to guide her, Whiskers felt a flutter of panic in her little heart.
    30
    40 Determined to return, Whiskers started her journey through the garden, her tiny paws padding softly on the warm earth. She sniffed at the air, hoping to catch a whiff of her mother's comforting presence. Along the way, she encountered friendly creatures: a wise old tortoise who offered directions, and a playful squirrel who showed her the way to the edge of the garden. Each encounter brought her closer to her goal, but the path was winding and filled with distractions that made her forget her purpose for a moment.
    50
    60 As dusk began to settle, casting a warm golden hue over the landscape, Whiskers finally spotted a familiar sight—a small wooden fence that surrounded her home. With renewed energy, she dashed toward it, her heart pounding with excitement. As she squeezed through a gap in the fence, she heard her mother's gentle call. Within moments, she was enveloped in the warmth of her mother's embrace, safe at last. The adventure had been daunting, but Whiskers knew she would always find her way home, no matter how lost she felt.
Ready
file 3
Ready
list
    10 小猫胡须,拥有明亮绿色眼睛的灰色小猫,在一个阳光明媚的下午醒来,发现自己独自一人身处一个广阔的花园中。高高的花朵在微风中轻轻摇曳,鸟儿的啁啾声充满了空气,奏响了欢快的旋律。好奇又冒险的她,为了寻找一只蝴蝶而走得离自己舒适的家太远。现在,周围没有熟悉的气味或声音来指引她,胡须感到小心脏里一阵慌乱。
    20
    30 决心要回家,胡须开始在花园中踏上旅程,她的小爪子轻轻踩在温暖的土壤上。她嗅了嗅空气,希望能闻到母亲安慰的气息。在途中,她遇到了友好的生物:一只提供方向的聪明老龟,以及一只带她到花园边缘的顽皮松鼠。每一次相遇都让她离目标更近,但道路弯曲且充满了干扰,让她一时忘记了自己的目的。
    40
    50 黄昏开始降临,给景色披上温暖的金色光辉,胡须终于看到了一个熟悉的景象——一个围绕着她家的小木栅栏。她重新充满了力量,朝它冲去,心中充满了兴奋的跳动。当她挤过栅栏的缝隙时,听到了母亲温柔的呼唤。几秒钟后,她被母亲的怀抱包围,终于安全了。冒险虽然令她感到畏惧,但胡须知道无论她感到多么迷失,她总能找到回家的路。
Ready
file 4
Ready
list
    10 ウィスカーズは、明るい緑の目を持つ小さな灰色の子猫で、ある晴れた午後に広大な庭で一人目覚めました。高い花々はそよ風に揺れ、さえずる鳥たちが空気を楽しいメロディーで満たしていました。好奇心旺盛で冒険心にあふれた彼女は、蝶を探すために居心地の良い家から遠くに迷い込んでしまったのです。今、馴染みのある香りや音がない中で、ウィスカーズの小さな心にはパニックの動悸が感じられました。
    20
    30 帰る決意を固めたウィスカーズは、庭を通り抜ける旅を始めました。彼女の小さな足は温かい土の上で柔らかく踏みしめられました。母の心地よい存在の香りを嗅ぎ取ろうと、彼女は空気を吸い込みました。途中で、彼女は親切な生き物たちに出会いました。道を教えてくれる賢い老亀や、庭の端までの道を示してくれる遊び好きのリスです。それぞれの出会いが彼女を目標に近づけましたが、道は曲がりくねっており、時折目的を忘れさせるような気を散らすものがありました。
    40
    50 夕暮れが訪れ、風景に温かい金色の色合いを投げかけると、ウィスカーズはついに見覚えのある光景を見つけました。彼女の家を囲む小さな木のフェンスです。新たなエネルギーを得て、彼女はそれに向かって駆け出しました。心臓は興奮で高鳴っています。フェンスの隙間を通り抜けると、母の優しい呼び声が聞こえました。数瞬後、彼女は母の抱擁の温もりに包まれ、ついに安全な場所に戻ったのです。冒険は厳しいものでしたが、ウィスカーズは、自分がどれだけ迷っても、いつも家に帰る道を見つけられると知っていました。
Ready
[/color]

zhulien

you can hand-code transformers too if you don't want to use an AI

zhulien

Quote from: mv on 23:16, 26 June 25
Quote from: zhulien on 18:24, 15 June 25CyborgShell now moved to http://cyborgshell.com/
Note yet CPC-capable development tool, but... soon
Interesting project — I find the idea of combining JavaScript with a CPC-style environment very appealing.
When working with LocoBasic, I sometimes wondered: could we start from (simple) JavaScript and compile it into Locomotive BASIC? Or even run a LocoBasic shell and compiler directly on a CPC?

I tried out CyborgShell — nice concept! A few impressions and suggestions:
    • There's a blinking cursor, when the shell is active. For some reason I always try to press Enter but nothing happens.
    • Copy & paste works into the shell, but it would be great to support copying from the shell too.
    • Command history would be a real productivity boost... ;)
    • Command auto-completion would also help with discoverability.
    • Some of the public examples like hello.js and cat.js appear to be binary files and can't be run as-is.
    • I (accidentally!) deleted 3d.js from the public space during testing.
    • I downloaded cat.js from GitHub and used drag & drop to upload it — nothing changed in the UI, so at first I thought it didn't work, but I later found it in the editor.
      Just tried that const {cls, print} = api; cls(); print(...); also works.
    • Minor quirk: I kept typing load"file, but it seems it must be load "file" — maybe a bit more leniency would help.

Looking forward to seeing how the CPC-style API evolves. Keep it up!
udpated cyborgshell.com and cyborgdesktop.com - type notes for today's notes.

commandline history included!

you now run js files simply by typing the filename without extension, i.e. "desktop" will run the desktop, "3d" will run 3d.js.



zhulien

#64
A massive update, you can now store your API Keys in your local storage.  Time to code those transformer plugins to generate some CPC code!

Late breaking release notes.

New Features 26th July 2025:

- You can now save your AI API Keys to your local storage on devices where local storage is available.

config save <identifer> <value>, e.g.

to configure your chatgpt API key, config save chatgpt AbC123
to configure your aihandler to chatgpt, config save aihandler chatgpt (this will use the chatgpt.js handler)

note: you don't need to hardcode APIKeys in the JS, it will use what's in your local storage. Take care
  that you only run trusted programs though that do NOT steal your APIKeys.
 
  note: prompting for permissions is coming soon!!! but if you are coding your own plugins or such
in your own space, then it's unlikely you will have issues.

config delete <identifer> to delete your previously saved config option. e.g. to delete your chatgpt API Key,
config delete chatgpt will do that.

- You can now cd to the new 'local' space with cd local. You can dir it also. For now file functionality is limited
  but you can see your configuration files there.  cd back to home or public or another space to do something useful.

- If you setup an aihandler, you can use the ! AI prefix within Cyborg Shell. e.g. !what is the meaning of life?
  Simply entering ! by itself if configured with the provided chatgpt.js will display some help for managing chatgpt
  sessions. You can use multiple sessions, load and save them, clear them etc. This allows you to create sessions of
  knowledge up to a point, save them and restore them as required. Sessions info is saved in your currently selected
  space when you save them.

New Features 25th July 2025:

- To run a js file, simply type the filename. i.e. to run bm.js, simply type 'bm'.
- Transient programs are now loaded into file space 0 so they don't corrupt user editing.
- Commandline history is now implemented allowing for up and down arrows to navigate.
- You can now code transformer plugins so that linked files can be transformed dynamically in realtime.
- Your transformers are loaded as files so you can develop them as per every other file.
- You can now save your current files and links as a project and load a project to restore the files and links.
- If you setup chatgpt.js, you can use chatgpt within Cyborg Shell. e.g. chatgpt give me a random number

- 3 AI transformer plugins provided chatgpt.xfrm, tolanguage.xfrm, null.xfrm

The AI transformer plugins require an API Key to be useful. You should NOT put any plugins in here on our servers
if you are putting your own API Keys directly into the code. Better you fetch it from local storage as per these plugins.

You can install ollama locally and modify your copy of plugins to use your own ollama which is also free and
you control your own local security. 

Also you can use these transformer plugins as a guide to how you may like to create your own.

chatgpt.xfrm:  this plugin has some commands within:
============

AI IGNORE - if you place AI IGNORE at the start of the file, AI will not be called while it is there.
This allows you to have AI IGNORE there while you create your prompts, and then either remove it or slightly modify it
to trigger the AI to proceed.

The chatgpt plugin has session logic to remember your training data for prompts. You can create and manage different
knowledge blocks with sessions.

AI SESSION CLEAR - will clear all AI session memory stored on in your browser

AI SESSION CLEAR <sessionname>, e.g. AI SESSION CLEAR database will clear only the database session.

AI SESSION START <sessionname> - start of a session block, multiple blocks can share the same session name to build up knowledge.
AI SESSION END <sessionname> - end of a session block, multiple blocks can share the same session name to build up knowledge.

AI PROMPT <sessionname> <prompt> - you can place as many AI PROMPT / AI PROMPT END blocks within your file as you like and each will make
separate AI calls and substitute the AI PROMPT block with the response.  Prompts may be embedded within session blocks.

AI PROMPT END <sessionname> - indicates the end of the prompt.

null.xfrm: if there is any input, return it, otherwise no output
=========

tolanguage.xfrm: if there is any input, transform it, if there is no input, return no output.  It takes the language you want to translate to as an argument.
===============

- New/Enhanced commands below:

file <filenumber>, will now create new files up to the specified filenumber if not already
linkto <sourcefilenumber> <plugin> <arguments>, will now create new files up to the specified filenumber if not already. arguments will be passed to the plugin so you can use the same plugin for different purposes.
link <targetfilenumber> <sourcefilenumber> <plugin> <arguments>, e.g. link 4 2 null will link a null transformer plugin on file 4 to file 2
newfile [<filename>], you can now create a new file but go to the file specified without having to go to the new file
touch <filenumber>, e.g. touch 1 to manually cause all transformers linked to file 1 and cascaded ones to process
project <projectname>, e.g. project test
project load <projectname>, e.g. project load test
project save <projectname>, e.g. project save test
linkto <filenumber> <transformername>, e.g. linkto 1, chatgpt

type ai-example1.txt or type ai-example2.txt for examples of transformer chains.

New Features 16th June 2025:

- You can now login with login yourusername [press enter], then have the password not visible when typing it in.

New Features 15th June 2025:

- Some support for Mime Types.
- Text and non-Text Mime Types can be listed and edited.
- Images and PDF can be OCRd, type 'ocr' after loaded by dragging (for now). New files will be created with any OCRd text.
- OCR currently is a separate module, but is going to evolve into a plugin facility.

New Features 9th March 2025:

- Files can now be dragged onto the editor from your computer.
- You can now paste text into the line editor. Files with line numbers on the first line preserve the numbers without are autonumbered.
- Listing files will now show which files are dirty (with a D).
- 'saveall' will save all named files.

Programming API:

- added input command,
e.g. api.cls(); api.print('enter your name:'); api.input(function(str_a) { api.print('hello ' + str_a); api.stop(); });

Work in Progress:

- ability to upload and download via the commandline.
- ability to schedule and manage the scheduling of JS files via the commandline.
- Saving edited binary Mime Types as binary.

Other notes:

- HCJS rebranded to CyborgShell.
- resolved xbox one browser's autocapitalisation issues by using email instead of text input types.

zhulien

Another update, this was really needed. You can now use the new csconfig utility to configure handlers, providers and services which are all stored in local storage, as well as an autorun program when you reset - such as desktop. 

handlers, really only 1 for now 'ai' for the ! command.
providers, you can configure them all to use different services or the same service, up to you.
services, you can now use any service that follows the typical gpt API, such as chatgpt or even locally installed ollama - both tested here. 

I hope it makes sense.

zhulien

maybe i am thinking to have a feature to turn on or off, the realtime code generation, why invoke the transformers for each line of code - maybe just a touch <filenumber> should do it... or another command as touch sets things to dirty, and the transformers are currently monitoring dirty files.  It's quite good if they are local transformers, but when they are calling AI, it isn't the best. to see all those messages come up.

having said that, it's pretty cool to see in no effort differnt things happen.

project load aicode
Could not load code.txt
Could not load code.c
Could not load code.pas
Could not load code.cs
Could not load code.z80
Could not load code.x86
Could not load code.c64
Could not load code.bas
Could not load code.js
File loaded: chatgpt.xfrm
Project loaded:
Ready
files
Project filename: aicode.prj
Files:
  0    Run Space 0 bytes/0 lines (text/javascript:text)
  1 *  code.txt 0 bytes/0 lines (text/javascript:text)
  2    code.c 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into c
  3    code.pas 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into pascal
  4    code.cs 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into c#
  5    code.z80 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into z80 assembly language for CP/M
  6    code.x86 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into 8086 assembly language for MSDOS
  7    code.c64 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into 6502 assembly language for a Commodore 64
  8    code.bas 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into Amstrad CPC Locomotive BASIC
  9    code.js 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into javascript ES5
 10    Unnamed File 0 bytes/0 lines (text/javascript:text)
 11    chatgpt.xfrm [PLUGIN] 15544 bytes/548 lines (text/javascript transformer:text)

* current file, D dirty file
Ready
10 FOR A = 1 TO 10: PRINT "Hello, World!":NEXT
Ready
openai processed argument prompt re-code this into javascript ES5
openai processed argument prompt re-code this into c#
openai processed argument prompt re-code this into pascal
openai processed argument prompt re-code this into Amstrad CPC Locomotive BASIC
openai processed argument prompt re-code this into c
openai processed argument prompt re-code this into 8086 assembly language for MSDOS
openai processed argument prompt re-code this into 6502 assembly language for a Commodore 64
openai processed argument prompt re-code this into z80 assembly language for CP/M
files
Project filename: aicode.prj
Files:
  0    Run Space 0 bytes/0 lines (text/javascript:text)
  1 *D code.txt 43 bytes/1 lines (text/javascript:text)
  2  D code.c 125 bytes/8 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into c
  3  D code.pas 56 bytes/4 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into pascal
  4  D code.cs 74 bytes/4 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into c#
  5  D code.z80 878 bytes/31 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into z80 assembly language for CP/M
  6  D code.x86 217 bytes/16 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into 8086 assembly language for MSDOS
  7  D code.c64 417 bytes/14 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into 6502 assembly language for a Commodore 64
  8  D code.bas 59 bytes/3 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into Amstrad CPC Locomotive BASIC
  9  D code.js 67 bytes/3 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:re-code this into javascript ES5
 10    Unnamed File 0 bytes/0 lines (text/javascript:text)
 11    chatgpt.xfrm [PLUGIN] 15544 bytes/548 lines (text/javascript transformer:text)

* current file, D dirty file
Ready
saveall
Ready
dir
Directory of home:

                3d.js 5612 bytes
      ai-example1.txt 2736 bytes
      ai-example2.txt 14643 bytes
           aicode.prj 2307 bytes
           aitest.prj 1941 bytes
   aitest_chinese.txt 1478 bytes
   aitest_english.txt 1588 bytes
aitest_indonesian.txt 1769 bytes
  aitest_japanese.txt 2009 bytes
    aitest_prompt.txt 175 bytes
     aitest_story.txt 1588 bytes
   aitest_tagalog.txt 1971 bytes
            arabic.js 339 bytes
         blocker.xfrm 1037 bytes
                bm.js 3401 bytes
               bm.txt 2668 bytes
               cat.js 442 bytes
           chatgpt.js 15077 bytes
         chatgpt.xfrm 15544 bytes
           cliform.js 2681 bytes
             code.bas 55 bytes
               code.c 117 bytes
             code.c64 394 bytes
              code.cs 73 bytes
              code.js 66 bytes
             code.pas 57 bytes
             code.txt 43 bytes
             code.x86 196 bytes
             code.z80 836 bytes
             count.js 136 bytes
csconfig.english.json 4346 bytes
          csconfig.js 15487 bytes
        csconfig.json 513 bytes
              data.js 1855 bytes
          desktop.css 8292 bytes
           desktop.js 50582 bytes
       desktop_api.js 31260 bytes
          filetest.js 606 bytes
           hangman.js 4125 bytes
         helloform.js 1142 bytes
           inc-idb.js 17718 bytes
         language.txt 7 bytes
            lorem.png 4990 bytes
            null.xfrm 806 bytes
             ocr.xfrm 6489 bytes
     passthrough.xfrm 837 bytes
            primes.js 1251 bytes
         simplegpt.js 2941 bytes
              tabs.js 258 bytes
             todo.txt 760 bytes
           tosell.txt 73 bytes
       translate.xfrm 5164 bytes
               ug.txt 2024 bytes
Ready
dir code.*
Directory of home:

code.bas 55 bytes
  code.c 117 bytes
code.c64 394 bytes
 code.cs 73 bytes
 code.js 66 bytes
code.pas 57 bytes
code.txt 43 bytes
code.x86 196 bytes
code.z80 836 bytes
Ready
type code.bas
Ready
     10 10 FOR A = 1 TO 10
     20 20 PRINT "Hello, World!"
     30 30 NEXT A
Ready
type code.c
Ready
     10 #include <stdio.h>
     20
     30 int main() {
     40 for (int A = 1; A <= 10; A++) {
     50 printf("Hello, World!\n");
     60 }
     70 return 0;
     80 }
Ready
type code.c64
Ready
     10 ```
     20 LDX #$01       ; Initialize X register to 1
     30 loop:
     40 LDA message    ; Load the address of the message
     50 JSR $FFD2      ; Call the Kernal to print the string
     60 INX            ; Increment X
     70 CPX #$0A      ; Compare X with 10
     80 BNE loop       ; If X is not 10, repeat
     90 RTS            ; Return from subroutine
    100
    110 message:
    120 .ASC "Hello, World!"
    130 .BYTE $00      ; Null terminator for the string
    140 ```
Ready
type code.cs
Ready
     10 for (int A = 1; A <= 10; A++)
     20 {
     30 Console.WriteLine("Hello, World!");
     40 }
Ready
type code.js
Ready
     10 for (var A = 1; A <= 10; A++) {
     20 console.log("Hello, World!");
     30 }
Ready
type code.pas
Ready
     10 FOR A := 1 TO 10 DO
     20 BEGIN
     30 WRITE('Hello, World!');
     40 END;
Ready
type code.x86
Ready
     10 MOV CX, 10
     20 MOV DX, OFFSET msg
     30
     40 print_loop:
     50 ; Print "Hello, World!"
     60 MOV AH, 09h
     70 INT 21h
     80
     90 ; Decrement CX
    100 LOOP print_loop
    110
    120 ; Exit program
    130 MOV AX, 4C00h
    140 INT 21h
    150
    160 msg DB 'Hello, World!$'
Ready
type code.z80
Ready
     10 ```
     20 ORG 100h          ; Starting address for CP/M
     30 START:
     40 LD C, 10          ; Set loop counter (C = 10)
     50 LD B, 1           ; Initialize A (B = 1)
     60
     70 PRINT_LOOP:
     80 LD HL, MESSAGE     ; Load address of message
     90 CALL PRINT_STRING   ; Call subroutine to print string
    100
    110 INC B              ; Increment A
    120 DEC C              ; Decrement loop counter
    130 JP NZ, PRINT_LOOP  ; Repeat until C = 0
    140
    150 RET                 ; Return from program
    160
    170 PRINT_STRING:
    180 LD A, (HL)         ; Load character
    190 CP 0               ; Check for null terminator
    200 RET Z              ; Return if end of string
    210 CALL PRINT_CHAR    ; Print character
    220 INC HL             ; Move to next character
    230 JP PRINT_STRING    ; Repeat for next character
    240
    250 PRINT_CHAR:
    260 ; Code to print character in A goes here
    270 RET
    280
    290 MESSAGE:
    300 DB 'Hello, World!', 0 ; Null-terminated string
    310 ```
Ready

zhulien

I just created the rpggpt game.  You need to setup your provider to play it.

zhulien

here is an example of the aicoder project.

Project filename: aicoder.prj
Files:
  0    Run Space 0 bytes/0 lines (text/javascript:text)
  1 *  coder.js 0 bytes/0 lines (text/javascript:text) Linked to 2:passthrough.xfrm:
  2    coderai.js 0 bytes/0 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:process the file prompts start with # or // #
  3    coderbackup.js 0 bytes/0 lines (text/javascript:text) Linked to 1:passthrough.xfrm:
  4    passthrough.xfrm [PLUGIN] 837 bytes/24 lines (text/javascript transformer:text)
  5    chatgpt.xfrm [PLUGIN] 15544 bytes/548 lines (text/javascript transformer:text)

file 0 is where stuff runs, 1 is where we are coding, 2 is the chatgpt transformer output that takes input from file 1 (note the link) and follows the instructions in the args (which then takes further instructions from my # within the editor). 3. passthrough (aka copy, in case chatgpt stuffs up too badly). 4. another copy, copy the output which is 2, and put it back into 1 for the next round. 5. the actual plugin added as a result of the link/linkto command.

Interactive 'anything'...

i used as follows, within a few minutes i get output which is close to what i want, basically a projectcreator js.  it's at the point i can manually fix it faster than the AI, but... i got to this point in a only a minute or so.

project load aicoder
Could not load coder.js
Could not load coderai.js
Could not load coderbackup.js
File loaded: passthrough.xfrm
File loaded: chatgpt.xfrm
Project loaded:
Ready
preserve line numbers
10 #we want a ES5 createProject function that takes an array for input arrInput_a of filename strings.  and puts them into a json object which i will describe soon
coder.js passes through
Ready
openai processed argument prompt process the file prompts start with # or // #
coderai.js passes through
list
     10 function createProject(arrInput_a) {
     20 var project = {};
     30 for (var i = 0; i < arrInput_a.length; i++) {
     40 var filename = arrInput_a[i];
     50 project[filename] = {}; // Add an empty object for each filename
     60 }
     70 return project;
     80 }
Ready
5 # add a test harness to this file
coder.js passes through
Ready
openai processed argument prompt process the file prompts start with # or // #
coderai.js passes through
list
     10 function createProject(arrInput_a) {
     20 var project = {};
     30 for (var i = 0; i < arrInput_a.length; i++) {
     40 var filename = arrInput_a[i];
     50 project[filename] = {}; // Add an empty object for each filename
     60 }
     70 return project;
     80 }
     90
    100 // Test harness
    110 function testCreateProject() {
    120 var input = ['file1.txt', 'file2.txt', 'file3.txt'];
    130 var expectedOutput = {
    140 'file1.txt': {},
    150 'file2.txt': {},
    160 'file3.txt': {}
    170 };
    180 var result = createProject(input);
    190 console.assert(JSON.stringify(result) === JSON.stringify(expectedOutput), 'Test failed: expected ' + JSON.stringify(expectedOutput) + ' but got ' + JSON.stringify(result));
    200 console.log('Test passed!');
    210 }
    220
    230 testCreateProject();
Ready
5 add a strProjectName_a parameter. the output json is in this format.  {"projectName": "","files": []} for now make the files an array of objects with a single fn property to store the filename
coder.js passes through
Ready
openai processed argument prompt process the file prompts start with # or // #
coderai.js passes through
list
     10 function createProject(arrInput_a, strProjectName_a) {
     20 var project = {
     30 projectName: strProjectName_a,
     40 files: []
     50 };
     60 for (var i = 0; i < arrInput_a.length; i++) {
     70 var filename = arrInput_a[i];
     80 project.files.push({ fn: filename });
     90 }
    100 return project;
    110 }
    120
    130 // Test harness
    140 function testCreateProject() {
    150 var input = ['file1.txt', 'file2.txt', 'file3.txt'];
    160 var expectedOutput = {
    170 projectName: 'Test Project',
    180 files: [
    190 { fn: 'file1.txt' },
    200 { fn: 'file2.txt' },
    210 { fn: 'file3.txt' }
    220 ]
    230 };
    240 var result = createProject(input, 'Test Project');
    250 console.assert(JSON.stringify(result) === JSON.stringify(expectedOutput), 'Test failed: expected ' + JSON.stringify(expectedOutput) + ' but got ' + JSON.stringify(result));
    260 console.log('Test passed!');
    270 }
    280
    290 testCreateProject();
Ready
# make the projectname contain no spaces, it can contain hyphens
File not found.
5 # make the projectname contain no spaces, it can contain hyphens
coder.js passes through
Ready
openai processed argument prompt process the file prompts start with # or // #
coderai.js passes through
list
     10 function createProject(arrInput_a, strProjectName_a) {
     20 strProjectName_a = strProjectName_a.replace(/\s+/g, '-');
     30 var project = {
     40 projectName: strProjectName_a,
     50 files: []
     60 };
     70 for (var i = 0; i < arrInput_a.length; i++) {
     80 var filename = arrInput_a[i];
     90 project.files.push({ fn: filename });
    100 }
    110 return project;
    120 }
    130
    140 function testCreateProject() {
    150 var input = ['file1.txt', 'file2.txt', 'file3.txt'];
    160 var expectedOutput = {
    170 projectName: 'Test-Project',
    180 files: [
    190 { fn: 'file1.txt' },
    200 { fn: 'file2.txt' },
    210 { fn: 'file3.txt' }
    220 ]
    230 };
    240 var result = createProject(input, 'Test Project');
    250 console.assert(JSON.stringify(result) === JSON.stringify(expectedOutput), 'Test failed: expected ' + JSON.stringify(expectedOutput) + ' but got ' + JSON.stringify(result));
    260 console.log('Test passed!');
    270 }
    280
    290 testCreateProject();
Ready
5 #swap your createProject parameters around
coder.js passes through
Ready
openai processed argument prompt process the file prompts start with # or // #
coderai.js passes through
list
     10 function createProject(strProjectName_a, arrInput_a) {
     20 strProjectName_a = strProjectName_a.replace(/\s+/g, '-');
     30 var project = {
     40 projectName: strProjectName_a,
     50 files: []
     60 };
     70 for (var i = 0; i < arrInput_a.length; i++) {
     80 var filename = arrInput_a[i];
     90 project.files.push({ fn: filename });
    100 }
    110 return project;
    120 }
    130
    140 function testCreateProject() {
    150 var input = ['file1.txt', 'file2.txt', 'file3.txt'];
    160 var expectedOutput = {
    170 projectName: 'Test-Project',
    180 files: [
    190 { fn: 'file1.txt' },
    200 { fn: 'file2.txt' },
    210 { fn: 'file3.txt' }
    220 ]
    230 };
    240 var result = createProject('Test Project', input);
    250 console.assert(JSON.stringify(result) === JSON.stringify(expectedOutput), 'Test failed: expected ' + JSON.stringify(expectedOutput) + ' but got ' + JSON.stringify(result));
    260 console.log('Test passed!');
    270 }
    280
    290 testCreateProject();
Ready
autonumber
# in the output json, each file regardless of filetype should have an entry like (leave mt and mte): {"fn": "actionFMSActiveServicesFetch.php","mt": "text/javascript","mte": "text","ln": null,"pl": "","arg": "","fl": "","st": ""}, for each file added, add them again with a slight modification to the json object and filename. prefix the filename with 'output-', ln should refer to the index+1 of the file when added the first time. pl is the chatgpt.xfrm plugin, and the prompt args as per this example. {"fn": "output-actionFMSActiveServicesFetch.php","mt": "text/javascript","mte": "text","ln": 1,"pl": "chatgpt.xfrm","arg": "please outline any bugs, missing variables or security issues","fl": "","st": ""}.  these files are to be output files referencing the input files. finally add 1 more entry to the object array which is the transformer referenced in the other files, just 1 shared by all: {"fn": "chatgpt.xfrm","mt": "text/javascript transformer","mte": "text","ln": null,"pl": "","arg": "","fl": "","st": ""}
Ready
list
     10 function createProject(strProjectName_a, arrInput_a) {
     20 strProjectName_a = strProjectName_a.replace(/\s+/g, '-');
     30 var project = {
     40 projectName: strProjectName_a,
     50 files: []
     60 };
     70 for (var i = 0; i < arrInput_a.length; i++) {
     80 var filename = arrInput_a[i];
     90 project.files.push({ fn: filename });
    100 }
    110 return project;
    120 }
    130
    140 function testCreateProject() {
    150 var input = ['file1.txt', 'file2.txt', 'file3.txt'];
    160 var expectedOutput = {
    170 projectName: 'Test-Project',
    180 files: [
    190 { fn: 'file1.txt' },
    200 { fn: 'file2.txt' },
    210 { fn: 'file3.txt' }
    220 ]
    230 };
    240 var result = createProject('Test Project', input);
    250 console.assert(JSON.stringify(result) === JSON.stringify(expectedOutput), 'Test failed: expected ' + JSON.stringify(expectedOutput) + ' but got ' + JSON.stringify(result));
    260 console.log('Test passed!');
    270 }
    280
    290 testCreateProject();
    300 # in the output json, each file regardless of filetype should have an entry like (leave mt and mte): {"fn": "actionFMSActiveServicesFetch.php","mt": "text/javascript","mte": "text","ln": null,"pl": "","arg": "","fl": "","st": ""}, for each file added, add them again with a slight modification to the json object and filename. prefix the filename with 'output-', ln should refer to the index+1 of the file when added the first time. pl is the chatgpt.xfrm plugin, and the prompt args as per this example. {"fn": "output-actionFMSActiveServicesFetch.php","mt": "text/javascript","mte": "text","ln": 1,"pl": "chatgpt.xfrm","arg": "please outline any bugs, missing variables or security issues","fl": "","st": ""}.  these files are to be output files referencing the input files. finally add 1 more entry to the object array which is the transformer referenced in the other files, just 1 shared by all: {"fn": "chatgpt.xfrm","mt": "text/javascript transformer","mte": "text","ln": null,"pl": "","arg": "","fl": "","st": ""}
Ready
5
coder.js passes through
Ready
openai processed argument prompt process the file prompts start with # or // #
coderai.js passes through
list
     10 function createProject(strProjectName_a, arrInput_a) {
     20 strProjectName_a = strProjectName_a.replace(/\s+/g, '-');
     30 var project = {
     40 projectName: strProjectName_a,
     50 files: []
     60 };
     70 for (var i = 0; i < arrInput_a.length; i++) {
     80 var filename = arrInput_a[i];
     90 project.files.push({
    100 fn: filename,
    110 mt: "text/javascript",
    120 mte: "text",
    130 ln: i + 1,
    140 pl: "",
    150 arg: "",
    160 fl: "",
    170 st: ""
    180 });
    190 project.files.push({
    200 fn: 'output-' + filename,
    210 mt: "text/javascript",
    220 mte: "text",
    230 ln: i + 1,
    240 pl: "chatgpt.xfrm",
    250 arg: "please outline any bugs, missing variables or security issues",
    260 fl: "",
    270 st: ""
    280 });
    290 }
    300 project.files.push({
    310 fn: "chatgpt.xfrm",
    320 mt: "text/javascript transformer",
    330 mte: "text",
    340 ln: null,
    350 pl: "",
    360 arg: "",
    370 fl: "",
    380 st: ""
    390 });
    400 return project;
    410 }
    420
    430 function testCreateProject() {
    440 var input = ['file1.txt', 'file2.txt', 'file3.txt'];
    450 var expectedOutput = {
    460 projectName: 'Test-Project',
    470 files: [
    480 { fn: 'file1.txt', mt: "text/javascript", mte: "text", ln: 1, pl: "", arg: "", fl: "", st: "" },
    490 { fn: 'output-file1.txt', mt: "text/javascript", mte: "text", ln: 1, pl: "chatgpt.xfrm", arg: "please outline any bugs, missing variables or security issues", fl: "", st: "" },
    500 { fn: 'file2.txt', mt: "text/javascript", mte: "text", ln: 2, pl: "", arg: "", fl: "", st: "" },
    510 { fn: 'output-file2.txt', mt: "text/javascript", mte: "text", ln: 2, pl: "chatgpt.xfrm", arg: "please outline any bugs, missing variables or security issues", fl: "", st: "" },
    520 { fn: 'file3.txt', mt: "text/javascript", mte: "text", ln: 3, pl: "", arg: "", fl: "", st: "" },
    530 { fn: 'output-file3.txt', mt: "text/javascript", mte: "text", ln: 3, pl: "chatgpt.xfrm", arg: "please outline any bugs, missing variables or security issues", fl: "", st: "" },
    540 { fn: "chatgpt.xfrm", mt: "text/javascript transformer", mte: "text", ln: null, pl: "", arg: "", fl: "", st: "" }
    550 ]
    560 };
    570 var result = createProject('Test Project', input);
    580 console.assert(JSON.stringify(result) === JSON.stringify(expectedOutput), 'Test failed: expected ' + JSON.stringify(expectedOutput) + ' but got ' + JSON.stringify(result));
    590 console.log('Test passed!');
    600 }
    610
    620 testCreateProject();
Ready
autonumber
# in the output json, each file regardless of filetype should have an INPUT entry like (leave mt and mte): {"fn": "actionFMSActiveServicesFetch.php","mt": "text/javascript","mte": "text","ln": null,"pl": "","arg": "","fl": "","st": ""}, for each file added, add them again with a slight modification to the json object and filename. prefix the filename with 'output-', ln should refer to the index+1 of the INPUT file entry when added the first time. pl is the chatgpt.xfrm plugin, and the prompt args as per this example. {"fn": "output-actionFMSActiveServicesFetch.php","mt": "text/javascript","mte": "text","ln": 1,"pl": "chatgpt.xfrm","arg": "please outline any bugs, missing variables or security issues","fl": "","st": ""}.  these files are to be output files referencing the input files. finally add 1 more entry to the object array which is the transformer referenced in the other files, just 1 shared by all: {"fn": "chatgpt.xfrm","mt": "text/javascript transformer","mte": "text","ln": null,"pl": "","arg": "","fl": "","st": ""}
Ready
1
coder.js passes through
Ready
openai processed argument prompt process the file prompts start with # or // #
coderai.js passes through
list
     10 function createProject(strProjectName_a, arrInput_a) {
     20 strProjectName_a = strProjectName_a.replace(/\s+/g, '-');
     30 var project = {
     40 projectName: strProjectName_a,
     50 files: []
     60 };
     70 for (var i = 0; i < arrInput_a.length; i++) {
     80 var filename = arrInput_a[i];
     90 project.files.push({
    100 fn: filename,
    110 mt: "",
    120 mte: "",
    130 ln: null,
    140 pl: "",
    150 arg: "",
    160 fl: "",
    170 st: ""
    180 });
    190 project.files.push({
    200 fn: 'output-' + filename,
    210 mt: "",
    220 mte: "",
    230 ln: i + 1,
    240 pl: "chatgpt.xfrm",
    250 arg: "please outline any bugs, missing variables or security issues",
    260 fl: "",
    270 st: ""
    280 });
    290 }
    300 project.files.push({
    310 fn: "chatgpt.xfrm",
    320 mt: "text/javascript transformer",
    330 mte: "text",
    340 ln: null,
    350 pl: "",
    360 arg: "",
    370 fl: "",
    380 st: ""
    390 });
    400 return project;
    410 }
    420
    430 function testCreateProject() {
    440 var input = ['file1.txt', 'file2.txt', 'file3.txt'];
    450 var expectedOutput = {
    460 projectName: 'Test-Project',
    470 files: [
    480 { fn: 'file1.txt', mt: "", mte: "", ln: null, pl: "", arg: "", fl: "", st: "" },
    490 { fn: 'output-file1.txt', mt: "", mte: "", ln: 1, pl: "chatgpt.xfrm", arg: "please outline any bugs, missing variables or security issues", fl: "", st: "" },
    500 { fn: 'file2.txt', mt: "", mte: "", ln: null, pl: "", arg: "", fl: "", st: "" },
    510 { fn: 'output-file2.txt', mt: "", mte: "", ln: 2, pl: "chatgpt.xfrm", arg: "please outline any bugs, missing variables or security issues", fl: "", st: "" },
    520 { fn: 'file3.txt', mt: "", mte: "", ln: null, pl: "", arg: "", fl: "", st: "" },
    530 { fn: 'output-file3.txt', mt: "", mte: "", ln: 3, pl: "chatgpt.xfrm", arg: "please outline any bugs, missing variables or security issues", fl: "", st: "" },
    540 { fn: "chatgpt.xfrm", mt: "text/javascript transformer", mte: "text", ln: null, pl: "", arg: "", fl: "", st: "" }
    550 ]
    560 };
    570 var result = createProject('Test Project', input);
    580 console.assert(JSON.stringify(result) === JSON.stringify(expectedOutput), 'Test failed: expected ' + JSON.stringify(expectedOutput) + ' but got ' + JSON.stringify(result));
    590 console.log('Test passed!');
    600 }
    610
    620 testCreateProject();
Ready

zhulien

#69
Quote from: zhulien on 19:09, 27 July 25I just created the rpggpt game.  You need to setup your provider to play it.

For those who like text adventures? now here is the ultimate play any adventure you want...  Example...

rpggpt
Enter a brief summary describing your ideal RPG game. Suggest a main plot or goal, specify the type of character you'd like to play, and describe the setting or world for your adventure. Feel free to mention any special themes, challenges, or story elements you'd like to see included in your game.
 
You're a superhero who lost their powers and must save the city using only wit and gadgets.
Enter your character's name:
Zara
 
The city of Eldoria is in turmoil. Once a bustling metropolis filled with vibrant life, it now lies shrouded in chaos. An evil mastermind known as Dr. Obsidian has unleashed a wave of destruction, leaving the authorities powerless and the citizens in despair. You, Zara, once a celebrated superhero with extraordinary abilities, now find yourself stripped of your powers and trapped in a world that desperately needs saving.

You stand on the rooftop of a crumbling skyscraper, overlooking the chaos below. Smoke billows from buildings, sirens wail in the distance, and the atmosphere crackles with tension. You can feel the weight of the city's fate resting on your shoulders, but you know you have your wits and a few gadgets at your disposal.

In your utility belt, you have:

1. **Smoke Bombs**: Perfect for creating distractions or making a quick escape.
2. **Grappling Hook**: Allows you to reach high places or swing across gaps.
3. **EMP Device**: Can disable electronics for a short time, useful against tech-based foes.
4. **Holo-Disguise Projector**: Creates a temporary illusion of another person, which can be helpful for stealth.

As you survey the city, you spot a few key locations:

- **The Central Plaza**: Crowds are gathered, panicking as Dr. Obsidian's minions wreak havoc.
- **The Old Library**: Rumored to contain ancient texts that may hold the key to defeating Dr. Obsidian.
- **The Abandoned Warehouse**: Known to be a hideout for criminals; it might be a good place to gather intel.

You need a plan. What would you like to do?
 
go to the old library
You make your way towards the Old Library, your heart pounding with the urgency of the city's plight. As you navigate through the streets, you expertly avoid the chaos, using your grappling hook to swing between buildings and evade Dr. Obsidian's minions.

Arriving at the library, you notice its grand architecture is marred by neglect; ivy climbs its stone walls, and the large wooden doors creak ominously as you push them open. The inside is dimly lit, with dusty shelves towering over you, filled with forgotten tomes. The air is thick with the scent of aged paper and mystery.

As you step further inside, you hear a faint noise. It seems like someone might be inside. You have a few options:

1. **Investigate the noise**: Approach cautiously to see who or what is making the sound.
2. **Search the shelves**: Look for any specific texts or scrolls that might provide information on Dr. Obsidian.
3. **Set a smoke bomb**: Create a diversion just in case there's danger lurking, allowing you to escape if needed.

What would you like to do?
 
set a smoke bomb then investigate the noise cautiously
You quickly reach for a smoke bomb from your utility belt, holding your breath as you pull the pin and toss it to the ground. A thick cloud of smoke billows up, filling the library with a dense haze. With your vision obscured, you feel a rush of adrenaline as you move stealthily toward the source of the noise.

As you approach, you can hear muffled voices, one of which sounds distressed. You inch closer, carefully navigating through the shelves, listening intently. The smoke provides a perfect cover; you can hear the voices more clearly now.

"Please, I didn't mean to trespass!" a frightened voice pleads. "I was just looking for a way to stop him!"

You peer around a corner of the shelf and spot a young woman, her clothes tattered and dirt smudged on her face. She's backed against a shelf, trembling. In front of her stands a cloaked figure—one of Dr. Obsidian's minions. They appear to be holding a device that looks suspiciously like the EMP device you've seen before.

You have a few options on how to proceed:

1. **Confront the minion**: Use your gadgets to take them by surprise.
2. **Try to reason with the young woman**: Find out what she knows about stopping Dr. Obsidian.
3. **Create a distraction**: Set off another smoke bomb or use your Holo-Disguise Projector to confuse the minion.

What would you like to do?
 
quickly see if there are any non-lethal objects i can see that might be able to distract the minion with
You scan the surroundings quickly, your mind racing as you try to find anything that could serve as a distraction. Your eyes dart across the shelves, noticing various items that might prove useful:

1. **Old Books**: There are several heavy books stacked precariously on a shelf nearby. You could throw one to create a noise on the other side of the room.
2. **A Glass Globe**: An ancient-looking glass globe sits on a pedestal, reflecting the dim light. If you were to knock it over, it could shatter and draw the minion's attention.
3. **Dusty Scrolls**: A pile of scrolls lies on a table, and you could easily scatter them to make a ruckus as they fall to the ground.

With these options in mind, you can choose one of them to use as a distraction. What would you like to do?
 
just run and tackle the minion
With determination coursing through you, you decide to take action. You surge forward from your hiding spot, using the smoke as cover, and launch yourself at the cloaked minion. The element of surprise is on your side as you tackle them to the ground, your momentum knocking the device from their grasp.

The minion is caught off guard, and you quickly wrestle them away, pinning them to the ground. You can feel their struggle beneath you, but you have the advantage. The young woman watches in awe, her fear turning into hope.

As you hold the minion down, you have a few options:

1. **Interrogate the minion**: Demand to know what they know about Dr. Obsidian's plans and any weaknesses he might have.
2. **Secure the minion**: Use a gadget, like your grappling hook, to tie them up temporarily.
3. **Let the minion go**: Release them but threaten them, hoping they'll spread word that you're back in action.

What would you like to do?
 
punch the minion and don't stop until he is unconcious
Fueled by a surge of adrenaline and the need to protect the young woman, you unleash a powerful punch to the minion's face. The impact reverberates through your fist, and the minion lets out a grunt of surprise.

You don't stop there. With each strike, you rain down blows, your training as a superhero kicking in despite the loss of your powers. The minion struggles beneath you, but your determination is unyielding. After a few more solid punches, the minion's resistance fades, and they fall unconscious beneath you.

Breathing heavily, you rise to your feet, glancing around to ensure the coast is clear. The young woman stands wide-eyed, clearly impressed and relieved.

"Wow! That was amazing!" she exclaims, stepping closer. "I thought I was done for. Thank you!"

You take a moment to catch your breath and assess the situation. The minion lies motionless on the ground, and the EMP device they were holding is within reach.

You can now:

1. **Examine the EMP device**: See if it can be useful for your plans against Dr. Obsidian.
2. **Talk to the young woman**: Ask her who she is and what she knows about Dr. Obsidian and his schemes.
3. **Search the minion's pockets**: Look for any clues or gadgets that might aid you in your quest.

What would you like to do?
 
ask the woman what she is doing here
You turn to the young woman, curiosity piqued by her sudden appearance in the library. "What are you doing here?" you ask, your voice steady despite the adrenaline still coursing through your veins.

She takes a deep breath, relief washing over her as she realizes she's safe for the moment. "My name is Lila," she replies, her voice trembling slightly. "I've been trying to gather information about Dr. Obsidian and his plans. I heard rumors that there are texts in this library that could hold the secrets to stopping him. I thought I could find something to help the city, but I didn't expect to run into his minions."

Her eyes widen as she glances at the unconscious minion on the floor. "You're a superhero, aren't you? I've heard stories about you, Zara! But I thought you lost your powers..."

You nod, acknowledging her recognition. "I have, but I'm determined to save this city one way or another."

Lila's determination seems to mirror yours as she continues, "I read about an ancient artifact that's hidden somewhere in the library. It's said to have the power to disrupt Dr. Obsidian's technology. If we can find it, we might be able to turn the tide!"

You sense the urgency of the situation. You can:

1. **Ask Lila for more details about the artifact**: Find out if she knows anything specific about its location or how to use it.
2. **Search the library together**: Team up with Lila to comb through the shelves for any sign of the artifact.
3. **Check the unconscious minion**: See if they have any information about the artifact or Dr. Obsidian's plans.

What would you like to do?
 
sessions
Active sessions: zara (14 entries, 19 KB)
Total memory usage: 19 KB of 256 MB
 
save zara
 
Session "zara" saved.

A tiny enhancement i need to make that you can work around for now... that is restoring your game to continue later.  For now when you are prompted for a scenario, just type continue, then type the same character name you used before 'zara'.  then type load zara.  the adventure will continue.

zhulien

Normal file draggin behaviour: I dragged 3 files, so 3 are dirty and will all save when I type 'saveall'.

files
Files:
  0    Run Space 0 bytes/0 lines (text/javascript:text)
  1    Unnamed File 0 bytes/0 lines (text/javascript:text)
  2  D test3.txt 45 bytes/1 lines (text/plain:text)
  3  D test2.txt 16 bytes/1 lines (text/plain:text)
  4 *D test1.txt 33 bytes/1 lines (text/plain:text)

* current file, D dirty file
Ready

Linking a transformer to the drop event:

link drop chatgpt translate to Japanese
Event link added: drop => chatgpt.xfrm:translate to Japanese
Ready

Project created from dropped files with event 'drop'.
openai processed argument prompt translate to Japanese
openai processed argument prompt translate to Japanese
openai processed argument prompt translate to Japanese
files
Project name: DroppedProject
Files:
  0    Run Space 0 bytes/0 lines (text/javascript:text)
  1 *D test1.txt 33 bytes/1 lines (text/javascript:text)
  2  D test2.txt 16 bytes/1 lines (text/javascript:text)
  3  D test3.txt 45 bytes/1 lines (text/javascript:text)
  4  D output-test1.txt 17 bytes/1 lines (text/javascript:text) Linked to 1:chatgpt.xfrm:translate to Japanese
  5  D output-test2.txt 12 bytes/1 lines (text/javascript:text) Linked to 2:chatgpt.xfrm:translate to Japanese
  6  D output-test3.txt 22 bytes/1 lines (text/javascript:text) Linked to 3:chatgpt.xfrm:translate to Japanese
  7  D chatgpt.xfrm [PLUGIN] 15544 bytes/548 lines (text/javascript transformer:text)

* current file, D dirty file
Ready
list
     10 what is the capital of Ireland?
Ready
file 4
Ready
list
     10 アイルランドの首都はダブリンです。
Ready


What happens if the drop event is configured, is when you drag files to the screen, you do lose what you were doing in order to have a new project automatically setup as displayed above.  You can use any transformers you have or create.  For example, you could customise the chatgpt one to analyse your code and log all bugs into JIRA.  Other uses are the ocr plugin, drag images or PDFs on to have them automatically OCRd.

For now drop events can only have a single transformer because i don't know how we would want to setup a project if there were multiple.  Maybe i could later create a project template idea where the files dragged are added template like, so you can then perform multiple tranformations from a single drag and drop of many files.

So today... i was able to process 83 files that would normally take me 2 days in finding bugs... I did it in less than a minute!


Powered by SMFPacks Menu Editor Mod