Problems with KMFAM Macro System

Greetings Keyboard Maestros

I've have used Keyboard Maestro for around six weeks and became a registered user after just week of trialling. The "About Keyboard Maestro" states that I've already saved 62 days - I'm not sure how it calculates that figure, but I won't argue!

Anyway, the point of me posting this is that the equally brilliant KMFAM has started giving an error message when running the "[KMFAM] Add Action(s)" macro despite using it without issues with numerous successes over the past few weeks.

Environment:

  • Keyboard Maestro v.9.2
  • KMFAM v.1.1
  • Mac Mini (M1) Big Sur v.11.4

After highlighting the desired action and issuing ⌘F15 I confirm that the Action name is copied to the clipboard. This is followed by an almighty pause (around three seconds in duration), and the following message is displayed instead of the usual "Add Action" prompt

  • ...This one during normal operation...
    Screenshot 2021-07-02 at 00.34.21

The KMFAM configuration is correct. I can see the necessary files via Finder and I can cat the contents via Terminal. The "Add Macro" action works as expected. Other KM macros work as expected.

Stepping through the actions of "Add Actions(s)" I eventually ended up loading "Favorite Actions Core.scpt" into the Safari Web Inspector debugger. I had never used the debugger before this. I hadn't even taken any notice of Javascript for Automation until then. I live a sheltered life. Anyway three days later I now get the following message, but only when using the debugger.

At this point KMFAM removal and reinstallation gave the same results. I also relocated the KM Resources Folder to a volume/folder that was not part of my iCloud configuration. Eventually I started with a fresh Each change gave the same errors.

I've tried adding different actions and more than one action, but each time, the error message is the same.

I'm not sure what else to try.

Any advice is appreciated.

Many Thanks

dp

I think this should solve your issue:

Hello Dan

Many Thanks for the super fast reply.

I've gotten into the habit of creating macros that perform their own "housekeeping" :slight_smile: Nevertheless, I gave the KM Variable List macro a run along with the Clean Up macro....

  • Before Clean Up...
    Screenshot 2021-07-02 at 13.16.44

  • After Clean Up...
    Screenshot 2021-07-02 at 13.37.03

With only those variables in the list, KMFAM still reports the same error :frowning:

I installed KM on a MacBook Pro (Big Sur v.11.1) along with KMFAM and everything works as expected. Looking through my recent software updates I see that the OS was updated a few days ago which coincides with when I first noticed the KMFAM issue.

  • Screenshot 2021-07-02 at 13.46.59

Could this update have broken something within KMFAM?

@DeepHeat, Your post (and replies) have been moved to a new Topic since you have asked a new question. Please follow this policy in the future.

A post was split to a new topic: How Do I Move Posts?

OK, let's see if we can narrow it down. Download this and install this in KM:

[kmfam]~Core (Sub-Macro) DEBUG CODE.kmmacros (58.3 KB)

Import it into KM. But you're not going to actually use this macro, you're just gonna copy from it.

I want you to modify the existing [kmfam]~Core (Sub-Macro) macro as follows:

#1 - Disable the "Run our Core script..." action

#2 & #3 - Copy these two actions from the DEBUG CODE macro, and paste them here.

#4 - Disable the last "if" in the macro.

Assuming I explained things well enough, and you followed instructions, run it and it should display a window with debug text in it. Post the text here.

You can switch from the debug version to the original version just by enabling and disabling #1 and #2. You can leave #3 & #4 as they are.

Fingers crossed.

Many Thanks Dan - I really wasn't expecting you to reply so quickly..

  1. Disabled Actions in "[kmfam]~Core (Sub-Macro)":

    • Run our Core script, to process the Request that was passed in TriggerValue,
    • If the Log variable contains anything, display it (for debugging)

...and...

  1. Added Actions from "[kmfam]~Core (Sub-Macro) DEBUG CODE"
    • Execute JavaScript For Automation
    • If the Log variable contains anything, display it (for debugging)

Screenshot 2021-07-02 at 20.28.42

  1. Trigger "[kmfam]~Core (Sub-Macro)"

Results.....

DEBUG LOG:
-------------

getNewActionFromClipboard
getActionsClipboardType
getClipboardStringForType
plistString: undefined

Hope this helps!

:+1:

Many apologies. I will take better care in the future.

You caught me on a good day. :smile:

Download and unzip this text file:

script.txt.zip (8.2 KB)

Then delete the current contents of the "Execute JavaScript for Automation" action (I think you know which action I mean), and paste the new text into it.

Run it again, and reply with the results.

Long may that continue!

As advised I deleted the contents of my latest arch-nemesis, "Execute Javascript for Automation" action and replaced it with the code from the zipped file..

  • Here are the results
    Screenshot 2021-07-02 at 22.40.58

....and...

    DEBUG LOG:
    -------------

    ```
    ENTER: Request: getNewActionFromClipboard
    	ENTER: getNewActionFromClipboard
    		getActionsClipboardType: com.stairways.keyboardmaestro.actionarray
    		ENTER: getClipboardStringForType "com.stairways.keyboardmaestro.actionarray"
    			Clipboard contains type
    			Result from NSPasteboard.generalPasteboard.stringForType(com.stairways.keyboardmaestro.actionarray):
    			EXIT: getClipboardStringForType "com.stairways.keyboardmaestro.actionarray"
    		EXIT: getNewActionFromClipboard
    	EXIT: Request: getNewActionFromClipboard

Well, at least we know where the error is. I'm getting an empty string from the clipboard. There's two possibilities that I can think of:

  1. The first, and least likely, is that even though the clipboard contains the proper type, it's empty. That seems highly unlikely.

  2. The second and most likely is that for some reason it won't let me get the actual contents of the clipboard. And that sounds very much like a permissions error.

Grasping at straws here, but @ccstone, @JMichaelTX , @ComplexPoint , @peternlewis - do any of you have any idea why I can't get the contents of the clipboard? This code is for KMFAM, which works on just about everybody else's computers, so there's definitely something wonky here.

Many Thanks for your heroic efforts so far Dan

I've upgraded the MacBook Pro to Big Sur v11.4 and retested KM/KMFAM. I'm pretty certain that the Apple update is the root cause.

I just updated to 11.4, so if it is an issue on 11.4, and you send me a barebones test script, I will check it out and see if I can learn anything.

I think my first step would be to check exactly what seems to be in the clipboard, and under what type key(s), perhaps trying something along these lines:

Clipboard Viewer (all textually representable data as JSON).kmmacros (21.2 KB)

Expand disclosure triangle to view JS Source
(() => {
    "use strict";

    // Rob Trew @2021

    ObjC.import("AppKit");

    // ----------- VIEW OF TYPES IN CLIPBOARD ------------

    // main :: IO ()
    const main = () => (
        pBoard => JSON.stringify(
            cartesianProduct(
                ObjC.deepUnwrap(
                    pBoard.pasteboardItems.js[0].types
                )
            )([
                "propertyList", "string", "data"
            ])
            .reduce(
                (a, [bundleID, k]) => (
                    a[`${bundleID} as ${k}`] = ObjC.deepUnwrap(
                        k !== "data" ? (
                            pBoard[`${k}ForType`](bundleID)
                        ) : $.NSString.alloc.initWithDataEncoding(
                            pBoard.dataForType(bundleID),
                            $.NSUTF8StringEncoding
                        )
                    ),
                    a
                ), {}
            ), null, 2
        )
    )($.NSPasteboard.generalPasteboard);

    // -------------- GENERIC FUNCTIONS --------------

    // cartesianProduct :: [a] -> [b] -> [[a, b]]
    const cartesianProduct = xs =>
        ys => xs.flatMap(
            x => ys.flatMap(
                y => [
                    [x, y]
                ]
            )
        );


    // MAIN ---
    return main();
})();
1 Like

Thanks! If you're using KMFAM, just try to add a new favorite action. If it works, that answers the question.

If not, I'll put something together.

@DeepHeat - Can you download and install @ComplexPoint's "Clipboard Viewer" macro, which he posted a few replies above? You'll need to enable it.

Then try to add an action again, and when it fails, run the clipboard viewer macro, and let me know what it shows. Thanks!

Thanks, that's perfect!

Here is the output from @ComplexPoint's Clipboard Viewer macro taken after running "[KMFAM] Add Action(s)" (and while the error message and the debug log were still present on screen)

{
  "public.utf8-plain-text as propertyList": "Group-L1",
  "public.utf8-plain-text as string": "Group-L1\n",
  "public.utf8-plain-text as data": "Group-L1\n",
  "com.stairways.keyboardmaestro.actionarray as propertyList": [
    {
      "MacroActionType": "Group",
      "TimeOutAbortsMacro": true,
      "ActionColor": "Purple",
      "ActionName": "Group-L1",
      "Actions": []
    }
  ]
}

Many Thanks Guys!

@ComplexPoint - Can you explain this code in more detail - perhaps break it apart into separate statements? Because whatever you're doing, it works where mine doesn't:

Yours:

ObjC.deepUnwrap(
    k !== "data" ? (
        pBoard[`${k}ForType`](bundleID)
    ) : $.NSString.alloc.initWithDataEncoding(
        pBoard.dataForType(bundleID),
        $.NSUTF8StringEncoding
    )
)

Here's what I'm doing, simplified:

ObjC.unwrap(
	$.NSPasteboard.generalPasteboard
	.stringForType("com.stairways.keyboardmaestro.actionarray"));

Thanks.

Perhaps just a type issue ?

Some types of clipboard contents are indeed strings, and for these:

.stringForType(bundleID)

is a relevant method, but for data with the propertyList structure you may need:

  • .propertyListForType(bundleID)
  • and typically a recursive unwrap with ObjC.deepUnwrap

so for example:

(() => {
    "use strict";

    ObjC.import("AppKit");

    const main = () =>
        ObjC.deepUnwrap(
            $.NSPasteboard.generalPasteboard
            .propertyListForType(
                "com.stairways.keyboardmaestro.actionarray"
            )
        );

    return main();
})();
1 Like