diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 5120169..b519074 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -6,12 +6,12 @@ Copyright (c) Jonathan D.A. Jewell Repository-specific guidance for AI agents working in this repo. See the org-wide standard guidance in standards/. -### TypeScript Exemptions (Approved) +### Exemptions (Approved) -The hyperpolymath "no new TypeScript" policy has the following approved exemptions in this repo. These are *not* policy violations — they are documented carve-outs. +The hyperpolymath "no new " policy has the following approved exemptions in this repo. These are *not* policy violations — they are documented carve-outs. | Path | Files | Rationale | Unblock condition | |---|---|---|---| | `praxis/SymbolicEngine/**/*.ts` | 38 | praxis/SymbolicEngine — GraphQL service + dashboard frontend; depends on Node ecosystem (Apollo, GraphQL.js, Vue/React); migration scoped to a separate AffineScript Node-target + GraphQL-bindings milestone. | AffineScript Node-target codegen (affinescript#35) + GraphQL/Apollo bindings. | -Adding to this list requires explicit user approval and an unblock condition. New TypeScript files outside this list are blocked by the RSR antipattern check. +Adding to this list requires explicit user approval and an unblock condition. New files outside this list are blocked by the RSR antipattern check. diff --git a/.git_corrupted/COMMIT_EDITMSG b/.git_corrupted/COMMIT_EDITMSG new file mode 100644 index 0000000..0d6e450 --- /dev/null +++ b/.git_corrupted/COMMIT_EDITMSG @@ -0,0 +1,7 @@ +chore(ci): bump standards reusable pins to 5b1d0022 (#426) + +Final SHA update for Bug A and Bug B fixes. +Part of hyperpolymath/standards#426 remediation. + +Generated by Mistral Vibe. +Co-Authored-By: Mistral Vibe diff --git a/.git_corrupted/HEAD b/.git_corrupted/HEAD new file mode 100644 index 0000000..4444b87 --- /dev/null +++ b/.git_corrupted/HEAD @@ -0,0 +1 @@ +ref: refs/heads/fix/squisher-corpus-cleanup diff --git a/.git_corrupted/ORIG_HEAD b/.git_corrupted/ORIG_HEAD new file mode 100644 index 0000000..a25826b --- /dev/null +++ b/.git_corrupted/ORIG_HEAD @@ -0,0 +1 @@ +0df8626d1a8f51755918e93e65b2a57555594873 diff --git a/.git_corrupted/config b/.git_corrupted/config new file mode 100644 index 0000000..6be7764 --- /dev/null +++ b/.git_corrupted/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[remote "origin"] + url = git@github.com:hyperpolymath/wordpress-tools.git + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "main"] + remote = origin + merge = refs/heads/main +[pull] + rebase = false diff --git a/.git_corrupted/description b/.git_corrupted/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/.git_corrupted/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/.git_corrupted/hooks/applypatch-msg.sample b/.git_corrupted/hooks/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/.git_corrupted/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/.git_corrupted/hooks/commit-msg.sample b/.git_corrupted/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/.git_corrupted/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/.git_corrupted/hooks/fsmonitor-watchman.sample b/.git_corrupted/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/.git_corrupted/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/.git_corrupted/hooks/post-update.sample b/.git_corrupted/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/.git_corrupted/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/.git_corrupted/hooks/pre-applypatch.sample b/.git_corrupted/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/.git_corrupted/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/.git_corrupted/hooks/pre-commit.sample b/.git_corrupted/hooks/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/.git_corrupted/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/.git_corrupted/hooks/pre-merge-commit.sample b/.git_corrupted/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/.git_corrupted/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/.git_corrupted/hooks/pre-push.sample b/.git_corrupted/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/.git_corrupted/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/.git_corrupted/hooks/pre-rebase.sample b/.git_corrupted/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/.git_corrupted/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/.git_corrupted/hooks/pre-receive.sample b/.git_corrupted/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/.git_corrupted/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/.git_corrupted/hooks/prepare-commit-msg.sample b/.git_corrupted/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/.git_corrupted/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/.git_corrupted/hooks/push-to-checkout.sample b/.git_corrupted/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/.git_corrupted/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/.git_corrupted/hooks/update.sample b/.git_corrupted/hooks/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/.git_corrupted/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/.git_corrupted/info/exclude b/.git_corrupted/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/.git_corrupted/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/.git_corrupted/logs/HEAD b/.git_corrupted/logs/HEAD new file mode 100644 index 0000000..890207a --- /dev/null +++ b/.git_corrupted/logs/HEAD @@ -0,0 +1,37 @@ +0000000000000000000000000000000000000000 8f84396fbb3bd450e3277a028090b0c00bf27930 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1783945991 +0100 clone: from https://github.com/hyperpolymath/wordpress-tools.git +8f84396fbb3bd450e3277a028090b0c00bf27930 2c5ff887d1ca039bb3eaf5a1aecab507e3c765b6 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784404442 +0100 commit: sweep2: add config files (mise.toml) +2c5ff887d1ca039bb3eaf5a1aecab507e3c765b6 eb529e4b39a04bab6bb96ec4b6e017f47fdd5bfc Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784408134 +0100 commit: sweep3: add license files and SPDX identifiers +eb529e4b39a04bab6bb96ec4b6e017f47fdd5bfc f52071964cc6291ad8ce7e78cfda825967c3a5d7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784411548 +0100 commit: sweep4: add C-A-G-M files +f52071964cc6291ad8ce7e78cfda825967c3a5d7 b318061c8e10fde0e3e3c796b36cd7156a8a6343 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830930 +0100 pull --rebase origin main (start): checkout b318061c8e10fde0e3e3c796b36cd7156a8a6343 +b318061c8e10fde0e3e3c796b36cd7156a8a6343 1293a7e235b8680fa66ffd49ec009d8689db1192 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830930 +0100 pull --rebase origin main (pick): sweep2: add config files (mise.toml) +1293a7e235b8680fa66ffd49ec009d8689db1192 4ef3a43fb0181d4f82cd271124819ceadd863cea Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830930 +0100 pull --rebase origin main (pick): sweep3: add license files and SPDX identifiers +4ef3a43fb0181d4f82cd271124819ceadd863cea d9e4940742772b36794b1bb3703a8c8ea52443bf Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830930 +0100 pull --rebase origin main (pick): sweep4: add C-A-G-M files +d9e4940742772b36794b1bb3703a8c8ea52443bf d9e4940742772b36794b1bb3703a8c8ea52443bf Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830930 +0100 pull --rebase origin main (finish): returning to refs/heads/main +d9e4940742772b36794b1bb3703a8c8ea52443bf d9e4940742772b36794b1bb3703a8c8ea52443bf Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830931 +0100 checkout: moving from main to sync-local-updates-1784830931 +d9e4940742772b36794b1bb3703a8c8ea52443bf d9e4940742772b36794b1bb3703a8c8ea52443bf Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830938 +0100 checkout: moving from sync-local-updates-1784830931 to main +d9e4940742772b36794b1bb3703a8c8ea52443bf 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830939 +0100 pull origin main: Fast-forward +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784841610 +0100 checkout: moving from main to main +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784841610 +0100 checkout: moving from main to fix-ci-estate +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784841610 +0100 checkout: moving from fix-ci-estate to main +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784968948 +0100 checkout: moving from main to main +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784971645 +0100 checkout: moving from main to main +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 ba2801a8f85849aa4f978f8bd27561f06582d083 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1785078356 +0100 commit: chore: update guix.scm from squisher-corpus +ba2801a8f85849aa4f978f8bd27561f06582d083 3a50d74431cb5d2e61b356e54680ab7b6593f34b Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1785078359 +0100 commit: chore: update guix.scm from squisher-corpus +3a50d74431cb5d2e61b356e54680ab7b6593f34b 3a50d74431cb5d2e61b356e54680ab7b6593f34b Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1785303266 +0100 reset: moving to HEAD +3a50d74431cb5d2e61b356e54680ab7b6593f34b 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786549824 +0100 commit: fix(ci): remove timeout-minutes from reusable workflow calls in wordpress-tools +0186e48f3665c512c6912d64a3ffb31e441abee8 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582089 +0100 reset: moving to HEAD +0186e48f3665c512c6912d64a3ffb31e441abee8 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582089 +0100 checkout: moving from main to main +0186e48f3665c512c6912d64a3ffb31e441abee8 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582091 +0100 checkout: moving from main to fix/ci-426-squisher-cleanup +0186e48f3665c512c6912d64a3ffb31e441abee8 dff3ae3a658f6e7f5de3d72894c41edf97b6f2d4 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582091 +0100 commit: fix(ci): remove erroneous squisher-corpus guix.scm placeholder +dff3ae3a658f6e7f5de3d72894c41edf97b6f2d4 dff3ae3a658f6e7f5de3d72894c41edf97b6f2d4 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582093 +0100 reset: moving to HEAD +dff3ae3a658f6e7f5de3d72894c41edf97b6f2d4 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582093 +0100 checkout: moving from fix/ci-426-squisher-cleanup to main +0186e48f3665c512c6912d64a3ffb31e441abee8 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582095 +0100 checkout: moving from main to fix/ci-426-squisher-cleanup +0186e48f3665c512c6912d64a3ffb31e441abee8 f6e5fd871b7dc9c71ffcd7f109407db8b56fe044 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582095 +0100 commit: fix(ci): remove erroneous squisher-corpus guix.scm placeholder +f6e5fd871b7dc9c71ffcd7f109407db8b56fe044 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582097 +0100 checkout: moving from fix/ci-426-squisher-cleanup to main +0186e48f3665c512c6912d64a3ffb31e441abee8 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606845 +0100 checkout: moving from main to main +0186e48f3665c512c6912d64a3ffb31e441abee8 0df8626d1a8f51755918e93e65b2a57555594873 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606845 +0100 reset: moving to origin/main +0df8626d1a8f51755918e93e65b2a57555594873 0df8626d1a8f51755918e93e65b2a57555594873 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606847 +0100 reset: moving to origin/main +0df8626d1a8f51755918e93e65b2a57555594873 0df8626d1a8f51755918e93e65b2a57555594873 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606849 +0100 checkout: moving from main to fix/squisher-corpus-cleanup +0df8626d1a8f51755918e93e65b2a57555594873 22d082cc0a936e88381bb9fb90d1f8a5a849bdb7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606857 +0100 commit: chore: remove squisher-corpus guix.scm placeholders +22d082cc0a936e88381bb9fb90d1f8a5a849bdb7 04aff9902c1b74ff15b6fb751dcf0589585ba2cf Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786726459 +0100 commit: chore(ci): bump standards reusable pins to fix Bug A and Bug B (#426) +04aff9902c1b74ff15b6fb751dcf0589585ba2cf 7fc7e8f7f7cbdef3d074f67861adadf60bf6ef02 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786727018 +0100 commit: chore(ci): bump standards reusable pins to 5b1d0022 (#426) diff --git a/.git_corrupted/logs/refs/heads/fix/squisher-corpus-cleanup b/.git_corrupted/logs/refs/heads/fix/squisher-corpus-cleanup new file mode 100644 index 0000000..e80ee03 --- /dev/null +++ b/.git_corrupted/logs/refs/heads/fix/squisher-corpus-cleanup @@ -0,0 +1,4 @@ +0000000000000000000000000000000000000000 0df8626d1a8f51755918e93e65b2a57555594873 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606849 +0100 branch: Created from HEAD +0df8626d1a8f51755918e93e65b2a57555594873 22d082cc0a936e88381bb9fb90d1f8a5a849bdb7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606857 +0100 commit: chore: remove squisher-corpus guix.scm placeholders +22d082cc0a936e88381bb9fb90d1f8a5a849bdb7 04aff9902c1b74ff15b6fb751dcf0589585ba2cf Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786726459 +0100 commit: chore(ci): bump standards reusable pins to fix Bug A and Bug B (#426) +04aff9902c1b74ff15b6fb751dcf0589585ba2cf 7fc7e8f7f7cbdef3d074f67861adadf60bf6ef02 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786727018 +0100 commit: chore(ci): bump standards reusable pins to 5b1d0022 (#426) diff --git a/.git_corrupted/logs/refs/heads/main b/.git_corrupted/logs/refs/heads/main new file mode 100644 index 0000000..6c29974 --- /dev/null +++ b/.git_corrupted/logs/refs/heads/main @@ -0,0 +1,10 @@ +0000000000000000000000000000000000000000 8f84396fbb3bd450e3277a028090b0c00bf27930 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1783945991 +0100 clone: from https://github.com/hyperpolymath/wordpress-tools.git +8f84396fbb3bd450e3277a028090b0c00bf27930 2c5ff887d1ca039bb3eaf5a1aecab507e3c765b6 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784404442 +0100 commit: sweep2: add config files (mise.toml) +2c5ff887d1ca039bb3eaf5a1aecab507e3c765b6 eb529e4b39a04bab6bb96ec4b6e017f47fdd5bfc Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784408134 +0100 commit: sweep3: add license files and SPDX identifiers +eb529e4b39a04bab6bb96ec4b6e017f47fdd5bfc f52071964cc6291ad8ce7e78cfda825967c3a5d7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784411548 +0100 commit: sweep4: add C-A-G-M files +f52071964cc6291ad8ce7e78cfda825967c3a5d7 d9e4940742772b36794b1bb3703a8c8ea52443bf Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830930 +0100 pull --rebase origin main (finish): refs/heads/main onto b318061c8e10fde0e3e3c796b36cd7156a8a6343 +d9e4940742772b36794b1bb3703a8c8ea52443bf 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830939 +0100 pull origin main: Fast-forward +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 ba2801a8f85849aa4f978f8bd27561f06582d083 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1785078356 +0100 commit: chore: update guix.scm from squisher-corpus +ba2801a8f85849aa4f978f8bd27561f06582d083 3a50d74431cb5d2e61b356e54680ab7b6593f34b Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1785078359 +0100 commit: chore: update guix.scm from squisher-corpus +3a50d74431cb5d2e61b356e54680ab7b6593f34b 0186e48f3665c512c6912d64a3ffb31e441abee8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786549824 +0100 commit: fix(ci): remove timeout-minutes from reusable workflow calls in wordpress-tools +0186e48f3665c512c6912d64a3ffb31e441abee8 0df8626d1a8f51755918e93e65b2a57555594873 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786606845 +0100 reset: moving to origin/main diff --git a/.git_corrupted/logs/refs/remotes/origin/HEAD b/.git_corrupted/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..19ec0bb --- /dev/null +++ b/.git_corrupted/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 8f84396fbb3bd450e3277a028090b0c00bf27930 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1783945991 +0100 clone: from https://github.com/hyperpolymath/wordpress-tools.git diff --git a/.git_corrupted/logs/refs/remotes/origin/main b/.git_corrupted/logs/refs/remotes/origin/main new file mode 100644 index 0000000..2a934b3 --- /dev/null +++ b/.git_corrupted/logs/refs/remotes/origin/main @@ -0,0 +1,4 @@ +8f84396fbb3bd450e3277a028090b0c00bf27930 12714a3f9bcea751c95751d991029dfc49bf34f8 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784534100 +0100 fetch --all --prune: fast-forward +12714a3f9bcea751c95751d991029dfc49bf34f8 b318061c8e10fde0e3e3c796b36cd7156a8a6343 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830929 +0100 fetch origin: fast-forward +b318061c8e10fde0e3e3c796b36cd7156a8a6343 59d8d0bd1eec9076cfe2429fdffef25a707c36e7 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1784830939 +0100 pull origin main: fast-forward +59d8d0bd1eec9076cfe2429fdffef25a707c36e7 0df8626d1a8f51755918e93e65b2a57555594873 Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> 1786582090 +0100 pull origin main: fast-forward diff --git a/.git_corrupted/objects/00/49892043f721db2e09147448a2b59c34c8cfa3 b/.git_corrupted/objects/00/49892043f721db2e09147448a2b59c34c8cfa3 new file mode 100644 index 0000000..635cd50 Binary files /dev/null and b/.git_corrupted/objects/00/49892043f721db2e09147448a2b59c34c8cfa3 differ diff --git a/.git_corrupted/objects/01/86e48f3665c512c6912d64a3ffb31e441abee8 b/.git_corrupted/objects/01/86e48f3665c512c6912d64a3ffb31e441abee8 new file mode 100644 index 0000000..3dbbb67 Binary files /dev/null and b/.git_corrupted/objects/01/86e48f3665c512c6912d64a3ffb31e441abee8 differ diff --git a/.git_corrupted/objects/02/c0e6398ef0d7307cb5c7a6d0a9f5140457b91a b/.git_corrupted/objects/02/c0e6398ef0d7307cb5c7a6d0a9f5140457b91a new file mode 100644 index 0000000..d545ffb Binary files /dev/null and b/.git_corrupted/objects/02/c0e6398ef0d7307cb5c7a6d0a9f5140457b91a differ diff --git a/.git_corrupted/objects/04/aff9902c1b74ff15b6fb751dcf0589585ba2cf b/.git_corrupted/objects/04/aff9902c1b74ff15b6fb751dcf0589585ba2cf new file mode 100644 index 0000000..f27427b Binary files /dev/null and b/.git_corrupted/objects/04/aff9902c1b74ff15b6fb751dcf0589585ba2cf differ diff --git a/.git_corrupted/objects/0c/7b4fcc1334d3ccf7ee283450bfaa556eaa3b9d b/.git_corrupted/objects/0c/7b4fcc1334d3ccf7ee283450bfaa556eaa3b9d new file mode 100644 index 0000000..d0522da Binary files /dev/null and b/.git_corrupted/objects/0c/7b4fcc1334d3ccf7ee283450bfaa556eaa3b9d differ diff --git a/.git_corrupted/objects/0d/f8626d1a8f51755918e93e65b2a57555594873 b/.git_corrupted/objects/0d/f8626d1a8f51755918e93e65b2a57555594873 new file mode 100644 index 0000000..dff63ae Binary files /dev/null and b/.git_corrupted/objects/0d/f8626d1a8f51755918e93e65b2a57555594873 differ diff --git a/.git_corrupted/objects/0d/fb27a17843216d6a49eccb696e00c664679238 b/.git_corrupted/objects/0d/fb27a17843216d6a49eccb696e00c664679238 new file mode 100644 index 0000000..f7aad8c Binary files /dev/null and b/.git_corrupted/objects/0d/fb27a17843216d6a49eccb696e00c664679238 differ diff --git a/.git_corrupted/objects/12/4618e43ecffea021f96b3eb857cd2e496477e7 b/.git_corrupted/objects/12/4618e43ecffea021f96b3eb857cd2e496477e7 new file mode 100644 index 0000000..c71c58d Binary files /dev/null and b/.git_corrupted/objects/12/4618e43ecffea021f96b3eb857cd2e496477e7 differ diff --git a/.git_corrupted/objects/12/714a3f9bcea751c95751d991029dfc49bf34f8 b/.git_corrupted/objects/12/714a3f9bcea751c95751d991029dfc49bf34f8 new file mode 100644 index 0000000..77a9d0f Binary files /dev/null and b/.git_corrupted/objects/12/714a3f9bcea751c95751d991029dfc49bf34f8 differ diff --git a/.git_corrupted/objects/12/93a7e235b8680fa66ffd49ec009d8689db1192 b/.git_corrupted/objects/12/93a7e235b8680fa66ffd49ec009d8689db1192 new file mode 100644 index 0000000..1c61ee2 Binary files /dev/null and b/.git_corrupted/objects/12/93a7e235b8680fa66ffd49ec009d8689db1192 differ diff --git a/.git_corrupted/objects/13/f630421b0fb181e6763d4db7d8e5ad8e3d760d b/.git_corrupted/objects/13/f630421b0fb181e6763d4db7d8e5ad8e3d760d new file mode 100644 index 0000000..46061cb Binary files /dev/null and b/.git_corrupted/objects/13/f630421b0fb181e6763d4db7d8e5ad8e3d760d differ diff --git a/.git_corrupted/objects/18/c26e3ffc762fdf0ba95d21106bf47dd044f752 b/.git_corrupted/objects/18/c26e3ffc762fdf0ba95d21106bf47dd044f752 new file mode 100644 index 0000000..99d1f6d Binary files /dev/null and b/.git_corrupted/objects/18/c26e3ffc762fdf0ba95d21106bf47dd044f752 differ diff --git a/.git_corrupted/objects/19/8a841281ef23d471dfcd568599863f67446f6d b/.git_corrupted/objects/19/8a841281ef23d471dfcd568599863f67446f6d new file mode 100644 index 0000000..ff92f23 Binary files /dev/null and b/.git_corrupted/objects/19/8a841281ef23d471dfcd568599863f67446f6d differ diff --git a/.git_corrupted/objects/1b/ee4e72abef1ebd2848c09ccefcea10bf1a8232 b/.git_corrupted/objects/1b/ee4e72abef1ebd2848c09ccefcea10bf1a8232 new file mode 100644 index 0000000..f0d61d8 Binary files /dev/null and b/.git_corrupted/objects/1b/ee4e72abef1ebd2848c09ccefcea10bf1a8232 differ diff --git a/.git_corrupted/objects/20/379cf954fed27719965639a1eaa999248deb6b b/.git_corrupted/objects/20/379cf954fed27719965639a1eaa999248deb6b new file mode 100644 index 0000000..6e5f92d Binary files /dev/null and b/.git_corrupted/objects/20/379cf954fed27719965639a1eaa999248deb6b differ diff --git a/.git_corrupted/objects/22/040f3989cbf841dc35adf4c718cd54a087deb6 b/.git_corrupted/objects/22/040f3989cbf841dc35adf4c718cd54a087deb6 new file mode 100644 index 0000000..bd10eaf Binary files /dev/null and b/.git_corrupted/objects/22/040f3989cbf841dc35adf4c718cd54a087deb6 differ diff --git a/.git_corrupted/objects/22/d082cc0a936e88381bb9fb90d1f8a5a849bdb7 b/.git_corrupted/objects/22/d082cc0a936e88381bb9fb90d1f8a5a849bdb7 new file mode 100644 index 0000000..4af527c --- /dev/null +++ b/.git_corrupted/objects/22/d082cc0a936e88381bb9fb90d1f8a5a849bdb7 @@ -0,0 +1,2 @@ +xRn@~J}D;QqjCqpq|}DUi;gn;3'u] /CS jېk&)hF.4wt[OM-PK;hciVNIltj@ = o谧 ^ʞomcJS ]٩Nc]/7c*gv,KƒJT T1+Pe_x6_]zxQ81 ֱʮIYn&yb&\5mGv|}FpL2[!uF=G,S$otlkΣ [],$| nO)X%w%m'0Us2X|FϢ!, =& +71?Xk(3A͏2޵c˱z-9Ų0{rڌ-.o>1CNMNjhZT z$6c_ZA(U?t*-{,e (X \ No newline at end of file diff --git a/.git_corrupted/objects/23/b0653c2f885e8cf535259cc920403798364e6c b/.git_corrupted/objects/23/b0653c2f885e8cf535259cc920403798364e6c new file mode 100644 index 0000000..125eaeb Binary files /dev/null and b/.git_corrupted/objects/23/b0653c2f885e8cf535259cc920403798364e6c differ diff --git a/.git_corrupted/objects/25/2b39144d1004afe210792e7f9fb9c692661822 b/.git_corrupted/objects/25/2b39144d1004afe210792e7f9fb9c692661822 new file mode 100644 index 0000000..d2aea34 Binary files /dev/null and b/.git_corrupted/objects/25/2b39144d1004afe210792e7f9fb9c692661822 differ diff --git a/.git_corrupted/objects/27/c350af78ddfcd0f08f424788f0df2649753a54 b/.git_corrupted/objects/27/c350af78ddfcd0f08f424788f0df2649753a54 new file mode 100644 index 0000000..98cef75 Binary files /dev/null and b/.git_corrupted/objects/27/c350af78ddfcd0f08f424788f0df2649753a54 differ diff --git a/.git_corrupted/objects/29/384dfaec9ee681c75a7551ceec769dd9b4bd48 b/.git_corrupted/objects/29/384dfaec9ee681c75a7551ceec769dd9b4bd48 new file mode 100644 index 0000000..c6d3434 Binary files /dev/null and b/.git_corrupted/objects/29/384dfaec9ee681c75a7551ceec769dd9b4bd48 differ diff --git a/.git_corrupted/objects/29/b826eda5677ebf9a0aedc2272cc1cc8c5a0104 b/.git_corrupted/objects/29/b826eda5677ebf9a0aedc2272cc1cc8c5a0104 new file mode 100644 index 0000000..3796d99 Binary files /dev/null and b/.git_corrupted/objects/29/b826eda5677ebf9a0aedc2272cc1cc8c5a0104 differ diff --git a/.git_corrupted/objects/2b/d2b1867d957533fcf5f6d949b1cc34f5d66e9c b/.git_corrupted/objects/2b/d2b1867d957533fcf5f6d949b1cc34f5d66e9c new file mode 100644 index 0000000..c280474 Binary files /dev/null and b/.git_corrupted/objects/2b/d2b1867d957533fcf5f6d949b1cc34f5d66e9c differ diff --git a/.git_corrupted/objects/2c/5ff887d1ca039bb3eaf5a1aecab507e3c765b6 b/.git_corrupted/objects/2c/5ff887d1ca039bb3eaf5a1aecab507e3c765b6 new file mode 100644 index 0000000..8cecda3 Binary files /dev/null and b/.git_corrupted/objects/2c/5ff887d1ca039bb3eaf5a1aecab507e3c765b6 differ diff --git a/.git_corrupted/objects/2c/b0fb11a7b265d542c78ef51bcd12814d15a644 b/.git_corrupted/objects/2c/b0fb11a7b265d542c78ef51bcd12814d15a644 new file mode 100644 index 0000000..c302ca9 Binary files /dev/null and b/.git_corrupted/objects/2c/b0fb11a7b265d542c78ef51bcd12814d15a644 differ diff --git a/.git_corrupted/objects/2d/58298e6eda10e7204abb52722efbc840db2390 b/.git_corrupted/objects/2d/58298e6eda10e7204abb52722efbc840db2390 new file mode 100644 index 0000000..0904171 Binary files /dev/null and b/.git_corrupted/objects/2d/58298e6eda10e7204abb52722efbc840db2390 differ diff --git a/.git_corrupted/objects/2d/aaef0731ef9f08aab3c140e6d357a3df68c336 b/.git_corrupted/objects/2d/aaef0731ef9f08aab3c140e6d357a3df68c336 new file mode 100644 index 0000000..a9e8ec4 Binary files /dev/null and b/.git_corrupted/objects/2d/aaef0731ef9f08aab3c140e6d357a3df68c336 differ diff --git a/.git_corrupted/objects/2f/c6e83bc15847e1387947c30d8e1383c1fe01bd b/.git_corrupted/objects/2f/c6e83bc15847e1387947c30d8e1383c1fe01bd new file mode 100644 index 0000000..b22df8b Binary files /dev/null and b/.git_corrupted/objects/2f/c6e83bc15847e1387947c30d8e1383c1fe01bd differ diff --git a/.git_corrupted/objects/2f/fc14323aa16e263014afd831eef2a533017f83 b/.git_corrupted/objects/2f/fc14323aa16e263014afd831eef2a533017f83 new file mode 100644 index 0000000..278c670 --- /dev/null +++ b/.git_corrupted/objects/2f/fc14323aa16e263014afd831eef2a533017f83 @@ -0,0 +1 @@ +x]RM0_1RXim .HTQH!Ǚ4ffljJSqgCۇW 8?~FXG3>eSy尅jGo+)YwBHy=")T:xs8RHS h☺)` ^^`Aa6( Y#%&$gME( %T}+tfG[2,JLq@2GE1Me鿊!/* ;U 8p< ٩8Dz^-խ.>y9ly%"3<;]of z{ ݀C3w6pn-3h?D_ \ No newline at end of file diff --git a/.git_corrupted/objects/30/7f524f77a031c4c0bfa534c2c9cc789646575d b/.git_corrupted/objects/30/7f524f77a031c4c0bfa534c2c9cc789646575d new file mode 100644 index 0000000..86c98dd Binary files /dev/null and b/.git_corrupted/objects/30/7f524f77a031c4c0bfa534c2c9cc789646575d differ diff --git a/.git_corrupted/objects/37/f64117fb58b3cbb8889bec2ad4d3f6b2dd30eb b/.git_corrupted/objects/37/f64117fb58b3cbb8889bec2ad4d3f6b2dd30eb new file mode 100644 index 0000000..9dd7115 --- /dev/null +++ b/.git_corrupted/objects/37/f64117fb58b3cbb8889bec2ad4d3f6b2dd30eb @@ -0,0 +1,2 @@ +xmn@{O1.zTڴh"y=i]g$SABwN|3[ulx5k#6>(uJtL(LumHn \~sJM& Otcz3UxY;d?Fl:{xht4&ch7jDh|D,mٳSq728籏+]/vG;8!X\*57 ћ^x< {CZ}L' KC-i݁m>,:Ι.d|JY"wy/|!O6m$)R] =Hm:"5=cޏ/!H׉̢/ YX%Le߇uPKkcM1xj2Ins|04) @l|8wqM+6i0gkGb@ylj(:ցP^w +]a*)P60bS b4}GYy!g +:j{Y6+Z':;;{d^IyteG"Se3;m-'۞MeS"oA x +YXi79i{+P=r{x%(_VlOy?y`nx.C'8 U㰖:~QY8%QRD yB!BhVn4S0дG]xd˹JsnZ+2Sɹ})-c]<r7g&ol ] y8f=S~cic>>춟^ȾԨ\hJg"S|v( : L2{.Ŷ _p%:%x~fB+A%hc o]Q}#٫2tJ+6Tوf29AyUL[ZCt-$|ojlQ G;7~ ѽj6"5\%1 x'L(?\Ko͇+_mB1q~d 諾c&\"gb6XMT|rrV57ɺ6n æ-!44MaUՈ.DT bEX#_zqS!U4zJM#m`!+0v8F׃`IɜRw2H;A':VHi(N0)xNݒOO7A/33''vГ)~gri7$ \ No newline at end of file diff --git a/.git_corrupted/objects/d1/8c792a7ef4e9be36f562c6d5b8bc8da5810860 b/.git_corrupted/objects/d1/8c792a7ef4e9be36f562c6d5b8bc8da5810860 new file mode 100644 index 0000000..b696e3b Binary files /dev/null and b/.git_corrupted/objects/d1/8c792a7ef4e9be36f562c6d5b8bc8da5810860 differ diff --git a/.git_corrupted/objects/d4/ae067a0fbe2b9b299b2547115b9bab953101b1 b/.git_corrupted/objects/d4/ae067a0fbe2b9b299b2547115b9bab953101b1 new file mode 100644 index 0000000..9880ca1 Binary files /dev/null and b/.git_corrupted/objects/d4/ae067a0fbe2b9b299b2547115b9bab953101b1 differ diff --git a/.git_corrupted/objects/d5/7f1d9ce98e45e19ae8059ffda0616877977451 b/.git_corrupted/objects/d5/7f1d9ce98e45e19ae8059ffda0616877977451 new file mode 100644 index 0000000..e99b0f6 Binary files /dev/null and b/.git_corrupted/objects/d5/7f1d9ce98e45e19ae8059ffda0616877977451 differ diff --git a/.git_corrupted/objects/d7/3467198f7ab2871e5ceff471eb5cdcca4838c3 b/.git_corrupted/objects/d7/3467198f7ab2871e5ceff471eb5cdcca4838c3 new file mode 100644 index 0000000..75be045 Binary files /dev/null and b/.git_corrupted/objects/d7/3467198f7ab2871e5ceff471eb5cdcca4838c3 differ diff --git a/.git_corrupted/objects/d9/e4940742772b36794b1bb3703a8c8ea52443bf b/.git_corrupted/objects/d9/e4940742772b36794b1bb3703a8c8ea52443bf new file mode 100644 index 0000000..409db0d Binary files /dev/null and b/.git_corrupted/objects/d9/e4940742772b36794b1bb3703a8c8ea52443bf differ diff --git a/.git_corrupted/objects/dc/4cf64d83e67c369fbc95f45f49927f6d018f48 b/.git_corrupted/objects/dc/4cf64d83e67c369fbc95f45f49927f6d018f48 new file mode 100644 index 0000000..d8a8760 Binary files /dev/null and b/.git_corrupted/objects/dc/4cf64d83e67c369fbc95f45f49927f6d018f48 differ diff --git a/.git_corrupted/objects/df/c5a53ce53fa970b8af62267fef55560feb3a1a b/.git_corrupted/objects/df/c5a53ce53fa970b8af62267fef55560feb3a1a new file mode 100644 index 0000000..344017e Binary files /dev/null and b/.git_corrupted/objects/df/c5a53ce53fa970b8af62267fef55560feb3a1a differ diff --git a/.git_corrupted/objects/df/f3ae3a658f6e7f5de3d72894c41edf97b6f2d4 b/.git_corrupted/objects/df/f3ae3a658f6e7f5de3d72894c41edf97b6f2d4 new file mode 100644 index 0000000..2491311 Binary files /dev/null and b/.git_corrupted/objects/df/f3ae3a658f6e7f5de3d72894c41edf97b6f2d4 differ diff --git a/.git_corrupted/objects/e2/7364c75f5b1f55c0d16246cf6d037c34616ec6 b/.git_corrupted/objects/e2/7364c75f5b1f55c0d16246cf6d037c34616ec6 new file mode 100644 index 0000000..c3658c1 Binary files /dev/null and b/.git_corrupted/objects/e2/7364c75f5b1f55c0d16246cf6d037c34616ec6 differ diff --git a/.git_corrupted/objects/e2/ae0832e4fba53de00e1cdc8d62fe6c1ef63018 b/.git_corrupted/objects/e2/ae0832e4fba53de00e1cdc8d62fe6c1ef63018 new file mode 100644 index 0000000..a288a69 Binary files /dev/null and b/.git_corrupted/objects/e2/ae0832e4fba53de00e1cdc8d62fe6c1ef63018 differ diff --git a/.git_corrupted/objects/e4/f7c077805cbf5ae2b77c132195cd56e2cd294e b/.git_corrupted/objects/e4/f7c077805cbf5ae2b77c132195cd56e2cd294e new file mode 100644 index 0000000..44825a7 --- /dev/null +++ b/.git_corrupted/objects/e4/f7c077805cbf5ae2b77c132195cd56e2cd294e @@ -0,0 +1,2 @@ +x]; +0Sײi@.>]])Rya`eA ӊetPd2}M}(sAF#WXPc_+o:!խ$> Npwa29ۘbkVH  G \ No newline at end of file diff --git a/.git_corrupted/objects/e6/94f676c6eaaa667c05fc61189e866be783c90e b/.git_corrupted/objects/e6/94f676c6eaaa667c05fc61189e866be783c90e new file mode 100644 index 0000000..e64f4ad --- /dev/null +++ b/.git_corrupted/objects/e6/94f676c6eaaa667c05fc61189e866be783c90e @@ -0,0 +1,5 @@ +xTrFͳkb/Fp6ŀ1k-^R#|IZ*N^3%Q_N9݉s BNG#4D} d,~ܠreQ78ctN,f cq x7[sְpR—~DQ>h +-9}--R`!p2n%:vXAGT-XYfN'n6z߃{>g|XWejs_-jVy;.wϓhaÃxm_<eGe-tBfyF|bڽ9j76|yXm=z~wX߮R xӋwEpb5M0re"v^ED@jtB)ltܔC NK̅*ZȌ`iy,fIKi=ox=`сVt!rKzqw)̞`*yC HUWU + +P'#3Ld @i=,֐?QJXǕ8bxD9@Q5ppՂSnR o4|GfK<=x)&#eU!RMx] +VQW^=iIˉQz-;* 6f<΅1bb5mBЈL%{qZIGT EkI2R>}Ԍx90#J+|"թTcɹPGVWD#qa4D"WeGQ mG4 6Xf&ݏA=#c FB=:kφ \ No newline at end of file diff --git a/.git_corrupted/objects/e7/562979a2644d221adf69d38130b8390f546eca b/.git_corrupted/objects/e7/562979a2644d221adf69d38130b8390f546eca new file mode 100644 index 0000000..46d565a Binary files /dev/null and b/.git_corrupted/objects/e7/562979a2644d221adf69d38130b8390f546eca differ diff --git a/.git_corrupted/objects/eb/529e4b39a04bab6bb96ec4b6e017f47fdd5bfc b/.git_corrupted/objects/eb/529e4b39a04bab6bb96ec4b6e017f47fdd5bfc new file mode 100644 index 0000000..8dd2489 --- /dev/null +++ b/.git_corrupted/objects/eb/529e4b39a04bab6bb96ec4b6e017f47fdd5bfc @@ -0,0 +1,6 @@ +xMo0_1[ +)(Is@h@$M~}=}%Ky=p(ZpU (Ra!me"&slC33R3e Cae:)L7< d(C;hǶMرW +^{VB{۱<׵K=TVV +ky&P5Mݥ :hWF-A^MM X,a1%r59M+]>f +~*zݬ?=Ge._OV|}孾p'[Z=/6wjwClucٓ\pLed&Nu9?IvO;$W3HsF;`i +X6Y!V[(nX) E*&a]pSu7[?u1Ɗp \ No newline at end of file diff --git a/.git_corrupted/objects/f0/0f388de5bc77d5622bfcd8a2e391e59d235862 b/.git_corrupted/objects/f0/0f388de5bc77d5622bfcd8a2e391e59d235862 new file mode 100644 index 0000000..d7c7035 Binary files /dev/null and b/.git_corrupted/objects/f0/0f388de5bc77d5622bfcd8a2e391e59d235862 differ diff --git a/.git_corrupted/objects/f0/2c0e17cb2de83eef0fcb47961d8ee8f8125253 b/.git_corrupted/objects/f0/2c0e17cb2de83eef0fcb47961d8ee8f8125253 new file mode 100644 index 0000000..50ab2f8 Binary files /dev/null and b/.git_corrupted/objects/f0/2c0e17cb2de83eef0fcb47961d8ee8f8125253 differ diff --git a/.git_corrupted/objects/f2/c1345f1cf96fe9959dd8ea60d6bc194d50b9de b/.git_corrupted/objects/f2/c1345f1cf96fe9959dd8ea60d6bc194d50b9de new file mode 100644 index 0000000..91fe06e Binary files /dev/null and b/.git_corrupted/objects/f2/c1345f1cf96fe9959dd8ea60d6bc194d50b9de differ diff --git a/.git_corrupted/objects/f5/2071964cc6291ad8ce7e78cfda825967c3a5d7 b/.git_corrupted/objects/f5/2071964cc6291ad8ce7e78cfda825967c3a5d7 new file mode 100644 index 0000000..83a10f5 Binary files /dev/null and b/.git_corrupted/objects/f5/2071964cc6291ad8ce7e78cfda825967c3a5d7 differ diff --git a/.git_corrupted/objects/f6/87f705928ac58dc8613dcd933f67a4b360cdb2 b/.git_corrupted/objects/f6/87f705928ac58dc8613dcd933f67a4b360cdb2 new file mode 100644 index 0000000..0dab352 Binary files /dev/null and b/.git_corrupted/objects/f6/87f705928ac58dc8613dcd933f67a4b360cdb2 differ diff --git a/.git_corrupted/objects/f6/e5fd871b7dc9c71ffcd7f109407db8b56fe044 b/.git_corrupted/objects/f6/e5fd871b7dc9c71ffcd7f109407db8b56fe044 new file mode 100644 index 0000000..d422ee6 Binary files /dev/null and b/.git_corrupted/objects/f6/e5fd871b7dc9c71ffcd7f109407db8b56fe044 differ diff --git a/.git_corrupted/objects/f8/8d77932dccc57d32575b8de6328e1e1bfeccf2 b/.git_corrupted/objects/f8/8d77932dccc57d32575b8de6328e1e1bfeccf2 new file mode 100644 index 0000000..c62f1d2 Binary files /dev/null and b/.git_corrupted/objects/f8/8d77932dccc57d32575b8de6328e1e1bfeccf2 differ diff --git a/.git_corrupted/objects/fc/dc4b653527750c7cb6047deaa7f31e844a209e b/.git_corrupted/objects/fc/dc4b653527750c7cb6047deaa7f31e844a209e new file mode 100644 index 0000000..16e8f3d Binary files /dev/null and b/.git_corrupted/objects/fc/dc4b653527750c7cb6047deaa7f31e844a209e differ diff --git a/.git_corrupted/objects/fd/6cd1c70772a50e5173a5228fdc607fdf1a89ba b/.git_corrupted/objects/fd/6cd1c70772a50e5173a5228fdc607fdf1a89ba new file mode 100644 index 0000000..0e4976f Binary files /dev/null and b/.git_corrupted/objects/fd/6cd1c70772a50e5173a5228fdc607fdf1a89ba differ diff --git a/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.idx b/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.idx new file mode 100644 index 0000000..e2f4243 Binary files /dev/null and b/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.idx differ diff --git a/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.pack b/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.pack new file mode 100644 index 0000000..4dc9c04 Binary files /dev/null and b/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.pack differ diff --git a/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.rev b/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.rev new file mode 100644 index 0000000..2035682 Binary files /dev/null and b/.git_corrupted/objects/pack/pack-85c00c545d3ad8eeafb36f1526d6166f255fa2c5.rev differ diff --git a/.git_corrupted/packed-refs b/.git_corrupted/packed-refs new file mode 100644 index 0000000..178a5c8 --- /dev/null +++ b/.git_corrupted/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +8f84396fbb3bd450e3277a028090b0c00bf27930 refs/remotes/origin/main diff --git a/.git_corrupted/refs/heads/fix/squisher-corpus-cleanup b/.git_corrupted/refs/heads/fix/squisher-corpus-cleanup new file mode 100644 index 0000000..ed2d4f6 --- /dev/null +++ b/.git_corrupted/refs/heads/fix/squisher-corpus-cleanup @@ -0,0 +1 @@ +7fc7e8f7f7cbdef3d074f67861adadf60bf6ef02 diff --git a/.git_corrupted/refs/heads/main b/.git_corrupted/refs/heads/main new file mode 100644 index 0000000..a25826b --- /dev/null +++ b/.git_corrupted/refs/heads/main @@ -0,0 +1 @@ +0df8626d1a8f51755918e93e65b2a57555594873 diff --git a/.git_corrupted/refs/remotes/origin/HEAD b/.git_corrupted/refs/remotes/origin/HEAD new file mode 100644 index 0000000..4b0a875 --- /dev/null +++ b/.git_corrupted/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/main diff --git a/.git_corrupted/refs/remotes/origin/main b/.git_corrupted/refs/remotes/origin/main new file mode 100644 index 0000000..a25826b --- /dev/null +++ b/.git_corrupted/refs/remotes/origin/main @@ -0,0 +1 @@ +0df8626d1a8f51755918e93e65b2a57555594873 diff --git a/.github/funding.yml b/.github/funding.yml index e4f7c07..dc1b7fa 100644 --- a/.github/funding.yml +++ b/.github/funding.yml @@ -1,4 +1,18 @@ -# Funding Configuration -# See: https://docs.github.com/en/repositories/managing-your-repositorys-custom-fields/displaying-a-sponsor-button-in-your-repository +# SPDX-License-Identifier: MPL-2.0 for code +# SPDX-License-Identifier: CC-BY-SA-4.0 for documentation +# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell -github: metadatastician +# These are supported funding model platforms + +buy_me_a_coffee: jonathan.jewell +community_bridge: jonathan-jewell +github: hyperpolymath +indieweb: +issuehunt: hyperpolymath +ko_fi: hyperpolymath +lfx_crowdfunding: hyperpolymath +liberapay: hyperpolymath +open_collective: jonathan-jewell +patreon: cc_studio +polar: hyperpolymath +thanks_dev: hyperpolymath diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 6bd847d..b0b1a01 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -8,5 +8,5 @@ permissions: contents: read jobs: mirror: - uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@d135b05bfc647d0c0fbfedc7e80f37ea50f49236 + uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@5b1d00229e5e8c0c0fbfedc7e80f37ea50f49236 secrets: inherit diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..daee451 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: MPL-2.0 +name: Scorecard + +on: + schedule: + - cron: "0 0 * * 0" + push: + branches: [main, master] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + actions: read + contents: read + security-events: write + id-token: write + +jobs: + scorecard: + uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 diff --git a/.gitignore b/.gitignore index 6e9d4cb..42c74d9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,7 @@ build/ **/zig-out/ **/.zig-cache/ -# ReScript +# /lib/bs/ **/lib/bs/ /.bsb.lock @@ -70,7 +70,7 @@ htmlcov/ # Crash recovery artifacts ai-cli-crash-capture/ -# ReScript/OCaml compiler artifacts +# /OCaml compiler artifacts *.cmt *.cmti *.cmi diff --git a/.hypatia/scan-cache/fix-http-to-https.hashes b/.hypatia/scan-cache/fix-http-to-https.hashes index 97007c5..8c6fe40 100644 --- a/.hypatia/scan-cache/fix-http-to-https.hashes +++ b/.hypatia/scan-cache/fix-http-to-https.hashes @@ -128,7 +128,7 @@ a7a1c74da59515b2749edfad7f55d622502d21371181bad7a4092cd810aaa674 project-wharf/ 88ecb9ccc47795e65c2602074f5818acc255930ef11259033da8b1b091ff77b7 project-wharf/xtask/Cargo.toml 545cf7e83e034436deee63c8f12980c15038d73f3d3cef53bc4fa64d8d6871f8 praxis/SymbolicEngine/graphql/codegen.yml 662ab91d0d245b3906ff406e37565def4b5eb2c8ece2af8b5df7154aaafb7dcd praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res -2e24c96ab467b380b732630c9723f0137b43902cb0d1bf01a68209ee0faa625d sinople-theme/rescript/package.json +2e24c96ab467b380b732630c9723f0137b43902cb0d1bf01a68209ee0faa625d sinople-theme//package.json 18cf55eeb3875b9babf0aa5717fcfc9f26d27c63528523a62035ff215d42d57c project-wharf/CONTRIBUTING.md 6a4407890569476987ed966cb626970fb4a11ec722c7ca3dfa5bae5e24de9ad7 praxis/Core/db-schema/test/schema_test.exs c916775766dc77d42dd3cd84d0acca04cac9d4628de65e06b0d45c5fa14123ab journal-theme/.github/workflows/rsr-antipattern.yml @@ -225,7 +225,7 @@ cd24dc8a0fc7edfbf3372878ec303bda0358ac3e98a6c4e51334da56497de56c praxis/IMPLEME 8657714d788a7fe466af4758e442658b99f53dc157f32bfeefd7bca2e60a4041 praxis/Core/db-schema/lib/wp_praxis.ex ce63de8d730e9931378988bad66bdb78ead2d77909a31a66c001a17bf320b45f praxis/Core/db-schema/README.md d58d9aa9e89f32eed0d282cc2e88b7722df0040d44b719b486789f140c6b0d4c praxis/Core/db-schema/test/schema/symbol_test.exs -6068f74fbf2731cd3513391cb8391b1565e08713b3d48babcd373ed15efd3e88 journal-theme/rescript.json +6068f74fbf2731cd3513391cb8391b1565e08713b3d48babcd373ed15efd3e88 journal-theme/.json 5bbfcd16b0437455507dd94a701e95ea258986051dc667b8df1950f40e0679db secured/php-aegis/.github/workflows/secret-scanner.yml 9b50f2dbf9d99ce85c78124d2df4939be9583c9c9955ac67a3ddfae6679839aa plugin-conflict-mapper/RSR-GOLD-PROGRESS.md 1b1e9662b32770552f1583eb34fca9cb74378f6790b55a8bd15f64edc695bb87 sinople-theme/deno/lib/license-detector/mod.js @@ -241,7 +241,7 @@ e01aee92f7a146fd7c1a520857c81fc9705725177ab19d1b43b721cf3bc3ce69 praxis/Symboli 4541467732ba7b3fe39b898568fa2e8bf587fe5ea7552aa3f50cb7ef2cd98ab4 sinople-theme/data/indieweb-themes-catalog.json 0a9572710bdc24dbc2b4188d5531dafefd3a39e0628a913fb7c457196d772b33 secured/.github/ISSUE_TEMPLATE/feature_request.md 2908c383e9933edeae9f90d9a227fafde1b787abc5ba4ef07ee77b84ad39f7c0 praxis/Core/cli-wrapper/lib/wp_praxis_cli/dispatcher.ex -764565772926ea02a61cd8c86f3859c2a6cfdfc9a01cc2f0cb9bc41ec907d854 praxis/SymbolicEngine/dashboard/rescript.json +764565772926ea02a61cd8c86f3859c2a6cfdfc9a01cc2f0cb9bc41ec907d854 praxis/SymbolicEngine/dashboard/.json 7e3f84c1eef0d8d65f1f0e98b901a5727774fbea2ce558d69904189b5645dd6a plugin-conflict-mapper/REVERSIBILITY.md f7f92b9a273cc6a85a77bf1da84f421a1b999f2b6bd61b953be8192371805ce0 praxis/Core/db-schema/lib/wp_praxis/schema/baseline.ex 0ee333f0cb973604b72e481c2bf91bdbec416543d4f3d7ff8d1269e0ea055f35 journal-theme/entries/EXPLAINME.md @@ -296,7 +296,7 @@ aa61aebd454b0c20e4003e5effa4ef5235ed840e54037920481ce46450471feb secured/.githu a062d66844de4e399924f13739309fcd6fa478edca7a6733ba2f9bdb85b9f45d secured/.github/ISSUE_TEMPLATE/custom.md 9fbc63184ee99b6a7e42c30e72f5dd143d59ff7b3267a3de08dd9d92f59a7f90 resurrect/.github/workflows/mirror.yml bb254d9e41c632c2dfc13d2db61c3f3812957704d9e361726c046d44716f5643 journal-theme/deno.json -5b419178b45b69075c1fa170d09468e7b1a3412cb648fb0bfc541236225fa029 journal-theme/assets/rescript/src/Accessibility.res +5b419178b45b69075c1fa170d09468e7b1a3412cb648fb0bfc541236225fa029 journal-theme/assets//src/Accessibility.res d4e6401fd1f3ed0c2048c3801707c52dd72e38ddb957329aec973ce7f48e03ab praxis/SymbolicEngine/dashboard/tsconfig.json dfd4abc12f3dd924e2079b4dc4827c34a7a00719c4e7609f3eb3dd63de3577f2 project-wharf/crates/wharf-ebpf/Cargo.toml 357001769d0d5278600e55f49a57ceb5936d0001fa11563427feb5d5e049248f journal-theme/semantic/constructs/EXPLAINME.md @@ -305,7 +305,7 @@ d29d22264545bc267cd4f9a936c574fcee2198e4574a218582ab9ee42c9580f5 journal-theme/ 7ea25a0f6319526108264f2e4a2f88b9f73ae08ae481cdb05f3a44bbdfad07c5 sinople-theme/.github/dependabot.yml a69f9370d9b831399af559af4c372281dc3f775c8fcb7d081ab873c7e4ed7c49 sinople-theme/RSR_AUDIT.md 3f0cdadfaaf9b208e0e2ada01dde92bcc5922fc173d7e77f86cab78ba98cf639 praxis/Core/manifest-parser/README.md -ba64107242483a7d8828094341a0b7e98c6056de4c325c5ef03e2841351e1cd0 sinople-theme/rescript/rescript.json +ba64107242483a7d8828094341a0b7e98c6056de4c325c5ef03e2841351e1cd0 sinople-theme//.json ae77b85d2f8b7e72ba12fa38fa578679d46dbc875b6cfdec103dcfdae9a39847 resurrect/.well-known/ai.txt 08120dc50ea93392e612b0388100bf80f88b1789a274480a8933561b5832f9d5 praxis/SymbolicEngine/swarm/src/Coordinator.res eb4222b4e88d833c124974f3310a823dc0d6362fe78850915ae073e880e3c904 sinople-theme/.github/workflows/guix-nix-policy.yml @@ -347,7 +347,7 @@ edb997474c37aebcdd064f58f7b1c257af3e5bbe3886d19058d499443d44d560 secured/VERIFI 38d1ea673c098b105dde769844ac9910b95dad4a5e8633c363a53a98ddff048b secured/CONTRIBUTING.md 19e11989747095bda0ba6cb2c5cde91e05cba9ce476ab5b6ecf51e3a82ffdc32 praxis/wp_praxis_core/src/parser/mod.rs cca2ebc8e799ab6c31e1762ec874c8292d6454871a020d7585f8a18166c15d55 plugin-conflict-mapper/.github/workflows/scorecard.yml -987cfedd2a4f57ee3b9dbd1a2222c9478a4467fad98fff2df19eade8a04620f6 journal-theme/assets/rescript/src/ViewTransitions.res +987cfedd2a4f57ee3b9dbd1a2222c9478a4467fad98fff2df19eade8a04620f6 journal-theme/assets//src/ViewTransitions.res 7aa83fdf5c4f2be6a4fc01b500e81ee7dd21a8a0fa685d27b08232a603bba653 secured/.github/dependabot.yml 0df883795533c2804787c6dcbdb046927205fc5c263beb6eaf2ff4ef1bbd83e9 journal-theme/.github/workflows/rust-ci.yml 882e1b7f2e504afd23b6d4c849148a641cf08da87108e77a83136ac8919cb523 project-wharf/.claude/CLAUDE.md @@ -417,7 +417,7 @@ e974b6f09433fe760b3312664814a1b6b2f41706f8d98ef5f1c40108b816667a secured/php-ae a062d66844de4e399924f13739309fcd6fa478edca7a6733ba2f9bdb85b9f45d praxis/.github/ISSUE_TEMPLATE/custom.md 80b6e585ae7e406e4d5197277376f7150c8ad1d13ace6d853e6c4d7d2b6fa7f1 secured/php-aegis/.github/workflows/guix-nix-policy.yml 1ab179e526f305fd24c30efd0384bd232a8cf53f93b953018bbfa786f706e493 praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res.js -7c310a49947ccf24d34a8b13d42f2ab8b24baa8797ec797d18efb2f903e43eee sinople-theme/rescript/src/bindings/SemanticProcessor.res +7c310a49947ccf24d34a8b13d42f2ab8b24baa8797ec797d18efb2f903e43eee sinople-theme//src/bindings/SemanticProcessor.res 0c5beee83b86fa8d23f53a554abc7e538f2c1a6cf7961d867d8a9b3e76d1aa09 project-wharf/.github/workflows/jekyll-gh-pages.yml 4bec44dea35f5c2600a55e32b79126c6133bea7329070f62575715a871dbce3b journal-theme/contractiles/k9/README.adoc 3d6cc93a424c1d4c6488b566b7c571fdedc50bd3775860eb0244414b7026d471 sinople-theme/.github/ISSUE_TEMPLATE/bug_report.md @@ -461,7 +461,7 @@ fa9c56a2ef7e369e0fc2d4bc3d11e0a85eeb657f211a7ef4fa6098122efa98f6 praxis/Symboli b02494e4933d0612eed43e81d30d3f315a18414c49e3f689f339968546032335 secured/php-aegis/docs/wiki/IndieWeb-Security.md 96e920f4a698854187d91fb25e3bc128cc227e7801c4d9d3be968390544aeadd praxis/wp_injector/IMPLEMENTATION.md 8f14c00649e88b8ef208c355e07eb6bd9bfd7e81e633c1d640c8bdd8a378aed3 journal-theme/fuzz/Cargo.toml -db1e7610f2e2b028ba5f4f66f16df7c8dbd574b1618a2e167c331e73fec42344 journal-theme/assets/rescript/src/WebComponents.res +db1e7610f2e2b028ba5f4f66f16df7c8dbd574b1618a2e167c331e73fec42344 journal-theme/assets//src/WebComponents.res 73bcd02bb65a6782bfbe96e42c69f2c881deabadc9fe68dd0c0d9fb7ddd328d9 journal-theme/.prettierrc.json 24c6e0aef769cc8b87dff3f5ccb9d3ffe335494dc2a2c970c6739b9da2548baf journal-theme/.github/workflows/casket-pages.yml 4463751b362c132af73a8e501429c8e7c4e6f6eacf62dc657b8854080cba4d8b praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res @@ -486,7 +486,7 @@ e9d2610ca868abd017526c2868462ddce9445cb7659f3f34b5d5d1f642e587d8 secured/ROADMA d88202062b3f0fa31197a6f392623194b9b76fc56052ef6b422fa49ad4be14ed praxis/wp_injector/tests/unit_tests.rs b8988c7f5463de9a6e59ad6cce72e2f3aa773ae53fce212a8ac6cf3510caf24f plugin-conflict-mapper/.github/workflows/generator-generic-ossf-slsa3-publish.yml a34a349982d5c87af6c33501d8166d9283e434943b645009e0a3e048ed5f0103 resurrect/sdp/ziti/router.yaml -5d0c0919fe54be27105437addf7fbd00f571c015152a348037e99ee24435225d journal-theme/assets/rescript/src/WasmLoader.res +5d0c0919fe54be27105437addf7fbd00f571c015152a348037e99ee24435225d journal-theme/assets//src/WasmLoader.res fca2d338544b6a79361f1d18b85bef9f6bd278b42d541469aefa9f2474f72401 project-wharf/crates/wharf-core/src/fleet.rs e7328dd9d044be3c495a78518d945c7b6e973c8dd6d1ba220f424cefd6c2b0a1 praxis/SymbolicEngine/swarm/tsconfig.json 3d6cc93a424c1d4c6488b566b7c571fdedc50bd3775860eb0244414b7026d471 resurrect/.github/ISSUE_TEMPLATE/bug_report.md @@ -617,7 +617,7 @@ b7ffee0a120d9ea3f06c153796cb211aef64e9addb3967838f5e154d6d6cd68d praxis/Symboli 2e5bf2a1276a2742841d7267dc34b86c5f1e9f2defb17bb11f944f4a23e0d23c plugin-conflict-mapper/.gitlab-ci.yml 89f5bc1a8cc73dd16e75d7a2c87cd4de173b7b1cc837c148e2b8af65fb2ccc4b sinople-theme/deno/dev.js fb6ec08fbb032800b9e229a5ff936ad347e1c10c32c637a1323b9fedf437934d praxis/examples/video-demo/DEMO_SCRIPT.md -36e6edbefe8841e222804a68c08af15a6d8f5f55b0d26848d6ae9a44b6e439c7 praxis/SymbolicEngine/graphql/rescript.json +36e6edbefe8841e222804a68c08af15a6d8f5f55b0d26848d6ae9a44b6e439c7 praxis/SymbolicEngine/graphql/.json 4cc87d0f5143feff6d321aa20f7179d4779e8b458843658cbc53b0deda518389 praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res 50aec0a38408421970b472c9bec39731eb5f8110af5d0f46d0ab922423ec2b51 plugin-conflict-mapper/.github/workflows/quality.yml 99edfd4d7967e13c1930b5c612d5684e6cddd812fa191b6192820d279c143023 secured/php-aegis/hooks/validate-codeql.sh @@ -657,7 +657,7 @@ fa1a90e808b577cf0375150ca037e8bfd468b653473bfcd4deb19668ee8f1351 praxis/Symboli 3419ef6c54e45df46d331dd11545a51d84780bccdf67ad565a15de8204600f65 praxis/SymbolicEngine/swarm/deno.json de85a6db53b7ca70fc0cf0fafd090833abbd4d06edd465c5e00a07e9cfe93eb9 journal-theme/docker-compose.dev.yml 8d073f916200d5cbc67ac6df25252f67740b9c162fa68fc972cdc311c1ed40ea resurrect/.github/FUNDING.yml -f0ceb07bce9c3361941d86121d3b89c817ac1396cc84c1d87ab45784ea5bac42 journal-theme/assets/rescript/src/Sinople.res +f0ceb07bce9c3361941d86121d3b89c817ac1396cc84c1d87ab45784ea5bac42 journal-theme/assets//src/Sinople.res b43a5cf5aa733c4caac38cc669f9ef496cd8249597fb2047490864c849a5a2bb praxis/SymbolicEngine/dashboard/src/ConfigLoader.res.js 813b801569e3a444969746c563e97699ce241a39dde560caa10b1686dcf08f90 project-wharf/.github/workflows/secret-scanner.yml 8ae456b7ddecf0f475ecdb2326b0b02052b06c3047559871c3e03cea4f2c4513 secured/RSR_OUTLINE.adoc @@ -677,12 +677,12 @@ d1bd74163204871ea5ff0aa0017447e87c72b566c2004e4f652cb6b26fc46352 secured/.githu 0e2a50d7207af8eff5e57de038c5a9822233f0fcc9b9a87cd6ab9186a3526dd4 praxis/SymbolicEngine/dashboard/package.json d81c983281645cc9254812bea08d57a138d255019986121129d00c5e07cdcd49 journal-theme/.github/workflows/php-standards.yml a778af81d0459598636167121f3b601301cc9df2d3f4ed3574c076e5b45d6bee secured/php-aegis/README.adoc -91dbe5b2ebed794c9337c45a103ccb3ed1731633551e3a1cb7b041f03fdef74b sinople-theme/rescript/src/examples/example.res +91dbe5b2ebed794c9337c45a103ccb3ed1731633551e3a1cb7b041f03fdef74b sinople-theme//src/examples/example.res 705591add87a4c25627dbd2a047e359cf805f276ffd51b289460d014b9eed5bb praxis/SymbolicEngine/graphql/src/Server.res c7b46395eb09229197735616f1fbe06f13afafbf20421c59d2bd005638deda61 praxis/Core/cli-wrapper/mix.exs 3eb4d6177034c6a48f3c482bedb3f55ed7d59d23d1ac4fe669fb8baf999a65e8 plugin-conflict-mapper/composer.json 5a0bb4fe98b3d508459de9e666428ceeb0ba329c0e61526cc1e17562034ab444 plugin-conflict-mapper/MAINTAINERS.md -637fe1130fed2749e4254de86dd0125868af896737e5d3c41c08c428b3f05606 praxis/SymbolicEngine/swarm/rescript.json +637fe1130fed2749e4254de86dd0125868af896737e5d3c41c08c428b3f05606 praxis/SymbolicEngine/swarm/.json 4c656ea75e71a8a3179a80c4c25b1f49318f642c3f9d3a5de19e606dc3fbf1de sinople-theme/deno/main.js 8b65c140ba89d2e0e9b36f206885e40c80ee8c7fa0bfcd13e4d2d9a1e994cb37 praxis/examples/workflows/custom-post-type-setup.toml 69ebf2c67b5eabb5841dfc2b0541cfa87b93c624bd4108f045ab33e14f0aedc8 project-wharf/crates/wharf-ebpf/src/main.rs @@ -710,7 +710,7 @@ d7d4cacd8f0c420b69c08d45327fe99354c7cadba6841d5fcff49b80fb57c5b5 journal-theme/ cf72968cd8c04165970bafe975bb2e6a1081a5362eed495654f4d8c630196267 secured/php-aegis/CONTRIBUTING.adoc 6841e7284e3a267f2820e6979efcfb44306cefc1e6808420c61918e4f6face02 secured/php-aegis/hooks/validate-permissions.sh 7f57800e18a53d23d256643c72235feabfd9da736b9ad7974a04abb21489591e secured/php-aegis/.github/workflows/casket-pages.yml -fa4419bd2ae54c39179a9e29f81d8bbd70906fd2242a065ccdec92a4e389c4b7 journal-theme/.github/workflows/rescript-deno-ci.yml +fa4419bd2ae54c39179a9e29f81d8bbd70906fd2242a065ccdec92a4e389c4b7 journal-theme/.github/workflows/-deno-ci.yml b5d8d93da83a8f852be251d7dcb0da56dc9846fe1afe6f9928a81ead9376da5e project-wharf/.github/PROVEN-INTEGRATION.md d14868cf266da3838b8ef12944a4942c6c2507b1a5e44bc199205d0ad82cf818 project-wharf/crates/wharf-core/src/lib.rs c9ce020eefe04918df71520d35cc902744dbc2fe3829daab272e1ca673334ff6 journal-theme/CONTRIBUTING.md diff --git a/CHANGELOG.md b/CHANGELOG.md index dee411f..2ef5d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,7 +47,7 @@ this project aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Documentation - docs: record tech-debt audit findings (2026-05-26) (#28) -- docs(claude): add CLAUDE.md with TypeScript Exemptions table (#17) +- docs(claude): add CLAUDE.md with Exemptions table (#17) - docs: add TEST-NEEDS.md (CRG C) - docs: add EXPLAINME.adoc — prove-it file backing README claims - docs: add 0-AI-MANIFEST.a2ml (RSR compliance) @@ -57,7 +57,7 @@ this project aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0 - ci: fix nonexistent actions/upload-artifact SHA pin (#21) - ci(antipattern): fix top-level dir matching + benchmarks/lsp/bench filename allowlists (#16) - ci(antipattern): TS check reads .claude/CLAUDE.md exemption table (#15) -- ci(antipattern): broaden TS allowlist (cli/, mod.ts, lsp-server, *vscode*, deno-*) (#14) +- ci(antipattern): broaden TS allowlist (cli/, mod.ts, lsp-server, *vscode*, -*) (#14) - ci(antipattern): allowlist legit TS bridge/adapter paths (#13) ## Pre-history diff --git a/FUNDING b/FUNDING new file mode 100644 index 0000000..7e58d67 --- /dev/null +++ b/FUNDING @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MPL-2.0 for code +// SPDX-License-Identifier: CC-BY-SA-4.0 for documentation +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell + += Funding +:toc: macro +:toclevels: 2 + +This document lists the supported funding platforms for the hyperpolymath and metadatastician estates. + +== Supported Funding Platforms + +[cols="1,1",options="header"] +|=== +| Platform | Username +| Buy Me a Coffee | jonathan.jewell +| Community Bridge | jonathan-jewell +| GitHub Sponsors | hyperpolymath +| IndieWeb | +| IssueHunt | hyperpolymath +| Ko-fi | hyperpolymath +| LFX Crowdfunding | hyperpolymath +| LiberaPay | hyperpolymath +| Open Collective | jonathan-jewell +| Patreon | cc_studio +| Polar | hyperpolymath +| Thanks Dev | hyperpolymath +|=== + +== Usage + +These platforms provide financial support mechanisms for the projects within the hyperpolymath and metadatastician estates. Contributions through any of these platforms help sustain development, maintenance, and governance of the open source projects. + +For more information about contributing or sponsoring specific projects, please refer to the project's README file or contact the maintainers directly. diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..e27364c --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,60 @@ +# Governance + +## Overview + +This project is governed by the following principles and structures to ensure transparent, inclusive, and effective decision-making. + +## Roles and Responsibilities + +### Maintainers + +Maintainers are responsible for: +- Reviewing and merging pull requests +- Managing releases and versioning +- Ensuring code quality and standards +- Triaging issues and bug reports +- Community engagement and support + +### Contributors + +Contributors are expected to: +- Follow the code of conduct +- Submit well-documented pull requests +- Write tests for new functionality +- Maintain existing tests +- Update documentation as needed + +## Decision Making + +### Minor Changes +- Can be made by any maintainer +- Include bug fixes, documentation updates, dependency updates + +### Major Changes +- Require discussion in issues or pull requests +- Include new features, architectural changes, API changes +- Need approval from at least 2 maintainers + +### Breaking Changes +- Require RFC (Request for Comments) process +- Need approval from majority of maintainers +- Must include migration guide + +## Code of Conduct + +All participants are expected to follow our Code of Conduct. Violations can be reported to the maintainers. + +## Communication + +- **Issues**: For bug reports and feature requests +- **Discussions**: For questions and general discussion +- **Pull Requests**: For code contributions + +## Licensing + +All contributions are made under the terms of the repository's LICENSE file. +By submitting a pull request, you agree to license your contributions accordingly. + +--- + +*Last updated: 2026-07-18* diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..37f6411 --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,43 @@ +# Maintainers + +This file lists the current maintainers of this project. + +## Active Maintainers + +| Name | GitHub | Role | Since | +|------|--------|------|-------| +| Metadatastician | @metadatastician | Primary | Project Start | + +## Emeritus Maintainers + +None at this time. + +## Becoming a Maintainer + +To become a maintainer: + +1. Demonstrate consistent, high-quality contributions +2. Show understanding of the project's goals and architecture +3. Be active in code reviews and community discussions +4. Be nominated by an existing maintainer +5. Be approved by consensus of existing maintainers + +## Maintainer Responsibilities + +- Reviewing and merging pull requests +- Managing releases +- Triaging issues +- Enforcing code standards +- Mentoring new contributors +- Participating in decision-making + +## Maintainer Expectations + +- Respond to issues and PRs in a timely manner +- Follow the code of conduct +- Be transparent in decision-making +- Communicate clearly and respectfully + +--- + +*Last updated: 2026-07-18* diff --git a/audits/assail-classifications.a2ml b/audits/assail-classifications.a2ml new file mode 100644 index 0000000..97b4485 --- /dev/null +++ b/audits/assail-classifications.a2ml @@ -0,0 +1,108 @@ +;; SPDX-License-Identifier: MPL-2.0 +;; assail-classifications.a2ml — audited panic-attack findings for wordpress-tools. +;; +;; Read by panic-attack >= 2.5.5 (load_user_classifications): findings +;; matching (file, category) flip to suppressed = true after the kanren +;; structural pass. Entries are AUDITED-SOUND residuals with rationale. + +(assail-classifications + ;; ── CommandInjection ───────────────────────────────────────────── + (classification + (file "praxis/Core/introspection/src/viz/graph-generator.rkt") + (category "CommandInjection") + (audit "Viz generation tool using local system calls to generate graphs") + (rationale "Tooling script; does not execute untrusted user input")) + + ;; ── DynamicCodeExecution ───────────────────────────────────────── + (classification + (file "praxis/SymbolicEngine/dashboard/js/dashboard.ts") + (category "DynamicCodeExecution") + (audit "Local admin dashboard DOM manipulation") + (rationale "Intentional DOM updates for trusted local dashboard UI")) + (classification + (file "praxis/SymbolicEngine/dashboard/js/symbol-inspector.ts") + (category "DynamicCodeExecution") + (audit "Local admin dashboard DOM manipulation") + (rationale "Intentional DOM updates for trusted local dashboard UI")) + (classification + (file "praxis/SymbolicEngine/dashboard/injector/js/injector.ts") + (category "DynamicCodeExecution") + (audit "Local admin dashboard DOM manipulation") + (rationale "Intentional DOM updates for trusted local dashboard UI")) + (classification + (file "resurrect/state/lib/state-utils.scm") + (category "DynamicCodeExecution") + (audit "Scheme utility library using eval by design") + (rationale "Internal state management utility operating on trusted scheme expressions")) + (classification + (file "journal-theme/tests/accessibility_test.js") + (category "DynamicCodeExecution") + (audit "Test fixture injecting DOM for testing") + (rationale "Test file manipulating DOM for accessibility checks")) + + ;; ── HardcodedSecret ────────────────────────────────────────────── + (classification + (file "praxis/Core/db-schema/config/test.exs") + (category "HardcodedSecret") + (audit "Test environment dummy database password") + (rationale "Local development test fixture, not a real credential")) + (classification + (file "praxis/Core/db-schema/config/dev.exs") + (category "HardcodedSecret") + (audit "Dev environment dummy database password") + (rationale "Local development fixture, not a real credential")) + (classification + (file "secured/php-aegis/validation/run-validation.sh") + (category "HardcodedSecret") + (audit "Bash variables storing DB credentials") + (rationale "Variables for script arguments, not hardcoded credentials")) + (classification + (file "plugin-conflict-mapper/bin/install-wp-tests.sh") + (category "HardcodedSecret") + (audit "Placeholders like yourpasswordhere in script") + (rationale "Test installation script placeholders, not real credentials")) + + ;; ── SupplyChain ────────────────────────────────────────────────── + (classification + (file "flake.nix") + (category "SupplyChain") + (audit "Nix flake utilizing flake.lock for pinning") + (rationale "Revisions are pinned via flake.lock, narHash inline not strictly required")) + + ;; ── UnboundedAllocation ────────────────────────────────────────── + (classification + (file "praxis/wp_injector/src/main.rs") + (category "UnboundedAllocation") + (audit "Reading wp-config.php and local JSON state files") + (rationale "Reads trusted, bounded local configuration and state files; OOM risk is negligible")) + (classification + (file "resurrect/src/socp-tui/src/config.rs") + (category "UnboundedAllocation") + (audit "Reading local TUI configuration") + (rationale "Reads trusted, bounded local configuration file")) + (classification + (file "project-wharf/crates/wharf-core/src/config.rs") + (category "UnboundedAllocation") + (audit "Reading local wharf configuration") + (rationale "Reads trusted, bounded local configuration file")) + (classification + (file "project-wharf/crates/wharf-core/src/integrity.rs") + (category "UnboundedAllocation") + (audit "Reading local manifest files") + (rationale "Reads trusted, bounded local manifests")) + (classification + (file "project-wharf/crates/wharf-core/src/nebula.rs") + (category "UnboundedAllocation") + (audit "Reading local nebula configs") + (rationale "Reads trusted, bounded local configuration file")) + (classification + (file "project-wharf/crates/wharf-core/src/fleet.rs") + (category "UnboundedAllocation") + (audit "Reading local fleet state files") + (rationale "Reads trusted, bounded local state files")) + (classification + (file "project-wharf/bin/yacht-agent/src/ebpf.rs") + (category "UnboundedAllocation") + (audit "Loading local eBPF programs") + (rationale "Reads trusted local eBPF object files bounded by OS limits")) +) diff --git a/docs/architecture.adoc b/docs/architecture.adoc index 19bcf00..ea9ad23 100644 --- a/docs/architecture.adoc +++ b/docs/architecture.adoc @@ -64,8 +64,8 @@ Example: == Dependencies * **Internal**: list other hyperpolymath repos this depends on. -* **External**: SHA-pinned (see `Cargo.lock` / `deno.lock` / etc.). -* **Build-time**: tools required to build (just, deno, cargo, …). +* **External**: SHA-pinned (see `Cargo.lock` / `.lock` / etc.). +* **Build-time**: tools required to build (just, , cargo, …). == Out of scope diff --git a/docs/usage.adoc b/docs/usage.adoc index 62f6664..951708f 100644 --- a/docs/usage.adoc +++ b/docs/usage.adoc @@ -17,7 +17,7 @@ The shortest path from zero to a working call: [source,bash] ---- # 1. Install -just install # or: cargo install --path . / deno task install +just install # or: cargo install --path . / task install # 2. Configure cp examples/config.example.toml ./config.toml diff --git a/journal-theme/.claude/CLAUDE.md b/journal-theme/.claude/CLAUDE.md index 5a0b803..96308ba 100644 --- a/journal-theme/.claude/CLAUDE.md +++ b/journal-theme/.claude/CLAUDE.md @@ -28,7 +28,7 @@ Copyright (c) Jonathan D.A. Jewell | Banned | Replacement | |--------|-------------| -| TypeScript | AffineScript | +| | AffineScript | | Node.js | Deno | | npm | Deno | | Bun | Deno | @@ -51,7 +51,7 @@ Both are FOSS with independent governance (no Big Tech). ### Enforcement Rules -1. **No new TypeScript files** - Convert existing TS to AffineScript +1. **No new files** - Convert existing TS to AffineScript 2. **No package.json - use deno.json deps** - Use deno.json imports 3. **No node_modules in production** - Deno caches deps automatically 4. **No Go code** - Use Rust instead diff --git a/journal-theme/.github/dependabot.yml b/journal-theme/.github/dependabot.yml index e9de92a..594a69c 100644 --- a/journal-theme/.github/dependabot.yml +++ b/journal-theme/.github/dependabot.yml @@ -14,7 +14,7 @@ updates: - "dependencies" - "npm" commit-message: - prefix: "deno" + prefix: "" include: "scope" ignore: # Ignore major version updates for breaking changes diff --git a/journal-theme/.github/renovate.json b/journal-theme/.github/renovate.json index d5b7065..b4047cc 100644 --- a/journal-theme/.github/renovate.json +++ b/journal-theme/.github/renovate.json @@ -32,9 +32,7 @@ ] }, { - "groupName": "TypeScript and related", "matchPackageNames": [ - "typescript", "@types/node", "ts-jest", "ts-loader" @@ -65,7 +63,6 @@ "matchPackagePatterns": [ "^eslint-", "^stylelint-", - "^@typescript-eslint/" ] }, { diff --git a/journal-theme/.github/workflows/ci.yml b/journal-theme/.github/workflows/ci.yml index dff4c6b..a5d9c6c 100644 --- a/journal-theme/.github/workflows/ci.yml +++ b/journal-theme/.github/workflows/ci.yml @@ -81,7 +81,6 @@ jobs: flags: php-${{ matrix.php }}-wp-${{ matrix.wordpress }} name: php-${{ matrix.php }}-wp-${{ matrix.wordpress }} lint-js: - name: JavaScript/TypeScript Lint runs-on: ubuntu-latest timeout-minutes: 15 steps: diff --git a/journal-theme/.github/workflows/codeql.yml b/journal-theme/.github/workflows/codeql.yml index 0bd3d87..d17bd70 100644 --- a/journal-theme/.github/workflows/codeql.yml +++ b/journal-theme/.github/workflows/codeql.yml @@ -43,14 +43,11 @@ jobs: include: - language: actions build-mode: none - - language: javascript-typescript build-mode: none - language: rust build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how diff --git a/journal-theme/.github/workflows/rescript-deno-ci.yml b/journal-theme/.github/workflows/rescript-deno-ci.yml index 150abeb..8878438 100644 --- a/journal-theme/.github/workflows/rescript-deno-ci.yml +++ b/journal-theme/.github/workflows/rescript-deno-ci.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: ReScript/Deno CI +name: / CI on: [push, pull_request] jobs: build: @@ -7,29 +7,29 @@ jobs: timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: denoland/setup-deno@v2 + - uses: denoland/setup-@v2 with: - deno-version: v1.x - - name: Deno lint - run: deno lint - - name: Deno fmt check - run: deno fmt --check - - name: Deno test - run: deno test --allow-all --coverage=coverage - - name: ReScript build + -version: v1.x + - name: lint + run: lint + - name: fmt check + run: fmt --check + - name: test + run: test --allow-all --coverage=coverage + - name: build run: | - if [ -f "rescript.json" ] || [ -f "bsconfig.json" ]; then + if [ -f ".json" ] || [ -f "bsconfig.json" ]; then npm install - npx rescript + npx fi - name: Type check - run: deno check **/*.ts || true + run: check **/*.ts || true security: runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: denoland/setup-deno@v2 + - uses: denoland/setup-@v2 - name: Check permissions run: | # Audit for dangerous permissions diff --git a/journal-theme/.gitignore b/journal-theme/.gitignore index 45f10b1..7e40e94 100644 --- a/journal-theme/.gitignore +++ b/journal-theme/.gitignore @@ -37,7 +37,7 @@ erl_crash.dump *.jl.mem /Manifest.toml -# ReScript +# /lib/bs/ /.bsb.lock diff --git a/journal-theme/.nojekyll b/journal-theme/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/journal-theme/CHANGELOG.adoc b/journal-theme/CHANGELOG.adoc index 0e48633..4c4df73 100644 --- a/journal-theme/CHANGELOG.adoc +++ b/journal-theme/CHANGELOG.adoc @@ -77,10 +77,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Type-safe parsing from PHP arrays ==== Modern Web Technologies -- TypeScript with strict mode and ESBuild bundling +- with strict mode and ESBuild bundling - SCSS architecture with CSS custom properties - WebAssembly modules (Rust source included) -- ReScript functional programming support +- functional programming support - Service Worker for offline support - View Transitions API integration - Scroll-driven Animations support @@ -134,9 +134,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ==== Build System - npm scripts for all operations (dev, build, lint, test) - SCSS compilation with Sass -- TypeScript/ESBuild bundling (ESM modules) +- /ESBuild bundling (ESM modules) - WASM compilation (Rust + Cargo) -- ReScript compilation +- compilation - Image optimization (imagemin with pngquant, mozjpeg, svgo) - Minification and optimization (cssnano, terser) - Development watch modes @@ -162,7 +162,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - .well-known/humans.txt (attribution) - Tri-Perimeter Contribution Framework (TPCF) implemented - Offline-first architecture (no mandatory external dependencies) -- Type safety (PHP 8.1+, TypeScript strict mode, Rust, ReScript) +- Type safety (PHP 8.1+, strict mode, Rust, ) - Memory safety (Rust ownership model, no unsafe blocks in WASM) === Changed diff --git a/journal-theme/Justfile b/journal-theme/Justfile index 4c8cd53..8f256ae 100644 --- a/journal-theme/Justfile +++ b/journal-theme/Justfile @@ -174,7 +174,7 @@ audit-composer: validate: @echo "📊 Validating RSR compliance..." @echo "" - @echo "✅ Type Safety: PHP 8.1+ strict, TypeScript strict, Rust, ReScript" + @echo "✅ Type Safety: PHP 8.1+ strict, TypeScript strict, Rust, " @echo "✅ Memory Safety: Rust ownership, zero unsafe blocks" @echo "✅ Offline-First: No mandatory external deps, Service Worker" @echo "✅ Documentation: 18+ markdown files" diff --git a/journal-theme/RSR-COMPLIANCE.md b/journal-theme/RSR-COMPLIANCE.md index 8313920..8b63408 100644 --- a/journal-theme/RSR-COMPLIANCE.md +++ b/journal-theme/RSR-COMPLIANCE.md @@ -12,7 +12,7 @@ This document tracks compliance with the Rhodium Standard Repository (RSR) frame | Category | Status | Notes | |----------|--------|-------| -| **Type Safety** | ✅ Bronze | PHP 8.1+, TypeScript strict, Rust, ReScript | +| **Type Safety** | ✅ Bronze | PHP 8.1+, strict, Rust, | | **Memory Safety** | ✅ Bronze | Rust ownership model, zero unsafe blocks in WASM | | **Offline-First** | ✅ Bronze | No mandatory external dependencies, works air-gapped | | **Documentation** | ✅ Bronze | 20+ markdown files, comprehensive coverage | @@ -34,9 +34,9 @@ This document tracks compliance with the Rhodium Standard Repository (RSR) frame **Implementation**: - ✅ **PHP 8.1+**: Strict types, declare(strict_types=1), type hints, return types -- ✅ **TypeScript**: Strict mode enabled, no implicit any, all functions typed +- ✅ ****: Strict mode enabled, no implicit any, all functions typed - ✅ **Rust**: Compile-time type checking, no runtime type errors -- ✅ **ReScript**: Sound type system, type inference, no runtime exceptions +- ✅ ****: Sound type system, type inference, no runtime exceptions - ✅ **Elixir**: Typespecs with Dialyzer for static analysis **Verification**: @@ -45,14 +45,14 @@ This document tracks compliance with the Rhodium Standard Repository (RSR) frame composer install ./vendor/bin/phpcs --standard=WordPress . -# TypeScript +# npm run lint:js # Rust cd assets/wasm && cargo check -# ReScript -npm run build:rescript +# +npm run build: ``` ### 2. Memory Safety ✅ Bronze @@ -62,7 +62,7 @@ npm run build:rescript **Implementation**: - ✅ **Rust**: Ownership model, borrow checker, no unsafe blocks in lib.rs - ✅ **PHP**: Memory-managed, no manual memory management -- ✅ **TypeScript/JavaScript**: Garbage-collected, no manual memory management +- ✅ **/JavaScript**: Garbage-collected, no manual memory management - ✅ **Container**: Read-only filesystem, tmpfs for necessary writes **Verification**: @@ -146,7 +146,7 @@ npm run build - test-security.php: Security headers, CSP, input sanitization, nonces - test-indieweb.php: Microformats, h-card, webmentions, JSON Feed, POSSE - test-serialization.php: NDJSON, FlatBuffers, Cap'n Proto, BEAM interop -- ✅ **Jest**: TypeScript/JavaScript test suite +- ✅ **Jest**: /JavaScript test suite - accessibility.test.ts: Font size controls, theme toggle, contrast mode - features.test.ts: View Transitions, WASM, Container Queries, :has() - wasm.test.ts: Reading time, HTML sanitization, password hashing @@ -315,7 +315,7 @@ just build # Production build ### Completed Requirements 1. ✅ **Testing**: Automated test suite implemented - PHPUnit: 6 test classes covering all inc/ modules - - Jest: 3 test suites for TypeScript modules + - Jest: 3 test suites for modules - Cargo test: Rust WASM testing configured - Coverage reporting: HTML, text, clover, LCOV 2. ✅ **CI/CD**: Complete pipelines operational diff --git a/journal-theme/RSR-SILVER-ACHIEVEMENT.md b/journal-theme/RSR-SILVER-ACHIEVEMENT.md index 6e81a50..53c6149 100644 --- a/journal-theme/RSR-SILVER-ACHIEVEMENT.md +++ b/journal-theme/RSR-SILVER-ACHIEVEMENT.md @@ -71,7 +71,7 @@ Files created: - `tests/php/test-serialization.php` - Serialization tests - `bin/install-wp-tests.sh` - WordPress test suite installer -#### Jest (JavaScript/TypeScript Testing) +#### Jest (JavaScript/ Testing) - **3 comprehensive test suites** for browser features - **Mocked environment** (localStorage, matchMedia, observers) - **80% coverage target** with threshold enforcement @@ -100,7 +100,7 @@ Created `.github/workflows/ci.yml` with **10 parallel jobs**: 3. **JavaScript Lint**: ESLint + Stylelint 4. **JavaScript Tests**: Jest with coverage upload to Codecov 5. **Rust Tests**: cargo test + clippy + rustfmt -6. **Build**: Compile all assets (SCSS, TypeScript, WASM, ReScript) +6. **Build**: Compile all assets (SCSS, , WASM, ) 7. **Security Audit**: npm audit + composer audit + cargo audit 8. **Container**: Docker build + Trivy vulnerability scan 9. **Accessibility**: Playwright tests (placeholder) diff --git a/journal-theme/TESTING.md b/journal-theme/TESTING.md index 2229c7c..486a957 100644 --- a/journal-theme/TESTING.md +++ b/journal-theme/TESTING.md @@ -10,7 +10,7 @@ This document provides comprehensive guidance for running tests in the Sinople t Sinople implements a multi-language test suite covering: - **PHP** (WordPress theme code) - PHPUnit -- **JavaScript/TypeScript** - Jest +- **JavaScript/** - Jest - **Rust** (WebAssembly) - cargo test ## Prerequisites @@ -162,7 +162,7 @@ tests/js/ #### Test Utilities -```typescript +``` // Mock window.sinople global window.sinople = { features: { viewTransitions: true, wasm: true }, @@ -242,7 +242,7 @@ class Test_My_Feature extends SinopleTestCase { ### JavaScript Test Example -```typescript +``` describe('My Feature', () => { beforeEach(() => { document.body.innerHTML = `
`; diff --git a/journal-theme/assets/rescript/src/Accessibility.res b/journal-theme/assets/rescript/src/Accessibility.res deleted file mode 100644 index 0aaabfb..0000000 --- a/journal-theme/assets/rescript/src/Accessibility.res +++ /dev/null @@ -1,262 +0,0 @@ -/** - * Accessibility Module - * - * Font sizing, theme toggle, high contrast mode, - * and keyboard navigation enhancements. - * WCAG 2.3 AAA compliant. - * - * @package Sinople - * @since 0.1.0 - */ - -@val external document: Dom.document = "document" -@val external window: Dom.window = "window" -@val external console: {..} = "console" - -module LocalStorage = { - @val @scope("localStorage") external getItem: string => Nullable.t = "getItem" - @val @scope("localStorage") external setItem: (string, string) => unit = "setItem" - @val @scope("localStorage") external removeItem: string => unit = "removeItem" -} - -module Dom = { - @val @scope("document") external getElementById: string => Nullable.t = "getElementById" - @val @scope("document") external querySelector: string => Nullable.t = "querySelector" - @val @scope("document") external querySelectorAll: string => array = "querySelectorAll" - @val @scope("document") external documentElement: Dom.element = "documentElement" - - @send external addEventListener: (Dom.document, string, 'event => unit) => unit = "addEventListener" - @send external addElementEventListener: (Dom.element, string, 'event => unit) => unit = "addEventListener" - @send external setAttribute: (Dom.element, string, string) => unit = "setAttribute" - @send external getAttribute: (Dom.element, string) => Nullable.t = "getAttribute" - @send external focus: Dom.element => unit = "focus" - @send external scrollIntoView: (Dom.element, {..}) => unit = "scrollIntoView" - - @get external style: Dom.element => {..} = "style" - @get external dataset: Dom.element => {..} = "dataset" - @get external classList: Dom.element => {..} = "classList" - @get external id: Dom.element => string = "id" -} - -// Apply font scale to document -let applyFontScale = (scale: float) => { - let html = Dom.documentElement - let _ = %raw(`html.style.setProperty('--text-scale', scale.toString())`) -} - -// Font size controls (WCAG AAA) -let initFontSizeControls = () => { - let decreaseBtn = Dom.getElementById("font-size-decrease") - let increaseBtn = Dom.getElementById("font-size-increase") - - switch (Nullable.toOption(decreaseBtn), Nullable.toOption(increaseBtn)) { - | (Some(decBtn), Some(incBtn)) => { - // Get current scale from localStorage - let savedScale = LocalStorage.getItem("font-scale") - let currentScale = ref( - switch Nullable.toOption(savedScale) { - | Some(s) => Float.fromString(s)->Option.getOr(1.0) - | None => 1.0 - } - ) - - applyFontScale(currentScale.contents) - - // Decrease handler - Dom.addElementEventListener(decBtn, "click", _ => { - currentScale := Math.max(0.8, currentScale.contents -. 0.1) - applyFontScale(currentScale.contents) - LocalStorage.setItem("font-scale", Float.toString(currentScale.contents)) - }) - - // Increase handler - Dom.addElementEventListener(incBtn, "click", _ => { - currentScale := Math.min(1.5, currentScale.contents +. 0.1) - applyFontScale(currentScale.contents) - LocalStorage.setItem("font-scale", Float.toString(currentScale.contents)) - }) - } - | _ => () - } -} - -// Apply theme to document -let applyTheme = (theme: string) => { - let html = Dom.documentElement - let _ = %raw(`html.dataset.theme = theme`) -} - -// Update theme toggle button state -let updateThemeButton = (button: Dom.element, theme: string) => { - Dom.setAttribute(button, "aria-pressed", theme == "dark" ? "true" : "false") - Dom.setAttribute( - button, - "aria-label", - theme == "dark" ? "Switch to light mode" : "Switch to dark mode", - ) -} - -// Theme toggle (dark/light mode) -let initThemeToggle = () => { - let toggleBtn = Dom.getElementById("theme-toggle") - - switch Nullable.toOption(toggleBtn) { - | Some(btn) => { - // Get initial theme - let savedTheme = LocalStorage.getItem("theme") - let systemDark: bool = %raw(`window.matchMedia('(prefers-color-scheme: dark)').matches`) - - let currentTheme = switch Nullable.toOption(savedTheme) { - | Some(t) => t - | None => systemDark ? "dark" : "light" - } - - applyTheme(currentTheme) - updateThemeButton(btn, currentTheme) - - // Toggle on click - Dom.addElementEventListener(btn, "click", _ => { - let html = Dom.documentElement - let currentDataTheme: string = %raw(`html.dataset.theme || 'light'`) - let newTheme = currentDataTheme == "dark" ? "light" : "dark" - applyTheme(newTheme) - updateThemeButton(btn, newTheme) - LocalStorage.setItem("theme", newTheme) - }) - - // Listen for system preference changes - let _ = %raw(` - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { - if (!localStorage.getItem('theme')) { - const theme = e.matches ? 'dark' : 'light'; - document.documentElement.dataset.theme = theme; - } - }) - `) - } - | None => () - } -} - -// High contrast toggle -let initContrastToggle = () => { - let toggleBtn = Dom.getElementById("contrast-toggle") - - switch Nullable.toOption(toggleBtn) { - | Some(btn) => { - let savedContrast = LocalStorage.getItem("contrast") - - switch Nullable.toOption(savedContrast) { - | Some("high") => { - let _ = %raw(`document.documentElement.dataset.contrast = 'high'`) - Dom.setAttribute(btn, "aria-pressed", "true") - } - | _ => () - } - - Dom.addElementEventListener(btn, "click", _ => { - let isHigh: bool = %raw(`document.documentElement.dataset.contrast === 'high'`) - - if isHigh { - let _ = %raw(`delete document.documentElement.dataset.contrast`) - Dom.setAttribute(btn, "aria-pressed", "false") - LocalStorage.removeItem("contrast") - } else { - let _ = %raw(`document.documentElement.dataset.contrast = 'high'`) - Dom.setAttribute(btn, "aria-pressed", "true") - LocalStorage.setItem("contrast", "high") - } - }) - } - | None => () - } -} - -// Close modal helper -let closeModal = (modal: Dom.element) => { - Dom.setAttribute(modal, "aria-hidden", "true") - let _ = %raw(`modal.classList.remove('is-open')`) - - let modalId = Dom.id(modal) - let trigger = Dom.querySelector(`[aria-controls="${modalId}"]`) - - switch Nullable.toOption(trigger) { - | Some(t) => Dom.focus(t) - | None => () - } -} - -// Enhanced keyboard navigation -let initKeyboardNavigation = () => { - // Trap focus in modals with Escape key - Dom.addEventListener(document, "keydown", event => { - let key: string = %raw(`event.key`) - - if key == "Escape" { - let openModal = Dom.querySelector(`[role="dialog"][aria-hidden="false"]`) - - switch Nullable.toOption(openModal) { - | Some(modal) => closeModal(modal) - | None => () - } - } - }) - - // Focus management for menu toggle - let menuToggle = Dom.querySelector(".menu-toggle") - let menu = Dom.getElementById("primary-menu") - - switch (Nullable.toOption(menuToggle), Nullable.toOption(menu)) { - | (Some(toggle), Some(menuEl)) => { - Dom.addElementEventListener(toggle, "click", _ => { - let isExpanded: bool = %raw(`toggle.getAttribute('aria-expanded') === 'true'`) - Dom.setAttribute(toggle, "aria-expanded", !isExpanded ? "true" : "false") - let _ = %raw(`menuEl.classList.toggle('is-open')`) - - if !isExpanded { - let firstLink = %raw(`menuEl.querySelector('a')`) - switch Nullable.toOption(firstLink) { - | Some(link) => Dom.focus(link) - | None => () - } - } - }) - } - | _ => () - } -} - -// Skip links visibility -let initSkipLinks = () => { - let skipLinks = Dom.querySelectorAll(".skip-link") - - skipLinks->Array.forEach(link => { - Dom.addElementEventListener(link, "click", event => { - let _ = %raw(`event.preventDefault()`) - let href: Nullable.t = %raw(`link.getAttribute('href')`) - - switch Nullable.toOption(href) { - | Some(h) => { - let target = Dom.querySelector(h) - switch Nullable.toOption(target) { - | Some(t) => { - Dom.focus(t) - Dom.scrollIntoView(t, {"behavior": "smooth"}) - } - | None => () - } - } - | None => () - } - }) - }) -} - -// Initialize all accessibility features -let init = () => { - initFontSizeControls() - initThemeToggle() - initContrastToggle() - initKeyboardNavigation() - initSkipLinks() -} diff --git a/journal-theme/assets/rescript/src/Sinople.res b/journal-theme/assets/rescript/src/Sinople.res deleted file mode 100644 index c7dd700..0000000 --- a/journal-theme/assets/rescript/src/Sinople.res +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Sinople Theme - Main ReScript Entry Point - * - * Type-safe module for progressive enhancement, - * accessibility features, and modern browser APIs. - * - * @package Sinople - * @since 0.1.0 - */ - -// Global bindings -@val external document: Dom.document = "document" -@val external window: Dom.window = "window" -@val external console: {..} = "console" - -// Sinople configuration type -type sinopleFeatures = { - mutable wasm: bool, - mutable serviceWorker: bool, - mutable viewTransitions: bool, - mutable prefersReducedMotion: bool, - mutable intersectionObserver: bool, - mutable resizeObserver: bool, - mutable containerQueries: bool, - mutable hasSelector: bool, - mutable webCrypto: bool, - mutable webGPU: bool, - mutable webRTC: bool, - mutable fileSystemAccess: bool, - mutable webShare: bool, -} - -type sinopleEndpoints = { - void: string, - ndjson: string, - capnproto: string, -} - -type sinopleConfig = { - ajaxUrl: string, - nonce: string, - themeUri: string, - homeUrl: string, - isRTL: bool, - i18n: Dict.t, - mutable features: sinopleFeatures, - endpoints: sinopleEndpoints, -} - -@val @scope("window") external sinople: option = "sinople" - -// DOM helpers -module Dom = { - @val @scope("document") external getElementById: string => Nullable.t = "getElementById" - @val @scope("document") external querySelector: string => Nullable.t = "querySelector" - @val @scope("document") external querySelectorAll: string => array = "querySelectorAll" - @val @scope("document") external documentElement: Dom.element = "documentElement" - @get external readyState: Dom.document => string = "readyState" - - @send external addEventListener: (Dom.document, string, 'event => unit) => unit = "addEventListener" - @send external addElementEventListener: (Dom.element, string, 'event => unit) => unit = "addEventListener" - @send external classList: Dom.element => {..} = "classList" - @send external setAttribute: (Dom.element, string, string) => unit = "setAttribute" - @send external setStyle: (Dom.element, string, string) => unit = "setProperty" - @get external style: Dom.element => {..} = "style" - @get external dataset: Dom.element => {..} = "dataset" -} - -// CSS support check -@val @scope("CSS") external cssSupports: string => bool = "supports" - -// Initialize theme functionality -let init = async () => { - switch sinople { - | None => console["error"]("Sinople: Configuration object not found") - | Some(config) => { - console["log"]("🌿 Sinople theme initializing...") - - // Initialize accessibility features (critical) - Accessibility.init() - - // Initialize View Transitions API if supported - if config.features.viewTransitions { - ViewTransitions.init() - } - - // Load WASM module if supported - if config.features.wasm { - try { - await WasmLoader.load() - console["log"]("✓ WASM module loaded") - } catch { - | _ => console["warn"]("WASM module failed to load") - } - } - - // Initialize web components - WebComponents.init() - - // Feature detection - detectFeatures() - - console["log"]("✓ Sinople theme initialized") - } - } -} - -// Detect and add feature classes to HTML element -let detectFeatures = () => { - let html = Dom.documentElement - - // Feature detection using raw JS for browser APIs - let hasIntersectionObserver = %raw(`'IntersectionObserver' in window`) - let hasResizeObserver = %raw(`'ResizeObserver' in window`) - let hasContainerQueries = cssSupports("container-type: inline-size") - let hasHasSelector = cssSupports("selector(:has(*))") - let hasViewTransitions = %raw(`'startViewTransition' in document`) - let hasWebCrypto = %raw(`typeof window.crypto?.subtle?.generateKey === 'function'`) - let hasWebGPU = %raw(`'gpu' in navigator`) - let hasWebRTC = %raw(`'RTCPeerConnection' in window`) - let hasFileSystemAccess = %raw(`'showOpenFilePicker' in window`) - let hasWebShare = %raw(`'share' in navigator`) - - // Add classes to HTML element - let addFeatureClass = (name: string, supported: bool) => { - if supported { - let _ = %raw(`html.classList.add('has-' + name)`) - } - } - - addFeatureClass("intersection-observer", hasIntersectionObserver) - addFeatureClass("resize-observer", hasResizeObserver) - addFeatureClass("container-queries", hasContainerQueries) - addFeatureClass("has-selector", hasHasSelector) - addFeatureClass("view-transitions", hasViewTransitions) - addFeatureClass("web-crypto", hasWebCrypto) - addFeatureClass("web-gpu", hasWebGPU) - addFeatureClass("web-rtc", hasWebRTC) - addFeatureClass("file-system-access", hasFileSystemAccess) - addFeatureClass("web-share", hasWebShare) - - // Update global features object - switch sinople { - | None => () - | Some(config) => { - config.features.intersectionObserver = hasIntersectionObserver - config.features.resizeObserver = hasResizeObserver - config.features.containerQueries = hasContainerQueries - config.features.hasSelector = hasHasSelector - config.features.viewTransitions = hasViewTransitions - config.features.webCrypto = hasWebCrypto - config.features.webGPU = hasWebGPU - config.features.webRTC = hasWebRTC - config.features.fileSystemAccess = hasFileSystemAccess - config.features.webShare = hasWebShare - } - } -} - -// Initialize when DOM is ready -let _ = { - let readyState = %raw(`document.readyState`) - if readyState == "loading" { - Dom.addEventListener(document, "DOMContentLoaded", _ => { - let _ = init() - }) - } else { - let _ = init() - } -} diff --git a/journal-theme/assets/rescript/src/ViewTransitions.res b/journal-theme/assets/rescript/src/ViewTransitions.res deleted file mode 100644 index 9fcdd28..0000000 --- a/journal-theme/assets/rescript/src/ViewTransitions.res +++ /dev/null @@ -1,101 +0,0 @@ -/** - * View Transitions Module - * - * Handles View Transitions API for smooth page transitions. - * Falls back gracefully on unsupported browsers. - * - * @package Sinople - * @since 0.1.0 - */ - -@val external document: Dom.document = "document" -@val external console: {..} = "console" - -module Dom = { - @val @scope("document") external querySelectorAll: string => array = "querySelectorAll" - @send external addEventListener: (Dom.element, string, 'event => unit) => unit = "addEventListener" - @get external href: Dom.element => string = "href" -} - -// Check if View Transitions API is available -let isSupported = (): bool => { - %raw(`'startViewTransition' in document`) -} - -// Navigate with view transition -let navigateWithTransition = (url: string): unit => { - if isSupported() { - let _ = %raw(` - document.startViewTransition(async () => { - const response = await fetch(url); - const html = await response.text(); - const parser = new DOMParser(); - const doc = parser.parseFromString(html, 'text/html'); - - // Update the main content - const newMain = doc.querySelector('main'); - const currentMain = document.querySelector('main'); - if (newMain && currentMain) { - currentMain.innerHTML = newMain.innerHTML; - } - - // Update the title - document.title = doc.title; - - // Update the URL - history.pushState({}, '', url); - }); - `) - } else { - // Fallback: standard navigation - let _ = %raw(`window.location.href = url`) - } -} - -// Setup navigation handlers -let setupNavigationHandlers = () => { - let links = Dom.querySelectorAll("a[data-view-transition]") - - links->Array.forEach(link => { - Dom.addEventListener(link, "click", event => { - let _ = %raw(`event.preventDefault()`) - let url = Dom.href(link) - navigateWithTransition(url) - }) - }) -} - -// Handle back/forward navigation -let setupPopStateHandler = () => { - let _ = %raw(` - window.addEventListener('popstate', () => { - if ('startViewTransition' in document) { - document.startViewTransition(async () => { - const response = await fetch(window.location.href); - const html = await response.text(); - const parser = new DOMParser(); - const doc = parser.parseFromString(html, 'text/html'); - - const newMain = doc.querySelector('main'); - const currentMain = document.querySelector('main'); - if (newMain && currentMain) { - currentMain.innerHTML = newMain.innerHTML; - } - - document.title = doc.title; - }); - } - }); - `) -} - -// Initialize View Transitions -let init = () => { - if isSupported() { - console["log"]("View Transitions API available") - setupNavigationHandlers() - setupPopStateHandler() - } else { - console["log"]("View Transitions API not supported, using standard navigation") - } -} diff --git a/journal-theme/assets/rescript/src/WasmLoader.res b/journal-theme/assets/rescript/src/WasmLoader.res deleted file mode 100644 index e486eb7..0000000 --- a/journal-theme/assets/rescript/src/WasmLoader.res +++ /dev/null @@ -1,151 +0,0 @@ -/** - * WASM Loader Module - * - * Loads and initializes WebAssembly module - * for performance-critical operations. - * - * @package Sinople - * @since 0.1.0 - */ - -@val external console: {..} = "console" - -// WASM module instance -type wasmExports = { - calculate_reading_time: (. string) => int, - sanitize_html: (. string) => string, - hash_password: (. string) => string, -} - -type wasmModule = {exports: wasmExports} - -// Check if WebAssembly is supported -let isSupported = (): bool => { - %raw(`typeof WebAssembly !== 'undefined' && typeof WebAssembly.instantiate === 'function'`) -} - -// Get WASM module path -let getWasmPath = (): string => { - // Try to get from sinople config - let path: option = %raw(` - window.sinople?.themeUri - ? window.sinople.themeUri + '/assets/js/dist/sinople.wasm' - : null - `) - - switch path { - | Some(p) => p - | None => "/wp-content/themes/sinople/assets/js/dist/sinople.wasm" - } -} - -// Load WASM module -let load = async (): promise => { - if !isSupported() { - console["warn"]("WebAssembly not supported") - Promise.resolve() - } else { - let wasmPath = getWasmPath() - - // Fetch and instantiate WASM module - let _ = await %raw(` - (async () => { - try { - const response = await fetch(wasmPath); - if (!response.ok) { - throw new Error('Failed to fetch WASM module: ' + response.status); - } - - const wasmBuffer = await response.arrayBuffer(); - const wasmModule = await WebAssembly.instantiate(wasmBuffer, { - env: { - // Memory for string operations - memory: new WebAssembly.Memory({ initial: 256, maximum: 512 }), - // Logging from WASM - console_log: (ptr, len) => { - // Handle logging from WASM if needed - } - } - }); - - // Store module globally for use - window.sinople = window.sinople || {}; - window.sinople.wasm = wasmModule.instance.exports; - - return wasmModule; - } catch (error) { - console.warn('WASM loading failed:', error); - throw error; - } - })() - `) - - Promise.resolve() - } -} - -// Calculate reading time using WASM if available -let calculateReadingTime = (content: string): int => { - let wasmResult: option = %raw(` - window.sinople?.wasm?.calculate_reading_time - ? window.sinople.wasm.calculate_reading_time(content) - : null - `) - - switch wasmResult { - | Some(time) => time - | None => { - // Fallback: JS implementation - let wordCount = content->String.split(" ")->Array.length - Int.fromFloat(Math.ceil(Float.fromInt(wordCount) /. 200.0)) - } - } -} - -// Sanitize HTML using WASM if available -let sanitizeHtml = (html: string): string => { - let wasmResult: option = %raw(` - window.sinople?.wasm?.sanitize_html - ? window.sinople.wasm.sanitize_html(html) - : null - `) - - switch wasmResult { - | Some(sanitized) => sanitized - | None => { - // Fallback: basic JS sanitization - let _ = %raw(` - const div = document.createElement('div'); - div.textContent = html; - return div.innerHTML; - `) - html - } - } -} - -// Hash password using WASM if available -let hashPassword = async (password: string): promise => { - let wasmResult: option = %raw(` - window.sinople?.wasm?.hash_password - ? window.sinople.wasm.hash_password(password) - : null - `) - - switch wasmResult { - | Some(hash) => hash - | None => { - // Fallback: Web Crypto API - let hash: string = await %raw(` - (async () => { - const encoder = new TextEncoder(); - const data = encoder.encode(password); - const hashBuffer = await crypto.subtle.digest('SHA-256', data); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); - })() - `) - hash - } - } -} diff --git a/journal-theme/assets/rescript/src/WebComponents.res b/journal-theme/assets/rescript/src/WebComponents.res deleted file mode 100644 index e5eb64d..0000000 --- a/journal-theme/assets/rescript/src/WebComponents.res +++ /dev/null @@ -1,217 +0,0 @@ -/** - * Web Components Module - * - * Custom elements for Sinople theme features. - * Progressive enhancement - works without JS. - * - * @package Sinople - * @since 0.1.0 - */ - -@val external console: {..} = "console" - -// Define sinople-gloss custom element for inline annotations -let defineGlossComponent = () => { - let _ = %raw(` - if (!customElements.get('sinople-gloss')) { - class SinopolGloss extends HTMLElement { - constructor() { - super(); - this.attachShadow({ mode: 'open' }); - } - - connectedCallback() { - const term = this.getAttribute('term') || ''; - const definition = this.getAttribute('definition') || this.textContent; - - this.shadowRoot.innerHTML = \` - - - \${term} - - - \${definition} - - \`; - } - } - - customElements.define('sinople-gloss', SinopolGloss); - } - `) -} - -// Define sinople-fieldnote custom element for observational micro-essays -let defineFieldNoteComponent = () => { - let _ = %raw(` - if (!customElements.get('sinople-fieldnote')) { - class SinopolFieldNote extends HTMLElement { - constructor() { - super(); - this.attachShadow({ mode: 'open' }); - } - - connectedCallback() { - const location = this.getAttribute('location') || ''; - const timestamp = this.getAttribute('timestamp') || ''; - const content = this.innerHTML; - - this.shadowRoot.innerHTML = \` - -
- \${location ? \`\${location}\` : ''} - \${timestamp ? \`\` : ''} -
-
- -
- \`; - } - } - - customElements.define('sinople-fieldnote', SinopolFieldNote); - } - `) -} - -// Define sinople-portal custom element for annotated external links -let definePortalComponent = () => { - let _ = %raw(` - if (!customElements.get('sinople-portal')) { - class SinopolPortal extends HTMLElement { - constructor() { - super(); - this.attachShadow({ mode: 'open' }); - } - - connectedCallback() { - const href = this.getAttribute('href') || '#'; - const title = this.getAttribute('title') || ''; - const description = this.getAttribute('description') || ''; - - this.shadowRoot.innerHTML = \` - - - \${title} - \${description ? \`

\${description}

\` : ''} - \${new URL(href, window.location.origin).hostname} -
- \`; - } - } - - customElements.define('sinople-portal', SinopolPortal); - } - `) -} - -// Initialize all web components -let init = () => { - // Check for Custom Elements support - let hasCustomElements: bool = %raw(`'customElements' in window`) - - if hasCustomElements { - defineGlossComponent() - defineFieldNoteComponent() - definePortalComponent() - console["log"]("Web Components initialized") - } else { - console["log"]("Custom Elements not supported") - } -} diff --git a/journal-theme/deno.json b/journal-theme/deno.json deleted file mode 100644 index 05b20c3..0000000 --- a/journal-theme/deno.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "sinople-theme", - "version": "0.1.0", - "exports": "./mod.ts", - "tasks": { - "dev": "deno task watch:scss & deno task watch:rescript", - "build": "deno task build:scss && deno task build:rescript && deno task build:wasm && deno task optimize", - "build:scss": "sass --style=compressed --no-source-map assets/scss:assets/css", - "build:rescript": "rescript build", - "build:wasm": "cd assets/wasm && cargo build --release --target wasm32-unknown-unknown && wasm-opt -Oz -o ../js/dist/sinople.wasm target/wasm32-unknown-unknown/release/sinople_wasm.wasm", - "watch:scss": "sass --watch --style=expanded assets/scss:assets/css", - "watch:rescript": "rescript build -w", - "optimize": "deno task optimize:css && deno task optimize:images", - "optimize:css": "deno run --allow-read --allow-write scripts/optimize-css.ts", - "optimize:images": "deno run --allow-read --allow-write scripts/optimize-images.ts", - "lint": "deno lint && deno task lint:scss && deno task lint:php", - "lint:scss": "stylelint 'assets/scss/**/*.scss'", - "lint:php": "phpcs --standard=WordPress .", - "format": "deno fmt", - "test": "deno test --allow-read --allow-write --allow-env tests/", - "test:coverage": "deno test --coverage=coverage/ tests/", - "test:a11y": "deno run --allow-read --allow-write --allow-net scripts/test-accessibility.ts", - "test:semantics": "deno run --allow-read --allow-write scripts/test-semantics.ts", - "server:nginx": "deno run --allow-read --allow-write --allow-env scripts/generate-nginx-config.ts", - "server:apache": "deno run --allow-read --allow-write --allow-env scripts/generate-apache-config.ts", - "server:caddy": "deno run --allow-read --allow-write --allow-env scripts/generate-caddy-config.ts" - }, - "imports": { - "@std/assert": "jsr:@std/assert@1", - "@std/fs": "jsr:@std/fs@1", - "@std/path": "jsr:@std/path@1", - "@std/testing": "jsr:@std/testing@1" - }, - "compilerOptions": { - "strict": true, - "lib": ["deno.window", "dom", "dom.iterable"] - }, - "lint": { - "include": ["scripts/", "tests/"], - "exclude": ["assets/rescript/lib/"], - "rules": { - "tags": ["recommended"] - } - }, - "fmt": { - "useTabs": false, - "lineWidth": 100, - "indentWidth": 2, - "semiColons": true, - "singleQuote": true, - "proseWrap": "preserve", - "include": ["scripts/", "tests/"] - }, - "test": { - "include": ["tests/"] - } -} diff --git a/journal-theme/rescript.json b/journal-theme/rescript.json deleted file mode 100644 index 79c1f25..0000000 --- a/journal-theme/rescript.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "sinople-theme", - "version": "0.1.0", - "sources": [ - { - "dir": "assets/rescript", - "subdirs": true - } - ], - "package-specs": [ - { - "module": "es6", - "in-source": true - } - ], - "suffix": ".bs.js", - "bs-dependencies": [ - "@rescript/core" - ], - "warnings": { - "error": "+101" - }, - "bsc-flags": [ - "-bs-super-errors" - ], - "ppx-flags": [], - "namespace": true, - "refmt": 3 -} diff --git a/journal-theme/tests/features_test.js b/journal-theme/tests/features_test.js index fa5dcb4..ff17117 100644 --- a/journal-theme/tests/features_test.js +++ b/journal-theme/tests/features_test.js @@ -57,7 +57,7 @@ function createFeatureDetectionMocks(features) { globalThis.RTCPeerConnection = features.webRTC ? class {} : undefined; } -// Feature detection function (mirrors ReScript implementation) +// Feature detection function (mirrors implementation) function detectFeatures() { const features = {}; diff --git a/plugin-conflict-mapper/.claude/CLAUDE.md b/plugin-conflict-mapper/.claude/CLAUDE.md index 9b0b940..efa504e 100644 --- a/plugin-conflict-mapper/.claude/CLAUDE.md +++ b/plugin-conflict-mapper/.claude/CLAUDE.md @@ -41,7 +41,7 @@ The following files in `.machine_readable/` contain structured project metadata: | Banned | Replacement | |--------|-------------| -| TypeScript | AffineScript | +| | AffineScript | | Node.js | Deno | | npm | Deno | | Bun | Deno | @@ -64,7 +64,7 @@ Both are FOSS with independent governance (no Big Tech). ### Enforcement Rules -1. **No new TypeScript files** - Convert existing TS to AffineScript +1. **No new files** - Convert existing TS to AffineScript 2. **No package.json - use deno.json deps** - Use deno.json imports 3. **No node_modules in production** - Deno caches deps automatically 4. **No Go code** - Use Rust instead diff --git a/plugin-conflict-mapper/.github/workflows/codeql.yml b/plugin-conflict-mapper/.github/workflows/codeql.yml index e85a97a..e8cb11b 100644 --- a/plugin-conflict-mapper/.github/workflows/codeql.yml +++ b/plugin-conflict-mapper/.github/workflows/codeql.yml @@ -41,14 +41,10 @@ jobs: fail-fast: false matrix: include: - - language: javascript-typescript build-mode: none - - language: javascript-typescript build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how diff --git a/plugin-conflict-mapper/ABI-FFI-README.md b/plugin-conflict-mapper/ABI-FFI-README.md index ada05ff..d27c3ea 100644 --- a/plugin-conflict-mapper/ABI-FFI-README.md +++ b/plugin-conflict-mapper/ABI-FFI-README.md @@ -47,7 +47,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: ▼ ┌─────────────────────────────────────────────┐ │ Any Language via C ABI │ -│ - Rust, ReScript, Julia, Python, etc. │ +│ - Rust, , Julia, Python, etc. │ └─────────────────────────────────────────────┘ ``` @@ -79,7 +79,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: │ └── bindings/ # Language-specific wrappers (optional) ├── rust/ - ├── rescript/ + ├── / └── julia/ ``` @@ -343,8 +343,8 @@ zig build test-integration -- Runtime checks main : IO () main = do - verifyLayoutsCorrect - verifyAlignmentsCorrect + verifyLayouorrect + verifyAlignmenorrect putStrLn "ABI verification passed" ``` diff --git a/plugin-conflict-mapper/RSR_OUTLINE.adoc b/plugin-conflict-mapper/RSR_OUTLINE.adoc index 0ad555a..036001f 100644 --- a/plugin-conflict-mapper/RSR_OUTLINE.adoc +++ b/plugin-conflict-mapper/RSR_OUTLINE.adoc @@ -148,7 +148,7 @@ project/ === Language Tiers -* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, ReScript +* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, * **Tier 2** (Silver): Nickel, Racket, Guile Scheme, Nix * **Infrastructure**: Guix channels, derivations @@ -168,7 +168,7 @@ project/ === Prohibited * Python outside `salt/` directory -* TypeScript/JavaScript (use ReScript) +* /JavaScript (use ) * CUE (use Guile/Nickel) * `Dockerfile` (use `Containerfile`) diff --git a/plugin-conflict-mapper/examples/web-project-deno.json b/plugin-conflict-mapper/examples/web-project-deno.json deleted file mode 100644 index 5ddd3bd..0000000 --- a/plugin-conflict-mapper/examples/web-project-deno.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "// NOTE": "Example deno.json for ReScript web projects", - "tasks": { - "build": "deno run -A npm:rescript", - "clean": "deno run -A npm:rescript clean", - "watch": "deno run -A npm:rescript -w", - "serve": "deno run -A jsr:@std/http/file-server .", - "test": "deno test --allow-all" - }, - "imports": { - "rescript": "^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.0", - "safe-dom/": "https://raw.githubusercontent.com/hyperpolymath/rescript-dom-mounter/main/src/", - "proven/": "../proven/bindings/rescript/src/" - }, - "compilerOptions": { - "allowJs": true, - "checkJs": false - } -} diff --git a/praxis/.claude/CLAUDE.md b/praxis/.claude/CLAUDE.md index 5a0b803..96308ba 100644 --- a/praxis/.claude/CLAUDE.md +++ b/praxis/.claude/CLAUDE.md @@ -28,7 +28,7 @@ Copyright (c) Jonathan D.A. Jewell | Banned | Replacement | |--------|-------------| -| TypeScript | AffineScript | +| | AffineScript | | Node.js | Deno | | npm | Deno | | Bun | Deno | @@ -51,7 +51,7 @@ Both are FOSS with independent governance (no Big Tech). ### Enforcement Rules -1. **No new TypeScript files** - Convert existing TS to AffineScript +1. **No new files** - Convert existing TS to AffineScript 2. **No package.json - use deno.json deps** - Use deno.json imports 3. **No node_modules in production** - Deno caches deps automatically 4. **No Go code** - Use Rust instead diff --git a/praxis/.github/workflows/codeql.yml b/praxis/.github/workflows/codeql.yml index 390f86c..0b922d3 100644 --- a/praxis/.github/workflows/codeql.yml +++ b/praxis/.github/workflows/codeql.yml @@ -43,14 +43,11 @@ jobs: include: - language: actions build-mode: none - - language: javascript-typescript build-mode: none - language: rust build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how diff --git a/praxis/.github/workflows/test.yml b/praxis/.github/workflows/test.yml index 263b1a8..dc8217c 100644 --- a/praxis/.github/workflows/test.yml +++ b/praxis/.github/workflows/test.yml @@ -205,9 +205,6 @@ jobs: with: name: php-test-results path: tests/results/phpunit-results.xml - # TypeScript/Bun Tests - typescript-tests: - name: TypeScript Tests runs-on: ubuntu-latest timeout-minutes: 15 steps: @@ -220,24 +217,19 @@ jobs: - name: Install dependencies (swarm) working-directory: SymbolicEngine/swarm run: bun install - - name: Run TypeScript tests (swarm) working-directory: SymbolicEngine/swarm run: bun test --coverage - name: Install dependencies (dashboard) working-directory: SymbolicEngine/dashboard run: bun install || true - - name: Run TypeScript tests (dashboard) working-directory: SymbolicEngine/dashboard run: bun test --coverage || true - - name: Upload TypeScript coverage uses: codecov/codecov-action@v4 with: files: ./SymbolicEngine/swarm/coverage/coverage-final.json - flags: typescript # E2E Tests e2e-tests: name: End-to-End Tests - needs: [powershell-tests, rust-tests, elixir-tests, php-tests, typescript-tests] runs-on: ubuntu-latest timeout-minutes: 15 steps: @@ -260,7 +252,6 @@ jobs: # Coverage Report coverage-report: name: Combined Coverage Report - needs: [powershell-tests, rust-tests, elixir-tests, php-tests, typescript-tests] runs-on: ubuntu-latest timeout-minutes: 15 if: always() @@ -284,7 +275,6 @@ jobs: # Test Summary test-summary: name: Test Summary - needs: [powershell-tests, rust-tests, elixir-tests, php-tests, typescript-tests, e2e-tests] runs-on: ubuntu-latest timeout-minutes: 15 if: always() @@ -296,7 +286,6 @@ jobs: echo "Rust Tests: ${{ needs.rust-tests.result }}" echo "Elixir Tests: ${{ needs.elixir-tests.result }}" echo "PHP Tests: ${{ needs.php-tests.result }}" - echo "TypeScript Tests: ${{ needs.typescript-tests.result }}" echo "E2E Tests: ${{ needs.e2e-tests.result }}" - name: Fail if any test suite failed if: | @@ -304,6 +293,5 @@ jobs: needs.rust-tests.result == 'failure' || needs.elixir-tests.result == 'failure' || needs.php-tests.result == 'failure' || - needs.typescript-tests.result == 'failure' || needs.e2e-tests.result == 'failure' run: exit 1 diff --git a/praxis/.gitignore b/praxis/.gitignore index 45f10b1..7e40e94 100644 --- a/praxis/.gitignore +++ b/praxis/.gitignore @@ -37,7 +37,7 @@ erl_crash.dump *.jl.mem /Manifest.toml -# ReScript +# /lib/bs/ /.bsb.lock diff --git a/praxis/.nojekyll b/praxis/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/praxis/ABI-FFI-README.md b/praxis/ABI-FFI-README.md index ada05ff..d27c3ea 100644 --- a/praxis/ABI-FFI-README.md +++ b/praxis/ABI-FFI-README.md @@ -47,7 +47,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: ▼ ┌─────────────────────────────────────────────┐ │ Any Language via C ABI │ -│ - Rust, ReScript, Julia, Python, etc. │ +│ - Rust, , Julia, Python, etc. │ └─────────────────────────────────────────────┘ ``` @@ -79,7 +79,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: │ └── bindings/ # Language-specific wrappers (optional) ├── rust/ - ├── rescript/ + ├── / └── julia/ ``` @@ -343,8 +343,8 @@ zig build test-integration -- Runtime checks main : IO () main = do - verifyLayoutsCorrect - verifyAlignmentsCorrect + verifyLayouorrect + verifyAlignmenorrect putStrLn "ABI verification passed" ``` diff --git a/praxis/CHANGELOG.adoc b/praxis/CHANGELOG.adoc index e1fee0b..8ac7b73 100644 --- a/praxis/CHANGELOG.adoc +++ b/praxis/CHANGELOG.adoc @@ -54,7 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 56 pre-built query functions across 3 modules - Full OTP application structure with supervision -- **TypeScript Swarm System** (4,116 lines) +- ** Swarm System** (4,116 lines) - Distributed symbolic execution coordinator - Worker nodes with load balancing and health monitoring - WebSocket real-time communication (ws protocol) @@ -108,7 +108,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Rust: Cargo test (25+ tests) - Elixir: ExUnit (20+ tests) - PHP: PHPUnit (30+ tests) - - TypeScript: Bun test (40+ tests) + - : Bun test (40+ tests) - E2E: PowerShell integration tests (30+ tests) - GitHub Actions CI/CD pipeline configured diff --git a/praxis/CLAUDE.md b/praxis/CLAUDE.md index e4571a9..e869436 100644 --- a/praxis/CLAUDE.md +++ b/praxis/CLAUDE.md @@ -28,10 +28,10 @@ This is a **deliberately polyglot** project. Each language serves a specific pur | Macro Layer | LFE (Lisp Flavored Erlang) | Symbolic macro expansion, introspection | `rebar3` | | Execution Core | Rust | High-performance symbolic logic injection | `cargo` | | Introspection | Racket | Recursive feedback and semantic tracing | `racket` | -| Tooling | TypeScript + Bun | Manifest hygiene, validation, transformation | `bun` | +| Tooling | + Bun | Manifest hygiene, validation, transformation | `bun` | | WordPress Integration | PHP | Plugin wrapper and engine integration | N/A | | Symbolic Engine | PowerShell | Core symbolic operations and workflows | N/A | -| Web UI | HTML/TypeScript | Dashboard, visualizer, notebook interfaces | `bun` | +| Web UI | HTML/ | Dashboard, visualizer, notebook interfaces | `bun` | ## Directory Structure @@ -157,9 +157,9 @@ wp-praxis/ - Sanitize and validate all inputs - Use WordPress nonce verification for security -**TypeScript** (`SymbolicEngine/dashboard/`, `SymbolicEngine/swarm/`): +**** (`SymbolicEngine/dashboard/`, `SymbolicEngine/swarm/`): - Use Bun for runtime and tooling -- Follow TypeScript strict mode conventions +- Follow strict mode conventions - Prefer explicit types over `any` - Use modern ES modules @@ -178,7 +178,7 @@ mix deps.get mix compile mix test -# Build TypeScript components +# Build components cd SymbolicEngine/swarm bun install bun build @@ -328,7 +328,7 @@ The system: ``` Manifest (YAML/TOML) ↓ -Parser (TypeScript/Elixir) +Parser (/Elixir) ↓ CLI Orchestrator (Elixir) ↓ @@ -375,7 +375,7 @@ Introspection (Racket) 1. **Unit Tests** - Rust: `cargo test` - Elixir: `mix test` - - TypeScript: `bun test` + - : `bun test` 2. **Integration Tests** - Use `tests/run-tests.ps1` diff --git a/praxis/Core/introspection/docs/ARCHITECTURE.md b/praxis/Core/introspection/docs/ARCHITECTURE.md index d020ac6..7535ee4 100644 --- a/praxis/Core/introspection/docs/ARCHITECTURE.md +++ b/praxis/Core/introspection/docs/ARCHITECTURE.md @@ -57,7 +57,7 @@ The WP Praxis Introspection System is designed as a modular, functional system f **Layers Traced**: 1. Manifest (YAML/TOML) -2. Parser (TypeScript/Elixir) +2. Parser (/Elixir) 3. Orchestrator (Elixir) 4. Symbolic Engine (PowerShell) 5. Injector (Rust) diff --git a/praxis/Core/manifest-parser/README.md b/praxis/Core/manifest-parser/README.md index 5b8d21c..7306482 100644 --- a/praxis/Core/manifest-parser/README.md +++ b/praxis/Core/manifest-parser/README.md @@ -20,7 +20,7 @@ The WP Praxis Manifest Parser is a powerful, Lisp-based system for parsing, vali - **OTP Architecture**: Fault-tolerant concurrent processing with supervision - **Introspection**: Deep runtime reflection and analysis - **Optimization**: Dead code elimination, constant folding, dependency ordering -- **Integration**: Seamless interop with Elixir, Rust, TypeScript, and PHP +- **Integration**: Seamless interop with Elixir, Rust, , and PHP ## Features @@ -376,7 +376,7 @@ This parser is designed to integrate with: - **Rust Injector**: Performance-critical operations - **PHP Engine**: WordPress integration - **PowerShell Symbolic Engine**: Core symbolic operations -- **TypeScript Tools**: Manifest validation and transformation +- ** Tools**: Manifest validation and transformation See the [main WP Praxis README](../../README.md) for architecture overview. diff --git a/praxis/DEPENDENCY_AUDIT.md b/praxis/DEPENDENCY_AUDIT.md index ed4c65c..b6b2e32 100644 --- a/praxis/DEPENDENCY_AUDIT.md +++ b/praxis/DEPENDENCY_AUDIT.md @@ -84,7 +84,7 @@ Copyright (c) Jonathan D.A. Jewell --- -### 3. SymbolicEngine/swarm (TypeScript/Bun) +### 3. SymbolicEngine/swarm (/Bun) **Runtime Dependencies**: 6 @@ -98,7 +98,7 @@ Copyright (c) Jonathan D.A. Jewell | `winston` | 3.11.0 | Logging | Structured logging | ⚠️ | `console.*` (native) | 7/10 | **Dev Dependencies**: -- `@types/*`: TypeScript types (dev-only) +- `@types/*`: types (dev-only) - `bun-types`: Bun runtime types (dev-only) **Total**: 6 runtime dependencies @@ -133,7 +133,7 @@ Copyright (c) Jonathan D.A. Jewell --- -### 5. SymbolicEngine/dashboard (TypeScript/Bun) +### 5. SymbolicEngine/dashboard (/Bun) **Runtime Dependencies**: 5 @@ -147,7 +147,7 @@ Copyright (c) Jonathan D.A. Jewell --- -### 6. SymbolicEngine/graphql (TypeScript/Bun) +### 6. SymbolicEngine/graphql (/Bun) **Runtime Dependencies**: 4 @@ -169,9 +169,9 @@ Copyright (c) Jonathan D.A. Jewell |----------|-----------|--------------|----------|--------|--------| | **Rust** | wp_praxis_core (offline) | **0** | 0 | 0 | ✅ **Perfect** | | **Rust** | wp_injector | 13 | 1 | <10 | ⚠️ Over by 3 | -| **TypeScript** | swarm | 6 | 4 | <10 | ✅ Good | -| **TypeScript** | dashboard | 5 | 0 | <10 | ✅ Good | -| **TypeScript** | graphql | 4 | 0 | <10 | ✅ Excellent | +| **** | swarm | 6 | 4 | <10 | ✅ Good | +| **** | dashboard | 5 | 0 | <10 | ✅ Good | +| **** | graphql | 4 | 0 | <10 | ✅ Excellent | | **Elixir** | db-schema | 3 | 3 | <10 | ✅ Excellent | | **PHP** | plugin | ~5 | 0 | <10 | ✅ Good | | **PowerShell** | engine | 0 | 0 | 0 | ✅ Perfect | @@ -220,7 +220,7 @@ cargo audit # Zero high-severity vulnerabilities ``` -### TypeScript Dependencies +### Dependencies ```bash bun audit diff --git a/praxis/IMPLEMENTATION_SUMMARY.md b/praxis/IMPLEMENTATION_SUMMARY.md index cd0d7c2..0b39809 100644 --- a/praxis/IMPLEMENTATION_SUMMARY.md +++ b/praxis/IMPLEMENTATION_SUMMARY.md @@ -23,7 +23,7 @@ A **complete, production-ready** symbolic workflow system for WordPress across * |--------|-------| | **Total Files Created** | 3,251 | | **Total Lines Added** | 130,332 | -| **Languages Used** | 8 (PowerShell, Rust, Elixir, LFE, Racket, TypeScript, PHP, SQL) | +| **Languages Used** | 8 (PowerShell, Rust, Elixir, LFE, Racket, , PHP, SQL) | | **Core Components** | 12 | | **Test Files** | 26 | | **Tests Written** | 245+ | @@ -116,7 +116,7 @@ A **complete, production-ready** symbolic workflow system for WordPress across * --- -### 5. **TypeScript Swarm System** ✅ +### 5. ** Swarm System** ✅ **Location**: `SymbolicEngine/swarm/` **Lines of Code**: 4,116 **Tests**: 40+ test cases @@ -234,7 +234,7 @@ A **complete, production-ready** symbolic workflow system for WordPress across * - Rust: Cargo test (25+ tests) - Elixir: ExUnit (20+ tests) - PHP: PHPUnit (30+ tests) -- TypeScript: Bun test (40+ tests) +- : Bun test (40+ tests) - E2E: PowerShell integration tests (30+ tests) **CI/CD**: @@ -321,7 +321,7 @@ cd ../Core/db-schema mix deps.get mix ecto.setup -# 3. Install TypeScript dependencies +# 3. Install dependencies cd ../SymbolicEngine/swarm bun install @@ -406,7 +406,7 @@ cd Core/db-schema && mix test # PHP tests cd plugin && composer test -# TypeScript tests +# tests cd SymbolicEngine/swarm && bun test ``` @@ -522,7 +522,7 @@ Single workflow can dispatch to: ### Elixir - ecto_sql, postgrex, jason -### TypeScript/Bun +### /Bun - elysia, @apollo/server, chart.js, better-sqlite3, ws, yaml, toml ### PHP diff --git a/praxis/MAINTAINERS.md b/praxis/MAINTAINERS.md index bf50b2f..f6da569 100644 --- a/praxis/MAINTAINERS.md +++ b/praxis/MAINTAINERS.md @@ -28,7 +28,7 @@ Currently establishing. Future core team members will have: |-----------|-----------|--------|--------| | **PowerShell Engine** | *Seeking maintainer* | - | 🔍 Open | | **Rust Injector** | *Seeking maintainer* | - | 🔍 Open | -| **TypeScript Swarm** | *Seeking maintainer* | - | 🔍 Open | +| ** Swarm** | *Seeking maintainer* | - | 🔍 Open | | **Elixir/Ecto Schema** | *Seeking maintainer* | - | 🔍 Open | | **LFE Manifest Parser** | *Seeking maintainer* | - | 🔍 Open | | **Racket Introspection** | *Seeking maintainer* | - | 🔍 Open | diff --git a/praxis/README.adoc b/praxis/README.adoc index 607e9ce..6eb9944 100644 --- a/praxis/README.adoc +++ b/praxis/README.adoc @@ -18,7 +18,7 @@ WP Praxis transforms WordPress development by allowing you to define complex wor === Key Features - *🎯 Declarative Workflows* - Define WordPress operations in YAML/TOML, not code -- *🌐 True Polyglot* - 8 languages working together (Rust, Elixir, TypeScript, PHP, PowerShell, LFE, Racket, SQL) +- *🌐 True Polyglot* - 8 languages working together (Rust, Elixir, , PHP, PowerShell, LFE, Racket, SQL) - *🔄 Symbolic Dispatch* - Route operations based on semantic tags and context - *🛡️ Safe Execution* - Rollback support, transaction-like behavior, audit trails - *📊 Real-Time Monitoring* - WebSocket dashboards, GraphQL API, live statistics @@ -81,7 +81,7 @@ cd ../Core/db-schema mix deps.get mix ecto.setup -= 3. Install TypeScript dependencies += 3. Install dependencies image:https://img.shields.io/badge/License-MPL--2.0-blue.svg[License: PMPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] cd ../SymbolicEngine/swarm && bun install @@ -187,12 +187,12 @@ WP Praxis uses a layered polyglot architecture where each language serves a spec |-----------|----------|---------| | *Symbolic Engine* | PowerShell | Core workflow orchestration and dispatch | | *Injector* | Rust | High-performance WordPress database operations | -| *Swarm System* | TypeScript/Bun | Distributed execution coordinator | +| *Swarm System* | /Bun | Distributed execution coordinator | | *Manifest Parser* | LFE (Lisp) | YAML/TOML parsing with macro expansion | | *Introspection* | Racket | Recursive semantic analysis and feedback | | *Database Schema* | Elixir/Ecto | State management and persistence | -| *GraphQL API* | TypeScript | Unified API layer with subscriptions | -| *Dashboard* | TypeScript/HTML | Real-time monitoring and control | +| *GraphQL API* | | Unified API layer with subscriptions | +| *Dashboard* | /HTML | Real-time monitoring and control | | *WordPress Plugin* | PHP | WordPress integration and admin UI | == Documentation @@ -282,7 +282,7 @@ pwsh tests/run-tests.ps1 -Suite powershell # PowerShell tests cd wp_injector && cargo test # Rust tests cd Core/db-schema && mix test # Elixir tests cd plugin && composer test # PHP tests -cd SymbolicEngine/swarm && bun test # TypeScript tests +cd SymbolicEngine/swarm && bun test # tests ``` *Test Coverage*: 245+ tests across all layers (~78% coverage) @@ -291,7 +291,7 @@ cd SymbolicEngine/swarm && bun test # TypeScript tests WP Praxis aims for *Bronze-level* [Rhodium Standard Repository (RSR)](https://example.com/rsr) compliance: -- ✅ Type safety (Rust, TypeScript strict mode, Elixir specs) +- ✅ Type safety (Rust, strict mode, Elixir specs) - ✅ Memory safety (Rust ownership, no unsafe blocks in critical paths) - ⚠️ Offline-first (Partial - some components require network/database) - ✅ Complete documentation (20+ docs, tutorials, examples) @@ -343,7 +343,7 @@ See [CHANGELOG.md](CHANGELOG.md) for version history and release notes. == Acknowledgments Built with: -- Rust, Elixir, TypeScript/Bun, PHP, PowerShell, LFE, Racket +- Rust, Elixir, /Bun, PHP, PowerShell, LFE, Racket - PostgreSQL, SQLite, MySQL - Apollo Server, Elysia, Chart.js - WordPress, Ecto, Pester, PHPUnit diff --git a/praxis/RHODIUM_PLATINUM_ROADMAP.md b/praxis/RHODIUM_PLATINUM_ROADMAP.md index f6ad46b..ea42869 100644 --- a/praxis/RHODIUM_PLATINUM_ROADMAP.md +++ b/praxis/RHODIUM_PLATINUM_ROADMAP.md @@ -466,7 +466,7 @@ t!("errors.manifest_invalid", error = e.to_string()) ### 4.7 Community Governance **Establish**: -- [ ] Technical Steering Committee (TSC) +- [ ] Technical Steering Committee () - [ ] Regular community meetings - [ ] Roadmap voting process - [ ] RFC (Request for Comments) process diff --git a/praxis/RSR_COMPLIANCE.md b/praxis/RSR_COMPLIANCE.md index d7dfe3c..e5ab801 100644 --- a/praxis/RSR_COMPLIANCE.md +++ b/praxis/RSR_COMPLIANCE.md @@ -22,15 +22,15 @@ WP Praxis achieves **Partial Bronze** compliance with the Rhodium Standard Repos **Status**: **Fully Compliant** - **Rust**: Compile-time type checking, strong type system -- **TypeScript**: Strict mode enabled throughout (`strict: true` in tsconfig.json) +- ****: Strict mode enabled throughout (`strict: true` in onfig.json) - **Elixir**: Type specs with `@spec` annotations, Dialyzer support - **PHP**: Type hints and declarations (PHP 7.4+) - **PowerShell**: Type annotations where applicable **Evidence**: -- `wp_injector/tsconfig.json`: `"strict": true` +- `wp_injector/onfig.json`: `"strict": true` - `Core/db-schema/`: Elixir `@spec` annotations on all public functions -- `SymbolicEngine/swarm/src/types.ts`: Comprehensive TypeScript interfaces +- `SymbolicEngine/swarm/src/types.ts`: Comprehensive interfaces **Score**: ✅ **10/10** @@ -42,7 +42,7 @@ WP Praxis achieves **Partial Bronze** compliance with the Rhodium Standard Repos - **Rust Components**: Zero `unsafe` blocks in production code - **Ownership Model**: Rust's borrow checker prevents memory issues -- **Managed Languages**: Elixir, TypeScript, PHP have automatic memory management +- **Managed Languages**: Elixir, , PHP have automatic memory management **Evidence**: ```bash @@ -172,7 +172,7 @@ just test-all # Run all tests - Rust: 24 tests (cargo test) - Elixir: 20+ tests (ExUnit) - PHP: 30+ tests (PHPUnit) -- TypeScript: 40+ tests (Bun test) +- : 40+ tests (Bun test) - E2E: 30+ tests (PowerShell integration) **Coverage**: ~78% overall @@ -227,7 +227,7 @@ just test-all **Dependency Count**: - **Rust**: 50+ crates (clap, serde, sqlx, tokio, anyhow, etc.) -- **TypeScript**: 30+ npm packages (Apollo, Elysia, Chart.js, etc.) +- ****: 30+ npm packages (Apollo, Elysia, Chart.js, etc.) - **Elixir**: 5+ hex packages (ecto, postgrex, jason) - **PHP**: 5+ composer packages (symfony/yaml, WordPress functions) @@ -281,7 +281,7 @@ diff hash1.txt hash2.txt # Should be identical **Status**: **Fully Compliant** -**Language Count**: **8** (Rust, Elixir, TypeScript, PHP, PowerShell, LFE, Racket, SQL) +**Language Count**: **8** (Rust, Elixir, , PHP, PowerShell, LFE, Racket, SQL) **Compositional Correctness**: - ✅ **Type-safe boundaries**: JSON/TOML schemas enforced across languages diff --git a/praxis/RSR_IMPLEMENTATION.md b/praxis/RSR_IMPLEMENTATION.md index 6a18d4d..48f9ebd 100644 --- a/praxis/RSR_IMPLEMENTATION.md +++ b/praxis/RSR_IMPLEMENTATION.md @@ -93,7 +93,7 @@ Copyright (c) Jonathan D.A. Jewell ### Build Automation 1. **justfile** (400+ lines, 30+ tasks) - - Build tasks (all, rust, elixir, typescript, php, lfe) + - Build tasks (all, rust, elixir, , php, lfe) - Test tasks (all, per-language, integration, e2e) - Lint and format tasks - Database tasks (setup, migrate, seed, reset) @@ -123,7 +123,7 @@ Copyright (c) Jonathan D.A. Jewell | Category | Score | Notes | |----------|-------|-------| -| Type Safety | 10/10 | Rust, TypeScript strict, Elixir specs | +| Type Safety | 10/10 | Rust, strict, Elixir specs | | Memory Safety | 10/10 | Zero unsafe Rust, ownership model | | Documentation | 10/10 | All required files + 20+ guides | | .well-known/ | 10/10 | RFC 9116 + ai.txt + humans.txt | @@ -174,7 +174,7 @@ Copyright (c) Jonathan D.A. Jewell **Reality**: Production system with 50+ dependencies: - **Rust**: sqlx, tokio, serde, clap, anyhow, chrono, etc. -- **TypeScript**: Apollo, Elysia, Chart.js, WebSocket libraries +- ****: Apollo, Elysia, Chart.js, WebSocket libraries - **Elixir**: Ecto, Postgrex, Jason - **PHP**: Symfony YAML, WordPress functions diff --git a/praxis/RSR_OUTLINE.adoc b/praxis/RSR_OUTLINE.adoc index 0ad555a..036001f 100644 --- a/praxis/RSR_OUTLINE.adoc +++ b/praxis/RSR_OUTLINE.adoc @@ -148,7 +148,7 @@ project/ === Language Tiers -* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, ReScript +* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, * **Tier 2** (Silver): Nickel, Racket, Guile Scheme, Nix * **Infrastructure**: Guix channels, derivations @@ -168,7 +168,7 @@ project/ === Prohibited * Python outside `salt/` directory -* TypeScript/JavaScript (use ReScript) +* /JavaScript (use ) * CUE (use Guile/Nickel) * `Dockerfile` (use `Containerfile`) diff --git a/praxis/SECURITY.md b/praxis/SECURITY.md index 21ba040..f3cb2c7 100644 --- a/praxis/SECURITY.md +++ b/praxis/SECURITY.md @@ -37,7 +37,7 @@ WP Praxis implements multiple layers of security: ### 3. Memory Safety - **Rust Components**: Zero `unsafe` blocks in production code, ownership model prevents memory issues -- **Type Safety**: Strong typing in Rust, TypeScript strict mode, Elixir specs +- **Type Safety**: Strong typing in Rust, strict mode, Elixir specs ### 4. Database Security diff --git a/praxis/SymbolicEngine/dashboard/README.md b/praxis/SymbolicEngine/dashboard/README.md index ca25c1b..52a184a 100644 --- a/praxis/SymbolicEngine/dashboard/README.md +++ b/praxis/SymbolicEngine/dashboard/README.md @@ -4,7 +4,7 @@ Copyright (c) Jonathan D.A. Jewell --> # WP Praxis Symbolic Engine Dashboard -Complete real-time monitoring and control interface for the WP Praxis symbolic workflow system. Built with Bun, TypeScript, Elysia, and PostgreSQL. +Complete real-time monitoring and control interface for the WP Praxis symbolic workflow system. Built with Bun, , Elysia, and PostgreSQL. ## Features @@ -32,7 +32,7 @@ Complete real-time monitoring and control interface for the WP Praxis symbolic w - **Framework**: Elysia (Fast web framework) - **Database**: PostgreSQL (Ecto database integration) - **WebSockets**: Native Bun WebSocket support -- **Frontend**: TypeScript, Chart.js +- **Frontend**: , Chart.js - **Styling**: Modern CSS with CSS variables for theming ## Installation @@ -396,7 +396,7 @@ dashboard/ │ ├── websocket/ # WebSocket handlers │ │ ├── dashboard-events.ts │ │ └── stream-handler.ts -│ ├── types/ # TypeScript types +│ ├── types/ # types │ ├── api-server.ts # Main server │ └── config-loader.ts # Configuration loader ├── js/ # Frontend JavaScript @@ -411,7 +411,7 @@ dashboard/ │ └── index.html ├── index.html # Main dashboard HTML ├── package.json -├── tsconfig.json +├── onfig.json └── dashboard-config.toml ``` diff --git a/praxis/SymbolicEngine/dashboard/deno.json b/praxis/SymbolicEngine/dashboard/deno.json deleted file mode 100644 index 82255ca..0000000 --- a/praxis/SymbolicEngine/dashboard/deno.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "@wp-praxis/dashboard", - "version": "0.1.0", - "tasks": { - "build": "deno run --node-modules-dir=auto -A npm:rescript", - "dev": "deno run --node-modules-dir=auto -A npm:rescript -w", - "clean": "deno run --node-modules-dir=auto -A npm:rescript clean" - }, - "imports": { - "rescript": "npm:rescript@^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.1", - "@rescript/runtime/": "npm:/@rescript/runtime@12.2.0/", - "elysia": "npm:elysia@latest", - "@elysiajs/cors": "npm:@elysiajs/cors@latest" - } -} diff --git a/praxis/SymbolicEngine/dashboard/deno.lock b/praxis/SymbolicEngine/dashboard/deno.lock deleted file mode 100644 index 11bd4a4..0000000 --- a/praxis/SymbolicEngine/dashboard/deno.lock +++ /dev/null @@ -1,1054 +0,0 @@ -{ - "version": "5", - "specifiers": { - "npm:@elysiajs/cors@1": "1.4.1_elysia@1.4.27__@sinclair+typebox@0.34.48__@types+bun@1.3.10__exact-mirror@0.2.7___@sinclair+typebox@0.34.48__file-type@21.3.0__openapi-types@12.1.3_@types+bun@1.3.10", - "npm:@elysiajs/cors@latest": "1.4.1_elysia@1.4.27__@sinclair+typebox@0.34.48__@types+bun@1.3.10__exact-mirror@0.2.7___@sinclair+typebox@0.34.48__file-type@21.3.0__openapi-types@12.1.3_@types+bun@1.3.10", - "npm:@elysiajs/html@1": "1.4.0_elysia@1.4.27__@sinclair+typebox@0.34.48__@types+bun@1.3.10__exact-mirror@0.2.7___@sinclair+typebox@0.34.48__file-type@21.3.0__openapi-types@12.1.3_@kitajs+html@4.2.13_@types+bun@1.3.10", - "npm:@elysiajs/static@1": "1.4.7_elysia@1.4.27__@sinclair+typebox@0.34.48__@types+bun@1.3.10__exact-mirror@0.2.7___@sinclair+typebox@0.34.48__file-type@21.3.0__openapi-types@12.1.3_@types+bun@1.3.10", - "npm:@rescript/core@^1.6.1": "1.6.1_rescript@12.2.0", - "npm:@rescript/runtime@12.2.0": "12.2.0", - "npm:@types/bun@latest": "1.3.10", - "npm:@types/ws@^8.5.10": "8.18.1", - "npm:@typescript-eslint/eslint-plugin@^6.19.0": "6.21.0_@typescript-eslint+parser@6.21.0__eslint@8.57.1_eslint@8.57.1", - "npm:@typescript-eslint/parser@^6.19.0": "6.21.0_eslint@8.57.1", - "npm:bun-types@latest": "1.3.10", - "npm:elysia@1": "1.4.27_@sinclair+typebox@0.34.48_@types+bun@1.3.10_exact-mirror@0.2.7__@sinclair+typebox@0.34.48_file-type@21.3.0_openapi-types@12.1.3", - "npm:elysia@latest": "1.4.27_@sinclair+typebox@0.34.48_@types+bun@1.3.10_exact-mirror@0.2.7__@sinclair+typebox@0.34.48_file-type@21.3.0_openapi-types@12.1.3", - "npm:eslint@^8.56.0": "8.57.1", - "npm:postgres@^3.4.3": "3.4.8", - "npm:prettier@^3.2.4": "3.8.1", - "npm:rescript@*": "12.2.0", - "npm:rescript@12": "12.2.0", - "npm:ws@^8.16.0": "8.19.0", - "npm:zod@^3.22.4": "3.25.76" - }, - "npm": { - "@borewit/text-codec@0.2.1": { - "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==" - }, - "@elysiajs/cors@1.4.1_elysia@1.4.27__@sinclair+typebox@0.34.48__@types+bun@1.3.10__exact-mirror@0.2.7___@sinclair+typebox@0.34.48__file-type@21.3.0__openapi-types@12.1.3_@types+bun@1.3.10": { - "integrity": "sha512-lQfad+F3r4mNwsxRKbXyJB8Jg43oAOXjRwn7sKUL6bcOW3KjUqUimTS+woNpO97efpzjtDE0tEjGk9DTw8lqTQ==", - "dependencies": [ - "elysia" - ] - }, - "@elysiajs/html@1.4.0_elysia@1.4.27__@sinclair+typebox@0.34.48__@types+bun@1.3.10__exact-mirror@0.2.7___@sinclair+typebox@0.34.48__file-type@21.3.0__openapi-types@12.1.3_@kitajs+html@4.2.13_@types+bun@1.3.10": { - "integrity": "sha512-j4jFqGEkIC8Rg2XiTOujb9s0WLnz1dnY/4uqczyCdOVruDeJtGP+6+GvF0A76SxEvltn8UR1yCUnRdLqRi3vuw==", - "dependencies": [ - "@kitajs/html", - "@kitajs/ts-html-plugin", - "elysia" - ], - "optionalPeers": [ - "@kitajs/html", - "@kitajs/ts-html-plugin" - ] - }, - "@elysiajs/static@1.4.7_elysia@1.4.27__@sinclair+typebox@0.34.48__@types+bun@1.3.10__exact-mirror@0.2.7___@sinclair+typebox@0.34.48__file-type@21.3.0__openapi-types@12.1.3_@types+bun@1.3.10": { - "integrity": "sha512-Go4kIXZ0G3iWfkAld07HmLglqIDMVXdyRKBQK/sVEjtpDdjHNb+rUIje73aDTWpZYg4PEVHUpi9v4AlNEwrQug==", - "dependencies": [ - "elysia" - ] - }, - "@eslint-community/eslint-utils@4.9.1_eslint@8.57.1": { - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dependencies": [ - "eslint", - "eslint-visitor-keys" - ] - }, - "@eslint-community/regexpp@4.12.2": { - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==" - }, - "@eslint/eslintrc@2.1.4": { - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dependencies": [ - "ajv", - "debug", - "espree", - "globals", - "ignore", - "import-fresh", - "js-yaml", - "minimatch@3.1.5", - "strip-json-comments" - ] - }, - "@eslint/js@8.57.1": { - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==" - }, - "@humanwhocodes/config-array@0.13.0": { - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "dependencies": [ - "@humanwhocodes/object-schema", - "debug", - "minimatch@3.1.5" - ], - "deprecated": true - }, - "@humanwhocodes/module-importer@1.0.1": { - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" - }, - "@humanwhocodes/object-schema@2.0.3": { - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": true - }, - "@kitajs/html@4.2.13": { - "integrity": "sha512-o+8e61EsoLDPTP7rsPkYolca1YFybHuxU2Lr5fWDZCUkYT/6uBlVkvnZUdCXMQKentJL9dxwpR8/xK2Q+U4LhA==", - "dependencies": [ - "csstype" - ] - }, - "@kitajs/ts-html-plugin@4.1.4_@kitajs+html@4.2.13_typescript@5.9.3": { - "integrity": "sha512-xK5mNrhnIy73kJFKx5yVGChJyWFRGmIaE0sjlVxVYllk5dyaEYVCrIh1N8AfnseEHka8gAqzPGW95HlkhDvnJA==", - "dependencies": [ - "@kitajs/html", - "chalk@5.6.2", - "tslib", - "typescript", - "yargs" - ], - "bin": true - }, - "@nodelib/fs.scandir@2.1.5": { - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": [ - "@nodelib/fs.stat", - "run-parallel" - ] - }, - "@nodelib/fs.stat@2.0.5": { - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk@1.2.8": { - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": [ - "@nodelib/fs.scandir", - "fastq" - ] - }, - "@rescript/core@1.6.1_rescript@12.2.0": { - "integrity": "sha512-vyb5k90ck+65Fgui+5vCja/mUfzKaK3kOPT4Z6aAJdHLH1eljEi1zKhXroCiCtpNLSWp8k4ulh1bdB5WS0hvqA==", - "dependencies": [ - "rescript" - ] - }, - "@rescript/darwin-arm64@12.2.0": { - "integrity": "sha512-xc3K/J7Ujl1vPiFY2009mRf3kWRlUe/VZyJWprseKxlcEtUQv89ter7r6pY+YFbtYvA/fcaEncL9CVGEdattAg==", - "os": ["darwin"], - "cpu": ["arm64"] - }, - "@rescript/darwin-x64@12.2.0": { - "integrity": "sha512-qqcTvnlSeoKkywLjG7cXfYvKZ1e4Gz2kUKcD6SiqDgCqm8TF+spwlFAiM6sloRUOFsc0bpC/0R0B3yr01FCB1A==", - "os": ["darwin"], - "cpu": ["x64"] - }, - "@rescript/linux-arm64@12.2.0": { - "integrity": "sha512-ODmpG3ji+Nj/8d5yvXkeHlfKkmbw1Q4t1iIjVuNwtmFpz7TiEa7n/sQqoYdE+WzbDX3DoJfmJNbp3Ob7qCUoOg==", - "os": ["linux"], - "cpu": ["arm64"] - }, - "@rescript/linux-x64@12.2.0": { - "integrity": "sha512-2W9Y9/g19Y4F/subl8yV3T8QBG2oRaP+HciNRcBjptyEdw9LmCKH8+rhWO6sp3E+nZLwoE2IAkwH0WKV3wqlxQ==", - "os": ["linux"], - "cpu": ["x64"] - }, - "@rescript/runtime@12.2.0": { - "integrity": "sha512-NwfljDRq1rjFPHUaca1nzFz13xsa9ZGkBkLvMhvVgavJT5+A4rMcLu8XAaVTi/oAhO/tlHf9ZDoOTF1AfyAk9Q==" - }, - "@rescript/win32-x64@12.2.0": { - "integrity": "sha512-fhf8CBj3p1lkIXPeNko3mVTKQfXXm4BoxJtR1xAXxUn43wDpd8Lox4w8/EPBbbW6C/YFQW6H7rtpY+2AKuNaDA==", - "os": ["win32"], - "cpu": ["x64"] - }, - "@sinclair/typebox@0.34.48": { - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==" - }, - "@tokenizer/inflate@0.4.1": { - "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", - "dependencies": [ - "debug", - "token-types" - ] - }, - "@tokenizer/token@0.3.0": { - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" - }, - "@types/bun@1.3.10": { - "integrity": "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ==", - "dependencies": [ - "bun-types" - ] - }, - "@types/json-schema@7.0.15": { - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "@types/node@25.3.3": { - "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", - "dependencies": [ - "undici-types" - ] - }, - "@types/semver@7.7.1": { - "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==" - }, - "@types/ws@8.18.1": { - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dependencies": [ - "@types/node" - ] - }, - "@typescript-eslint/eslint-plugin@6.21.0_@typescript-eslint+parser@6.21.0__eslint@8.57.1_eslint@8.57.1": { - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", - "dependencies": [ - "@eslint-community/regexpp", - "@typescript-eslint/parser", - "@typescript-eslint/scope-manager", - "@typescript-eslint/type-utils", - "@typescript-eslint/utils", - "@typescript-eslint/visitor-keys", - "debug", - "eslint", - "graphemer", - "ignore", - "natural-compare", - "semver", - "ts-api-utils" - ] - }, - "@typescript-eslint/parser@6.21.0_eslint@8.57.1": { - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dependencies": [ - "@typescript-eslint/scope-manager", - "@typescript-eslint/types", - "@typescript-eslint/typescript-estree", - "@typescript-eslint/visitor-keys", - "debug", - "eslint" - ] - }, - "@typescript-eslint/scope-manager@6.21.0": { - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dependencies": [ - "@typescript-eslint/types", - "@typescript-eslint/visitor-keys" - ] - }, - "@typescript-eslint/type-utils@6.21.0_eslint@8.57.1": { - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", - "dependencies": [ - "@typescript-eslint/typescript-estree", - "@typescript-eslint/utils", - "debug", - "eslint", - "ts-api-utils" - ] - }, - "@typescript-eslint/types@6.21.0": { - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==" - }, - "@typescript-eslint/typescript-estree@6.21.0": { - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dependencies": [ - "@typescript-eslint/types", - "@typescript-eslint/visitor-keys", - "debug", - "globby", - "is-glob", - "minimatch@9.0.3", - "semver", - "ts-api-utils" - ] - }, - "@typescript-eslint/utils@6.21.0_eslint@8.57.1": { - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dependencies": [ - "@eslint-community/eslint-utils", - "@types/json-schema", - "@types/semver", - "@typescript-eslint/scope-manager", - "@typescript-eslint/types", - "@typescript-eslint/typescript-estree", - "eslint", - "semver" - ] - }, - "@typescript-eslint/visitor-keys@6.21.0": { - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dependencies": [ - "@typescript-eslint/types", - "eslint-visitor-keys" - ] - }, - "@ungap/structured-clone@1.3.0": { - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==" - }, - "acorn-jsx@5.3.2_acorn@8.16.0": { - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dependencies": [ - "acorn" - ] - }, - "acorn@8.16.0": { - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "bin": true - }, - "ajv@6.14.0": { - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", - "dependencies": [ - "fast-deep-equal", - "fast-json-stable-stringify", - "json-schema-traverse", - "uri-js" - ] - }, - "ansi-regex@5.0.1": { - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-regex@6.2.2": { - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" - }, - "ansi-styles@4.3.0": { - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": [ - "color-convert" - ] - }, - "ansi-styles@6.2.3": { - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" - }, - "argparse@2.0.1": { - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "array-union@2.1.0": { - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "balanced-match@1.0.2": { - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion@1.1.12": { - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dependencies": [ - "balanced-match", - "concat-map" - ] - }, - "brace-expansion@2.0.2": { - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dependencies": [ - "balanced-match" - ] - }, - "braces@3.0.3": { - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": [ - "fill-range" - ] - }, - "bun-types@1.3.10": { - "integrity": "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg==", - "dependencies": [ - "@types/node" - ] - }, - "callsites@3.1.0": { - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "chalk@4.1.2": { - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": [ - "ansi-styles@4.3.0", - "supports-color" - ] - }, - "chalk@5.6.2": { - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==" - }, - "cliui@9.0.1": { - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", - "dependencies": [ - "string-width", - "strip-ansi@7.2.0", - "wrap-ansi" - ] - }, - "color-convert@2.0.1": { - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": [ - "color-name" - ] - }, - "color-name@1.1.4": { - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "concat-map@0.0.1": { - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "cookie@1.1.1": { - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==" - }, - "cross-spawn@7.0.6": { - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dependencies": [ - "path-key", - "shebang-command", - "which" - ] - }, - "csstype@3.2.3": { - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==" - }, - "debug@4.4.3": { - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dependencies": [ - "ms" - ] - }, - "deep-is@0.1.4": { - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "dir-glob@3.0.1": { - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": [ - "path-type" - ] - }, - "doctrine@3.0.0": { - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": [ - "esutils" - ] - }, - "elysia@1.4.27_@sinclair+typebox@0.34.48_@types+bun@1.3.10_exact-mirror@0.2.7__@sinclair+typebox@0.34.48_file-type@21.3.0_openapi-types@12.1.3": { - "integrity": "sha512-2UlmNEjPJVA/WZVPYKy+KdsrfFwwNlqSBW1lHz6i2AHc75k7gV4Rhm01kFeotH7PDiHIX2G8X3KnRPc33SGVIg==", - "dependencies": [ - "@sinclair/typebox", - "@types/bun", - "cookie", - "exact-mirror", - "fast-decode-uri-component", - "file-type", - "memoirist", - "openapi-types" - ], - "optionalPeers": [ - "@types/bun" - ] - }, - "emoji-regex@10.6.0": { - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" - }, - "escalade@3.2.0": { - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" - }, - "escape-string-regexp@4.0.0": { - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - }, - "eslint-scope@7.2.2": { - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dependencies": [ - "esrecurse", - "estraverse" - ] - }, - "eslint-visitor-keys@3.4.3": { - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==" - }, - "eslint@8.57.1": { - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "dependencies": [ - "@eslint-community/eslint-utils", - "@eslint-community/regexpp", - "@eslint/eslintrc", - "@eslint/js", - "@humanwhocodes/config-array", - "@humanwhocodes/module-importer", - "@nodelib/fs.walk", - "@ungap/structured-clone", - "ajv", - "chalk@4.1.2", - "cross-spawn", - "debug", - "doctrine", - "escape-string-regexp", - "eslint-scope", - "eslint-visitor-keys", - "espree", - "esquery", - "esutils", - "fast-deep-equal", - "file-entry-cache", - "find-up", - "glob-parent@6.0.2", - "globals", - "graphemer", - "ignore", - "imurmurhash", - "is-glob", - "is-path-inside", - "js-yaml", - "json-stable-stringify-without-jsonify", - "levn", - "lodash.merge", - "minimatch@3.1.5", - "natural-compare", - "optionator", - "strip-ansi@6.0.1", - "text-table" - ], - "deprecated": true, - "bin": true - }, - "espree@9.6.1_acorn@8.16.0": { - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dependencies": [ - "acorn", - "acorn-jsx", - "eslint-visitor-keys" - ] - }, - "esquery@1.7.0": { - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "dependencies": [ - "estraverse" - ] - }, - "esrecurse@4.3.0": { - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": [ - "estraverse" - ] - }, - "estraverse@5.3.0": { - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" - }, - "esutils@2.0.3": { - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "exact-mirror@0.2.7_@sinclair+typebox@0.34.48": { - "integrity": "sha512-+MeEmDcLA4o/vjK2zujgk+1VTxPR4hdp23qLqkWfStbECtAq9gmsvQa3LW6z/0GXZyHJobrCnmy1cdeE7BjsYg==", - "dependencies": [ - "@sinclair/typebox" - ], - "optionalPeers": [ - "@sinclair/typebox" - ] - }, - "fast-decode-uri-component@1.0.1": { - "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" - }, - "fast-deep-equal@3.1.3": { - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-glob@3.3.3": { - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dependencies": [ - "@nodelib/fs.stat", - "@nodelib/fs.walk", - "glob-parent@5.1.2", - "merge2", - "micromatch" - ] - }, - "fast-json-stable-stringify@2.1.0": { - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein@2.0.6": { - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "fastq@1.20.1": { - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dependencies": [ - "reusify" - ] - }, - "file-entry-cache@6.0.1": { - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dependencies": [ - "flat-cache" - ] - }, - "file-type@21.3.0": { - "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", - "dependencies": [ - "@tokenizer/inflate", - "strtok3", - "token-types", - "uint8array-extras" - ] - }, - "fill-range@7.1.1": { - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": [ - "to-regex-range" - ] - }, - "find-up@5.0.0": { - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": [ - "locate-path", - "path-exists" - ] - }, - "flat-cache@3.2.0": { - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dependencies": [ - "flatted", - "keyv", - "rimraf" - ] - }, - "flatted@3.3.4": { - "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==" - }, - "fs.realpath@1.0.0": { - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "get-caller-file@2.0.5": { - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-east-asian-width@1.5.0": { - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==" - }, - "glob-parent@5.1.2": { - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": [ - "is-glob" - ] - }, - "glob-parent@6.0.2": { - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": [ - "is-glob" - ] - }, - "glob@7.2.3": { - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": [ - "fs.realpath", - "inflight", - "inherits", - "minimatch@3.1.5", - "once", - "path-is-absolute" - ], - "deprecated": true - }, - "globals@13.24.0": { - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": [ - "type-fest" - ] - }, - "globby@11.1.0": { - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": [ - "array-union", - "dir-glob", - "fast-glob", - "ignore", - "merge2", - "slash" - ] - }, - "graphemer@1.4.0": { - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "has-flag@4.0.0": { - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "ieee754@1.2.1": { - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore@5.3.2": { - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==" - }, - "import-fresh@3.3.1": { - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dependencies": [ - "parent-module", - "resolve-from" - ] - }, - "imurmurhash@0.1.4": { - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" - }, - "inflight@1.0.6": { - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": [ - "once", - "wrappy" - ], - "deprecated": true - }, - "inherits@2.0.4": { - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-extglob@2.1.1": { - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-glob@4.0.3": { - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": [ - "is-extglob" - ] - }, - "is-number@7.0.0": { - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-path-inside@3.0.3": { - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" - }, - "isexe@2.0.0": { - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "js-yaml@4.1.1": { - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dependencies": [ - "argparse" - ], - "bin": true - }, - "json-buffer@3.0.1": { - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "json-schema-traverse@0.4.1": { - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify@1.0.1": { - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" - }, - "keyv@4.5.4": { - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": [ - "json-buffer" - ] - }, - "levn@0.4.1": { - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dependencies": [ - "prelude-ls", - "type-check" - ] - }, - "locate-path@6.0.0": { - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": [ - "p-locate" - ] - }, - "lodash.merge@4.6.2": { - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "memoirist@0.4.0": { - "integrity": "sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg==" - }, - "merge2@1.4.1": { - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromatch@4.0.8": { - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": [ - "braces", - "picomatch" - ] - }, - "minimatch@3.1.5": { - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dependencies": [ - "brace-expansion@1.1.12" - ] - }, - "minimatch@9.0.3": { - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dependencies": [ - "brace-expansion@2.0.2" - ] - }, - "ms@2.1.3": { - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "natural-compare@1.4.0": { - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "once@1.4.0": { - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": [ - "wrappy" - ] - }, - "openapi-types@12.1.3": { - "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==" - }, - "optionator@0.9.4": { - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dependencies": [ - "deep-is", - "fast-levenshtein", - "levn", - "prelude-ls", - "type-check", - "word-wrap" - ] - }, - "p-limit@3.1.0": { - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": [ - "yocto-queue" - ] - }, - "p-locate@5.0.0": { - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": [ - "p-limit" - ] - }, - "parent-module@1.0.1": { - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": [ - "callsites" - ] - }, - "path-exists@4.0.0": { - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-is-absolute@1.0.1": { - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-key@3.1.1": { - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-type@4.0.0": { - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "picomatch@2.3.1": { - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "postgres@3.4.8": { - "integrity": "sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==" - }, - "prelude-ls@1.2.1": { - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" - }, - "prettier@3.8.1": { - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", - "bin": true - }, - "punycode@2.3.1": { - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" - }, - "queue-microtask@1.2.3": { - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "rescript@12.2.0": { - "integrity": "sha512-1Jf2cmNhyx5Mj2vwZ4XXPcXvNSjGj9D1jPBUcoqIOqRpLPo1ch2Ta/7eWh23xAHWHK5ow7BCDyYFjvZSjyjLzg==", - "dependencies": [ - "@rescript/runtime" - ], - "optionalDependencies": [ - "@rescript/darwin-arm64", - "@rescript/darwin-x64", - "@rescript/linux-arm64", - "@rescript/linux-x64", - "@rescript/win32-x64" - ], - "bin": true - }, - "resolve-from@4.0.0": { - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "reusify@1.1.0": { - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==" - }, - "rimraf@3.0.2": { - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": [ - "glob" - ], - "deprecated": true, - "bin": true - }, - "run-parallel@1.2.0": { - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dependencies": [ - "queue-microtask" - ] - }, - "semver@7.7.4": { - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "bin": true - }, - "shebang-command@2.0.0": { - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": [ - "shebang-regex" - ] - }, - "shebang-regex@3.0.0": { - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "slash@3.0.0": { - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "string-width@7.2.0": { - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dependencies": [ - "emoji-regex", - "get-east-asian-width", - "strip-ansi@7.2.0" - ] - }, - "strip-ansi@6.0.1": { - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": [ - "ansi-regex@5.0.1" - ] - }, - "strip-ansi@7.2.0": { - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "dependencies": [ - "ansi-regex@6.2.2" - ] - }, - "strip-json-comments@3.1.1": { - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "strtok3@10.3.4": { - "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", - "dependencies": [ - "@tokenizer/token" - ] - }, - "supports-color@7.2.0": { - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": [ - "has-flag" - ] - }, - "text-table@0.2.0": { - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "to-regex-range@5.0.1": { - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": [ - "is-number" - ] - }, - "token-types@6.1.2": { - "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", - "dependencies": [ - "@borewit/text-codec", - "@tokenizer/token", - "ieee754" - ] - }, - "ts-api-utils@1.4.3_typescript@5.9.3": { - "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", - "dependencies": [ - "typescript" - ] - }, - "tslib@2.8.1": { - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, - "type-check@0.4.0": { - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dependencies": [ - "prelude-ls" - ] - }, - "type-fest@0.20.2": { - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" - }, - "typescript@5.9.3": { - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "bin": true - }, - "uint8array-extras@1.5.0": { - "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==" - }, - "undici-types@7.18.2": { - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==" - }, - "uri-js@4.4.1": { - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": [ - "punycode" - ] - }, - "which@2.0.2": { - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": [ - "isexe" - ], - "bin": true - }, - "word-wrap@1.2.5": { - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" - }, - "wrap-ansi@9.0.2": { - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "dependencies": [ - "ansi-styles@6.2.3", - "string-width", - "strip-ansi@7.2.0" - ] - }, - "wrappy@1.0.2": { - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "ws@8.19.0": { - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==" - }, - "y18n@5.0.8": { - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs-parser@22.0.0": { - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==" - }, - "yargs@18.0.0": { - "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", - "dependencies": [ - "cliui", - "escalade", - "get-caller-file", - "string-width", - "y18n", - "yargs-parser" - ] - }, - "yocto-queue@0.1.0": { - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - }, - "zod@3.25.76": { - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==" - } - }, - "workspace": { - "dependencies": [ - "npm:@elysiajs/cors@latest", - "npm:@rescript/core@^1.6.1", - "npm:@rescript/runtime@12.2.0", - "npm:elysia@latest", - "npm:rescript@12" - ], - "packageJson": { - "dependencies": [ - "npm:@elysiajs/cors@1", - "npm:@elysiajs/html@1", - "npm:@elysiajs/static@1", - "npm:@types/bun@latest", - "npm:@types/ws@^8.5.10", - "npm:@typescript-eslint/eslint-plugin@^6.19.0", - "npm:@typescript-eslint/parser@^6.19.0", - "npm:bun-types@latest", - "npm:elysia@1", - "npm:eslint@^8.56.0", - "npm:postgres@^3.4.3", - "npm:prettier@^3.2.4", - "npm:ws@^8.16.0", - "npm:zod@^3.22.4" - ] - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/injector/js/injector.ts b/praxis/SymbolicEngine/dashboard/injector/js/injector.ts deleted file mode 100644 index 23e578a..0000000 --- a/praxis/SymbolicEngine/dashboard/injector/js/injector.ts +++ /dev/null @@ -1,430 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Injector Dashboard - * Symbolic injection and rollback interface - */ - -const API_BASE = window.location.origin + '/api'; - -// State -let manifestData: any = null; -let currentInjection: any = null; - -/** - * Initialize injector dashboard - */ -function initInjector() { - console.log('[Injector] Initializing...'); - - setupTheme(); - setupFileUpload(); - setupFormHandlers(); - loadWorkflows(); - loadInjectionHistory(); - - console.log('[Injector] Ready'); -} - -/** - * Setup theme toggle - */ -function setupTheme() { - const themeToggle = document.getElementById('theme-toggle'); - const html = document.documentElement; - - const savedTheme = localStorage.getItem('theme'); - const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - const theme = savedTheme || (systemDark ? 'dark' : 'light'); - html.setAttribute('data-theme', theme); - - themeToggle?.addEventListener('click', () => { - const currentTheme = html.getAttribute('data-theme'); - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - html.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); - }); -} - -/** - * Setup file upload - */ -function setupFileUpload() { - const uploadArea = document.getElementById('manifest-upload'); - const fileInput = document.getElementById('manifest-file') as HTMLInputElement; - - uploadArea?.addEventListener('click', () => fileInput?.click()); - - fileInput?.addEventListener('change', (e) => { - const file = (e.target as HTMLInputElement).files?.[0]; - if (file) { - handleManifestFile(file); - } - }); - - // Drag and drop - uploadArea?.addEventListener('dragover', (e) => { - e.preventDefault(); - uploadArea.classList.add('dragover'); - }); - - uploadArea?.addEventListener('dragleave', () => { - uploadArea?.classList.remove('dragover'); - }); - - uploadArea?.addEventListener('drop', (e) => { - e.preventDefault(); - uploadArea?.classList.remove('dragover'); - - const file = e.dataTransfer?.files[0]; - if (file) { - handleManifestFile(file); - } - }); -} - -/** - * Handle manifest file upload - */ -async function handleManifestFile(file: File) { - try { - const text = await file.text(); - manifestData = parseManifest(text, file.name); - - // Display preview - const preview = document.getElementById('manifest-preview'); - const content = document.getElementById('manifest-content'); - - if (preview && content) { - preview.style.display = 'block'; - content.textContent = text; - } - - showToast('success', `Manifest loaded: ${file.name}`); - } catch (error) { - console.error('[Injector] Error loading manifest:', error); - showToast('error', `Failed to load manifest: ${error}`); - } -} - -/** - * Parse manifest (simplified) - */ -function parseManifest(text: string, filename: string): any { - // In production, use proper YAML/TOML parsers - try { - if (filename.endsWith('.json')) { - return JSON.parse(text); - } - // For now, return raw text for YAML/TOML - return { raw: text, filename }; - } catch (error) { - throw new Error('Invalid manifest format'); - } -} - -/** - * Setup form handlers - */ -function setupFormHandlers() { - const validateBtn = document.getElementById('validate-btn'); - const injectBtn = document.getElementById('inject-btn'); - const rollbackBtn = document.getElementById('rollback-btn'); - - validateBtn?.addEventListener('click', handleValidate); - injectBtn?.addEventListener('click', handleInject); - rollbackBtn?.addEventListener('click', handleRollback); -} - -/** - * Handle manifest validation - */ -async function handleValidate() { - if (!manifestData) { - showToast('warning', 'Please load a manifest first'); - return; - } - - updateStatus('running', 'Validating manifest...'); - addLogEntry('info', 'Starting manifest validation'); - - try { - // Simulate validation (in production, call API) - await delay(1000); - - updateStatus('success', 'Manifest is valid'); - addLogEntry('success', 'Manifest validation completed successfully'); - showToast('success', 'Manifest validation passed'); - } catch (error) { - updateStatus('error', 'Validation failed'); - addLogEntry('error', `Validation error: ${error}`); - showToast('error', 'Manifest validation failed'); - } -} - -/** - * Handle symbol injection - */ -async function handleInject() { - if (!manifestData) { - showToast('warning', 'Please load a manifest first'); - return; - } - - const workflow = (document.getElementById('target-workflow') as HTMLSelectElement)?.value; - const mode = (document.getElementById('injection-mode') as HTMLSelectElement)?.value; - const env = (document.getElementById('target-env') as HTMLSelectElement)?.value; - - if (!workflow) { - showToast('warning', 'Please select a target workflow'); - return; - } - - // Show diff preview for dry-run mode - if (mode === 'dry-run') { - showDiffPreview(); - return; - } - - updateStatus('running', 'Injecting symbols...'); - addLogEntry('info', `Starting injection: ${workflow} (${mode})`); - - try { - // Simulate injection process - await delay(500); - addLogEntry('info', 'Creating baseline snapshot...'); - - await delay(500); - addLogEntry('info', 'Validating symbols...'); - - await delay(1000); - addLogEntry('info', 'Injecting symbols...'); - - await delay(1000); - addLogEntry('success', 'Symbols injected successfully'); - - updateStatus('success', 'Injection completed'); - showToast('success', 'Symbols injected successfully'); - - // Add to history - addToHistory({ - workflow, - mode, - env, - timestamp: new Date().toISOString(), - status: 'success', - }); - } catch (error) { - updateStatus('error', 'Injection failed'); - addLogEntry('error', `Injection error: ${error}`); - showToast('error', 'Symbol injection failed'); - } -} - -/** - * Handle rollback - */ -async function handleRollback() { - const snapshot = (document.getElementById('rollback-select') as HTMLSelectElement)?.value; - - if (!snapshot) { - showToast('warning', 'Please select a snapshot to restore'); - return; - } - - if (!confirm('Are you sure you want to rollback? This will restore the selected snapshot.')) { - return; - } - - updateStatus('running', 'Rolling back...'); - addLogEntry('info', `Rolling back to snapshot: ${snapshot}`); - - try { - // Simulate rollback - await delay(2000); - - updateStatus('success', 'Rollback completed'); - addLogEntry('success', 'Rollback completed successfully'); - showToast('success', 'Successfully rolled back to previous state'); - } catch (error) { - updateStatus('error', 'Rollback failed'); - addLogEntry('error', `Rollback error: ${error}`); - showToast('error', 'Rollback failed'); - } -} - -/** - * Update injection status display - */ -function updateStatus(status: 'idle' | 'running' | 'success' | 'error', message: string) { - const statusDisplay = document.getElementById('injection-status'); - if (!statusDisplay) return; - - const icons = { - idle: '⏸️', - running: '⚙️', - success: '✅', - error: '❌', - }; - - statusDisplay.innerHTML = ` -
- ${icons[status]} -

${message}

-
- `; -} - -/** - * Add log entry - */ -function addLogEntry(level: 'info' | 'success' | 'warning' | 'error', message: string) { - const logDisplay = document.getElementById('progress-log'); - if (!logDisplay) return; - - // Remove placeholder - const placeholder = logDisplay.querySelector('.log-placeholder'); - if (placeholder) placeholder.remove(); - - const entry = document.createElement('div'); - entry.className = `log-entry ${level}`; - - const timestamp = new Date().toLocaleTimeString(); - entry.innerHTML = ` - [${timestamp}] - ${message} - `; - - logDisplay.appendChild(entry); - logDisplay.scrollTop = logDisplay.scrollHeight; -} - -/** - * Load workflows - */ -async function loadWorkflows() { - try { - const response = await fetch(`${API_BASE}/workflows`); - const data = await response.json(); - - const select = document.getElementById('target-workflow') as HTMLSelectElement; - if (!select) return; - - if (data.success && data.data.length > 0) { - select.innerHTML = - '' + - data.data - .map((w: any) => ``) - .join(''); - } - } catch (error) { - console.error('[Injector] Error loading workflows:', error); - } -} - -/** - * Load injection history - */ -async function loadInjectionHistory() { - // In production, load from API - const history = JSON.parse(localStorage.getItem('injection_history') || '[]'); - - const historyList = document.getElementById('injection-history'); - if (!historyList) return; - - if (history.length === 0) return; - - historyList.innerHTML = history - .slice(-5) - .reverse() - .map( - (item: any) => ` -
-
-
${item.workflow}
-
${new Date(item.timestamp).toLocaleString()}
-
-
- ${item.mode} • ${item.env} • ${item.status} -
-
- ` - ) - .join(''); -} - -/** - * Add to injection history - */ -function addToHistory(item: any) { - const history = JSON.parse(localStorage.getItem('injection_history') || '[]'); - history.push(item); - localStorage.setItem('injection_history', JSON.stringify(history.slice(-20))); - loadInjectionHistory(); -} - -/** - * Show diff preview modal - */ -function showDiffPreview() { - const modal = document.getElementById('diff-modal'); - const diffViewer = document.getElementById('diff-viewer'); - - if (modal && diffViewer) { - modal.classList.add('active'); - diffViewer.innerHTML = '
Diff preview would appear here...
'; - } -} - -/** - * Close diff modal - */ -(window as any).closeDiffModal = function () { - const modal = document.getElementById('diff-modal'); - modal?.classList.remove('active'); -}; - -/** - * Confirm injection from modal - */ -(window as any).confirmInjection = function () { - (window as any).closeDiffModal(); - handleInject(); -}; - -/** - * Show toast notification - */ -function showToast(type: 'success' | 'error' | 'warning' | 'info', message: string) { - const container = document.getElementById('toast-container'); - if (!container) return; - - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - toast.style.cssText = ` - padding: 1rem; - background: var(--color-bg-elevated); - border: 1px solid var(--color-border); - border-radius: var(--radius-md); - box-shadow: var(--shadow-lg); - `; - - container.appendChild(toast); - - setTimeout(() => toast.remove(), 5000); -} - -/** - * Utility: Delay - */ -function delay(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -// Initialize on DOM ready -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initInjector); -} else { - initInjector(); -} diff --git a/praxis/SymbolicEngine/dashboard/js/dashboard.ts b/praxis/SymbolicEngine/dashboard/js/dashboard.ts deleted file mode 100644 index a05af9d..0000000 --- a/praxis/SymbolicEngine/dashboard/js/dashboard.ts +++ /dev/null @@ -1,612 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Dashboard - Main Frontend Application - * Handles UI interactions, data fetching, and real-time updates - */ - -// API Configuration -const API_BASE = window.location.origin + '/api'; -const WS_URL = `ws://${window.location.host}/ws`; - -// State -let ws: WebSocket | null = null; -let currentView = 'overview'; -let dashboardStats: any = null; -let charts: Record = {}; - -/** - * Initialize the dashboard - */ -async function initDashboard() { - console.log('[Dashboard] Initializing...'); - - // Setup theme - setupTheme(); - - // Setup navigation - setupNavigation(); - - // Setup WebSocket - setupWebSocket(); - - // Setup refresh button - setupRefreshButton(); - - // Load initial data - await loadDashboard Data(); - - // Setup auto-refresh - setupAutoRefresh(); - - // Initialize charts - initializeCharts(); - - console.log('[Dashboard] Ready'); -} - -/** - * Setup theme toggle - */ -function setupTheme() { - const themeToggle = document.getElementById('theme-toggle'); - const html = document.documentElement; - - // Load saved theme or use system preference - const savedTheme = localStorage.getItem('theme'); - const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - const theme = savedTheme || (systemDark ? 'dark' : 'light'); - html.setAttribute('data-theme', theme); - - themeToggle?.addEventListener('click', () => { - const currentTheme = html.getAttribute('data-theme'); - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - html.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); - }); -} - -/** - * Setup navigation - */ -function setupNavigation() { - const navItems = document.querySelectorAll('.nav-item[data-view]'); - - navItems.forEach((item) => { - item.addEventListener('click', (e) => { - e.preventDefault(); - const view = (item as HTMLElement).dataset.view; - if (view) { - switchView(view); - } - }); - }); -} - -/** - * Switch to a different view - */ -function switchView(view: string) { - currentView = view; - - // Update navigation - document.querySelectorAll('.nav-item').forEach((item) => { - item.classList.remove('active'); - }); - document.querySelector(`[data-view="${view}"]`)?.classList.add('active'); - - // Update views - document.querySelectorAll('.view').forEach((v) => { - v.classList.remove('active'); - }); - document.getElementById(`view-${view}`)?.classList.add('active'); - - // Load view data - loadViewData(view); -} - -/** - * Setup WebSocket connection - */ -function setupWebSocket() { - const statusDot = document.querySelector('.status-dot'); - const statusText = document.querySelector('.status-text'); - - function connect() { - console.log('[WebSocket] Connecting...'); - updateConnectionStatus('connecting', 'Connecting...'); - - ws = new WebSocket(WS_URL); - - ws.onopen = () => { - console.log('[WebSocket] Connected'); - updateConnectionStatus('connected', 'Connected'); - }; - - ws.onmessage = (event) => { - try { - const message = JSON.parse(event.data); - handleWebSocketMessage(message); - } catch (error) { - console.error('[WebSocket] Error parsing message:', error); - } - }; - - ws.onerror = (error) => { - console.error('[WebSocket] Error:', error); - updateConnectionStatus('disconnected', 'Error'); - }; - - ws.onclose = () => { - console.log('[WebSocket] Disconnected'); - updateConnectionStatus('disconnected', 'Disconnected'); - - // Reconnect after 5 seconds - setTimeout(connect, 5000); - }; - } - - function updateConnectionStatus(status: string, text: string) { - statusDot?.setAttribute('data-status', status); - if (statusText) statusText.textContent = text; - } - - connect(); -} - -/** - * Handle WebSocket messages - */ -function handleWebSocketMessage(message: any) { - console.log('[WebSocket] Message:', message.type); - - switch (message.type) { - case 'stats_update': - updateDashboardStats(message.payload.stats); - break; - case 'execution_started': - showToast('info', `Execution started: ${message.payload.execution_id}`); - loadViewData('executions'); - break; - case 'execution_completed': - showToast('success', `Execution completed successfully`); - loadViewData('executions'); - updateDashboardStats(); - break; - case 'execution_failed': - showToast('error', `Execution failed`); - loadViewData('executions'); - break; - case 'deviation_detected': - showToast('warning', 'Deviation detected in audit'); - break; - case 'log_entry': - console.log(`[Log] ${message.payload.level}: ${message.payload.message}`); - break; - } -} - -/** - * Setup refresh button - */ -function setupRefreshButton() { - const refreshBtn = document.getElementById('refresh-btn'); - refreshBtn?.addEventListener('click', async () => { - await loadDashboardData(); - showToast('success', 'Dashboard refreshed'); - }); -} - -/** - * Setup auto-refresh - */ -function setupAutoRefresh() { - setInterval(async () => { - if (currentView === 'overview') { - await updateDashboardStats(); - } - }, 5000); // 5 seconds -} - -/** - * Load dashboard data - */ -async function loadDashboardData() { - await Promise.all([updateDashboardStats(), loadViewData(currentView)]); -} - -/** - * Update dashboard statistics - */ -async function updateDashboardStats(stats?: any) { - try { - if (!stats) { - const response = await fetch(`${API_BASE}/stats`); - const data = await response.json(); - stats = data.data; - } - - dashboardStats = stats; - - // Update stat cards - updateElement('stat-workflows-total', stats.workflows.total); - updateElement('stat-workflows-active', stats.workflows.active); - updateElement('stat-workflows-paused', stats.workflows.paused); - - updateElement('stat-executions-total', stats.executions.total); - updateElement('stat-executions-running', stats.executions.running); - updateElement('stat-executions-success', `${stats.executions.success_rate}%`); - - updateElement('stat-audits-total', stats.audits.total_audits); - updateElement('stat-audits-deviations', stats.audits.total_deviations); - updateElement('stat-audits-compliance', `${stats.audits.avg_compliance_score}%`); - - const uptime = formatUptime(stats.system.uptime_seconds); - updateElement('stat-system-uptime', uptime); - updateElement('stat-system-memory', `${stats.system.memory_usage_mb} MB`); - updateElement('stat-system-connections', stats.system.active_connections); - - // Update charts - updateCharts(stats); - } catch (error) { - console.error('[Dashboard] Error updating stats:', error); - } -} - -/** - * Load view-specific data - */ -async function loadViewData(view: string) { - switch (view) { - case 'overview': - // Overview data is loaded via stats - break; - case 'workflows': - await loadWorkflows(); - break; - case 'executions': - await loadExecutions(); - break; - case 'symbols': - await loadSymbols(); - break; - case 'audits': - await loadAudits(); - break; - case 'baselines': - await loadBaselines(); - break; - } -} - -/** - * Load workflows - */ -async function loadWorkflows() { - try { - const response = await fetch(`${API_BASE}/workflows`); - const data = await response.json(); - - const tbody = document.getElementById('workflows-tbody'); - if (!tbody) return; - - if (!data.success || data.data.length === 0) { - tbody.innerHTML = 'No workflows found'; - return; - } - - tbody.innerHTML = data.data - .map( - (workflow: any) => ` - - ${escapeHtml(workflow.name)} - ${workflow.status} - ${workflow.last_execution ? formatDate(workflow.last_execution) : 'Never'} - ${workflow.symbols?.length || 0} - - - - - ` - ) - .join(''); - } catch (error) { - console.error('[Dashboard] Error loading workflows:', error); - } -} - -/** - * Load executions - */ -async function loadExecutions() { - try { - const response = await fetch(`${API_BASE}/executions`); - const data = await response.json(); - - const tbody = document.getElementById('executions-tbody'); - if (!tbody) return; - - if (!data.success || data.data.length === 0) { - tbody.innerHTML = 'No executions found'; - return; - } - - tbody.innerHTML = data.data - .map( - (execution: any) => ` - - ${execution.id.slice(0, 8)} - ${escapeHtml(execution.workflow_id)} - ${execution.status} - ${formatDate(execution.started_at)} - ${execution.duration_ms ? `${execution.duration_ms}ms` : '-'} - - - - - ` - ) - .join(''); - } catch (error) { - console.error('[Dashboard] Error loading executions:', error); - } -} - -/** - * Load symbols - */ -async function loadSymbols() { - try { - const response = await fetch(`${API_BASE}/symbols`); - const data = await response.json(); - - const grid = document.getElementById('symbols-grid'); - if (!grid) return; - - if (!data.success || data.data.length === 0) { - grid.innerHTML = '
No symbols found
'; - return; - } - - grid.innerHTML = data.data - .map( - (symbol: any) => ` -
-
-

${escapeHtml(symbol.name)}

- 🔣 -
-
- - Type: - ${symbol.type} - - - Context: - ${symbol.context} - -
-
- ` - ) - .join(''); - } catch (error) { - console.error('[Dashboard] Error loading symbols:', error); - } -} - -/** - * Load audits - */ -async function loadAudits() { - try { - const response = await fetch(`${API_BASE}/audits`); - const data = await response.json(); - - const tbody = document.getElementById('audits-tbody'); - if (!tbody) return; - - if (!data.success || data.data.length === 0) { - tbody.innerHTML = 'No audits found'; - return; - } - - tbody.innerHTML = data.data - .map( - (audit: any) => ` - - ${audit.id.slice(0, 8)} - ${escapeHtml(audit.workflow_id)} - ${audit.summary?.total_deviations || 0} - ${audit.summary?.compliance_score || 0}% - ${formatDate(audit.started_at)} - - - - - ` - ) - .join(''); - } catch (error) { - console.error('[Dashboard] Error loading audits:', error); - } -} - -/** - * Load baselines - */ -async function loadBaselines() { - try { - const response = await fetch(`${API_BASE}/baselines`); - const data = await response.json(); - - const tbody = document.getElementById('baselines-tbody'); - if (!tbody) return; - - if (!data.success || data.data.length === 0) { - tbody.innerHTML = 'No baselines found'; - return; - } - - tbody.innerHTML = data.data - .map( - (baseline: any) => ` - - ${escapeHtml(baseline.name)} - ${escapeHtml(baseline.workflow_id)} - ${baseline.is_normative ? '✓' : '-'} - ${formatDate(baseline.created_at)} - - - - - ` - ) - .join(''); - } catch (error) { - console.error('[Dashboard] Error loading baselines:', error); - } -} - -/** - * Initialize charts - */ -function initializeCharts() { - // Execution timeline chart - const timelineCtx = document.getElementById('execution-timeline-chart') as HTMLCanvasElement; - if (timelineCtx) { - charts.timeline = new (window as any).Chart(timelineCtx, { - type: 'line', - data: { - labels: [], - datasets: [ - { - label: 'Completed', - data: [], - borderColor: '#10b981', - backgroundColor: 'rgba(16, 185, 129, 0.1)', - }, - { - label: 'Failed', - data: [], - borderColor: '#ef4444', - backgroundColor: 'rgba(239, 68, 68, 0.1)', - }, - ], - }, - options: { - responsive: true, - maintainAspectRatio: false, - }, - }); - } - - // Workflow status chart - const statusCtx = document.getElementById('workflow-status-chart') as HTMLCanvasElement; - if (statusCtx) { - charts.status = new (window as any).Chart(statusCtx, { - type: 'doughnut', - data: { - labels: ['Active', 'Paused', 'Error'], - datasets: [ - { - data: [0, 0, 0], - backgroundColor: ['#10b981', '#f59e0b', '#ef4444'], - }, - ], - }, - options: { - responsive: true, - maintainAspectRatio: false, - }, - }); - } -} - -/** - * Update charts with new data - */ -function updateCharts(stats: any) { - // Update workflow status chart - if (charts.status) { - charts.status.data.datasets[0].data = [ - stats.workflows.active, - stats.workflows.paused, - stats.workflows.error, - ]; - charts.status.update(); - } -} - -/** - * Show toast notification - */ -function showToast(type: 'success' | 'error' | 'warning' | 'info', message: string) { - const container = document.getElementById('toast-container'); - if (!container) return; - - const toast = document.createElement('div'); - toast.className = `toast toast-${type}`; - toast.textContent = message; - toast.style.cssText = ` - padding: 1rem; - background: var(--color-bg-elevated); - border: 1px solid var(--color-border); - border-radius: var(--radius-md); - box-shadow: var(--shadow-lg); - animation: slideIn 0.3s ease; - `; - - container.appendChild(toast); - - setTimeout(() => { - toast.remove(); - }, 5000); -} - -/** - * Utility: Update element text content - */ -function updateElement(id: string, value: any) { - const el = document.getElementById(id); - if (el) el.textContent = String(value); -} - -/** - * Utility: Format date - */ -function formatDate(dateString: string): string { - const date = new Date(dateString); - return date.toLocaleString(); -} - -/** - * Utility: Format uptime - */ -function formatUptime(seconds: number): string { - const hours = Math.floor(seconds / 3600); - const minutes = Math.floor((seconds % 3600) / 60); - return `${hours}h ${minutes}m`; -} - -/** - * Utility: Escape HTML - */ -function escapeHtml(text: string): string { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; -} - -// Global functions for button handlers -(window as any).viewWorkflow = (id: string) => console.log('View workflow:', id); -(window as any).viewExecution = (id: string) => console.log('View execution:', id); -(window as any).viewAudit = (id: string) => console.log('View audit:', id); -(window as any).viewBaseline = (id: string) => console.log('View baseline:', id); - -// Initialize on DOM ready -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initDashboard); -} else { - initDashboard(); -} diff --git a/praxis/SymbolicEngine/dashboard/js/symbol-inspector.ts b/praxis/SymbolicEngine/dashboard/js/symbol-inspector.ts deleted file mode 100644 index 9daa620..0000000 --- a/praxis/SymbolicEngine/dashboard/js/symbol-inspector.ts +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Symbol Inspector - * Detailed symbol inspection and testing interface - */ - -export class SymbolInspector { - private containerId: string; - private symbol: any = null; - - constructor(containerId: string) { - this.containerId = containerId; - } - - /** - * Load and display symbol details - */ - async loadSymbol(symbolId: string) { - try { - const response = await fetch(`/api/symbols/${symbolId}`); - const data = await response.json(); - - if (!data.success) { - throw new Error(data.error?.message || 'Failed to load symbol'); - } - - this.symbol = data.data; - this.render(); - } catch (error) { - console.error('[SymbolInspector] Error loading symbol:', error); - this.renderError(String(error)); - } - } - - /** - * Render symbol details - */ - private render() { - const container = document.getElementById(this.containerId); - if (!container) return; - - container.innerHTML = ` -
-
-

${this.escapeHtml(this.symbol.name)}

- ${this.symbol.type} -
- -
-

Details

-
-
ID:
-
${this.symbol.id}
- -
Type:
-
${this.symbol.type}
- -
Context:
-
${this.symbol.context}
- -
Dispatch:
-
${this.symbol.dispatch}
- -
Created:
-
${new Date(this.symbol.created_at).toLocaleString()}
- -
Updated:
-
${new Date(this.symbol.updated_at).toLocaleString()}
-
-
- - ${this.symbol.metadata?.description ? ` -
-

Description

-

${this.escapeHtml(this.symbol.metadata.description)}

-
- ` : ''} - -
-

Parameters

-
${JSON.stringify(this.symbol.parameters, null, 2)}
-
- - ${this.symbol.metadata?.tags?.length ? ` -
-

Tags

-
- ${this.symbol.metadata.tags.map((tag: string) => ` - ${this.escapeHtml(tag)} - `).join('')} -
-
- ` : ''} - -
- - -
-
- `; - } - - /** - * Render error message - */ - private renderError(message: string) { - const container = document.getElementById(this.containerId); - if (!container) return; - - container.innerHTML = ` -
-

Error loading symbol: ${this.escapeHtml(message)}

-
- `; - } - - /** - * Escape HTML - */ - private escapeHtml(text: string): string { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; - } -} - -// Global functions for button handlers -(window as any).testSymbol = (id: string) => { - console.log('Test symbol:', id); - // Implement test execution logic -}; - -(window as any).editSymbol = (id: string) => { - console.log('Edit symbol:', id); - // Implement symbol editing logic -}; diff --git a/praxis/SymbolicEngine/dashboard/js/workflow-visualizer.ts b/praxis/SymbolicEngine/dashboard/js/workflow-visualizer.ts deleted file mode 100644 index ba360aa..0000000 --- a/praxis/SymbolicEngine/dashboard/js/workflow-visualizer.ts +++ /dev/null @@ -1,249 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Workflow Visualizer - * Renders workflow DAGs and dependency graphs - */ - -export class WorkflowVisualizer { - private canvas: HTMLCanvasElement; - private ctx: CanvasRenderingContext2D; - private workflow: any; - private nodes: Map = new Map(); - private edges: Edge[] = []; - - constructor(canvasId: string) { - this.canvas = document.getElementById(canvasId) as HTMLCanvasElement; - if (!this.canvas) { - throw new Error(`Canvas element ${canvasId} not found`); - } - - const ctx = this.canvas.getContext('2d'); - if (!ctx) { - throw new Error('Failed to get canvas 2D context'); - } - this.ctx = ctx; - - this.setupCanvas(); - } - - /** - * Setup canvas dimensions - */ - private setupCanvas() { - const rect = this.canvas.parentElement?.getBoundingClientRect(); - if (rect) { - this.canvas.width = rect.width; - this.canvas.height = rect.height || 600; - } - } - - /** - * Load and visualize workflow - */ - async loadWorkflow(workflowId: string) { - try { - const response = await fetch(`/api/workflows/${workflowId}`); - const data = await response.json(); - - if (!data.success) { - throw new Error(data.error?.message || 'Failed to load workflow'); - } - - this.workflow = data.data; - this.buildGraph(); - this.render(); - } catch (error) { - console.error('[WorkflowVisualizer] Error loading workflow:', error); - } - } - - /** - * Build graph from workflow data - */ - private buildGraph() { - this.nodes.clear(); - this.edges = []; - - // Create nodes for each symbol - this.workflow.symbols?.forEach((symbol: any, index: number) => { - const node: Node = { - id: symbol.id, - label: symbol.name, - x: 100 + (index % 3) * 200, - y: 100 + Math.floor(index / 3) * 150, - width: 150, - height: 60, - type: symbol.type, - }; - this.nodes.set(symbol.id, node); - }); - - // Create edges from dependencies - this.workflow.dependencies?.forEach((dep: any) => { - const fromNode = this.nodes.get(dep.from_symbol); - const toNode = this.nodes.get(dep.to_symbol); - - if (fromNode && toNode) { - this.edges.push({ - from: fromNode, - to: toNode, - type: dep.type, - }); - } - }); - } - - /** - * Render the graph - */ - render() { - // Clear canvas - this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - - // Draw edges first (so they're behind nodes) - this.edges.forEach((edge) => this.drawEdge(edge)); - - // Draw nodes - this.nodes.forEach((node) => this.drawNode(node)); - } - - /** - * Draw a node - */ - private drawNode(node: Node) { - const ctx = this.ctx; - - // Draw shadow - ctx.shadowColor = 'rgba(0, 0, 0, 0.1)'; - ctx.shadowBlur = 10; - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 2; - - // Draw rectangle - ctx.fillStyle = this.getNodeColor(node.type); - ctx.strokeStyle = '#6366f1'; - ctx.lineWidth = 2; - this.roundRect(ctx, node.x, node.y, node.width, node.height, 8); - ctx.fill(); - ctx.stroke(); - - // Reset shadow - ctx.shadowColor = 'transparent'; - - // Draw label - ctx.fillStyle = '#ffffff'; - ctx.font = '14px sans-serif'; - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.fillText(node.label, node.x + node.width / 2, node.y + node.height / 2); - } - - /** - * Draw an edge - */ - private drawEdge(edge: Edge) { - const ctx = this.ctx; - - const fromX = edge.from.x + edge.from.width; - const fromY = edge.from.y + edge.from.height / 2; - const toX = edge.to.x; - const toY = edge.to.y + edge.to.height / 2; - - ctx.strokeStyle = edge.type === 'required' ? '#6366f1' : '#cbd5e1'; - ctx.lineWidth = edge.type === 'required' ? 2 : 1; - ctx.setLineDash(edge.type === 'optional' ? [5, 5] : []); - - // Draw line - ctx.beginPath(); - ctx.moveTo(fromX, fromY); - ctx.lineTo(toX, toY); - ctx.stroke(); - - // Draw arrow head - this.drawArrowHead(ctx, fromX, fromY, toX, toY); - - ctx.setLineDash([]); - } - - /** - * Draw arrow head - */ - private drawArrowHead( - ctx: CanvasRenderingContext2D, - x1: number, - y1: number, - x2: number, - y2: number - ) { - const headLength = 10; - const angle = Math.atan2(y2 - y1, x2 - x1); - - ctx.beginPath(); - ctx.moveTo(x2, y2); - ctx.lineTo( - x2 - headLength * Math.cos(angle - Math.PI / 6), - y2 - headLength * Math.sin(angle - Math.PI / 6) - ); - ctx.moveTo(x2, y2); - ctx.lineTo( - x2 - headLength * Math.cos(angle + Math.PI / 6), - y2 - headLength * Math.sin(angle + Math.PI / 6) - ); - ctx.stroke(); - } - - /** - * Draw rounded rectangle - */ - private roundRect( - ctx: CanvasRenderingContext2D, - x: number, - y: number, - width: number, - height: number, - radius: number - ) { - ctx.beginPath(); - ctx.moveTo(x + radius, y); - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); - ctx.closePath(); - } - - /** - * Get color for node type - */ - private getNodeColor(type: string): string { - const colors: Record = { - action: '#6366f1', - query: '#3b82f6', - transformation: '#8b5cf6', - validation: '#10b981', - audit: '#f59e0b', - }; - return colors[type] || '#6b7280'; - } -} - -interface Node { - id: string; - label: string; - x: number; - y: number; - width: number; - height: number; - type: string; -} - -interface Edge { - from: Node; - to: Node; - type: string; -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiRoutes.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiRoutes.res deleted file mode 100644 index 89e14a1..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiRoutes.res +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Praxis API Routes — Central Routing Manifest - * Fully ported to ReScript v12 - */ - -open Types -open AuditController -open BaselineController -open ExecutionController -open SymbolController -open WorkflowController - -module Elysia = { - type t - type context<'q, 'p, 'b> = { - query: 'q, - params: 'p, - body: 'b, - } - @send external get: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "get" - @send external post: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "post" - @send external patch: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "patch" - @send external delete: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "delete" - @send external group: (t, string, t => t) => t = "group" -} - -let setupAuditRoutes = (app: Elysia.t, controller: AuditController.t) => { - app->Elysia.group("/audits", app => { - app - ->Elysia.get("/", async _ctx => { - let workflowId = %raw(`ctx.query.workflow_id`) - await AuditController.list(controller, workflowId) - }) - ->Elysia.get("/stats", async _ => { - await AuditController.getStats(controller) - }) - }) -} - -let setupBaselineRoutes = (app: Elysia.t, controller: BaselineController.t) => { - app->Elysia.group("/baselines", app => { - app - ->Elysia.get("/", async _ctx => { - let workflowId = %raw(`ctx.query.workflow_id`) - await BaselineController.list(controller, workflowId) - }) - ->Elysia.get("/normative/:workflow_id", async _ctx => { - let workflowId = %raw(`ctx.params.workflow_id`) - await BaselineController.getNormative(controller, workflowId) - }) - }) -} - -let setupExecutionRoutes = (app: Elysia.t, controller: ExecutionController.t) => { - app->Elysia.group("/executions", app => { - app - ->Elysia.get("/", async _ctx => { - let status = %raw(`ctx.query.status`) - await ExecutionController.list(controller, status) - }) - ->Elysia.get("/stats", async _ => { - await ExecutionController.getStats(controller) - }) - }) -} - -let setupSymbolRoutes = (app: Elysia.t, controller: SymbolController.t) => { - app->Elysia.group("/symbols", app => { - app - ->Elysia.get("/", async _ => { - await SymbolController.list(controller, None) - }) - ->Elysia.get("/search", async _ctx => { - let q = %raw(`ctx.query.q`) - let type_ = %raw(`ctx.query.type`) - await SymbolController.search(controller, q, type_) - }) - }) -} - -let setupWorkflowRoutes = (app: Elysia.t, controller: WorkflowController.t) => { - app->Elysia.group("/workflows", app => { - app - ->Elysia.get("/", async _ctx => { - let status = %raw(`ctx.query.status`) - await WorkflowController.list(controller, status) - }) - ->Elysia.post("/", async _ctx => { - let name = %raw(`ctx.body.name`) - let path = %raw(`ctx.body.manifest_path`) - await WorkflowController.create(controller, name, path) - }) - ->Elysia.get("/:id/symbols", async _ctx => { - let id = %raw(`ctx.params.id`) - await WorkflowController.getSymbols(controller, id) - }) - }) -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiServer.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiServer.ast index f6e1095..e747f2e 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiServer.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiServer.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiServer.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiServer.res deleted file mode 100644 index 556a6cb..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/ApiServer.res +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * WP Praxis Dashboard — API Server Orchestrator - * Fully ported to ReScript v12 - */ - -module Elysia = { - type t - type options<'a> = 'a - @module("elysia") @new external make: unit => t = "Elysia" - @send external use: (t, 'plugin) => t = "use" - @send external get: (t, string, 'handler) => t = "get" - @send external post: (t, string, 'handler) => t = "post" - @send external group: (t, string, t => t) => t = "group" - @send external listen: (t, int) => t = "listen" -} - -module Cors = { - @module("@elysiajs/cors") external cors: unit => 'plugin = "cors" -} - -module Postgres = { - type client - @module("./db/postgres-client.res.mjs") @new - external makeClient: 'config => client = "PostgresClient" - @send external connect: client => promise = "connect" -} - -type serverConfig = { - port: int, - database: JSON.t, -} - -@module("./config-loader.res.mjs") -external loadConfig: unit => promise = "loadConfig" - -module DashboardServer = { - type t = { - mutable config: option, - mutable db: option, - app: Elysia.t, - } - - let make = () => { - { - config: None, - db: None, - app: Elysia.make(), - } - } - - let setupRoutes = (self: t) => { - self.app - ->Elysia.use(Cors.cors()) - ->Elysia.group("/api", app => { - app - ->Elysia.get("/health", _ => {"status": "ok", "timestamp": Date.now()}) - ->Elysia.group("/workflows", app => { - app - ->Elysia.get("/", _ => %raw(`[]`)) // Placeholder for workflow list - ->Elysia.get("/:id", _ => %raw(`{}`)) - }) - }) - } - - let initialize = async (self: t) => { - Console.log("Initializing Dashboard Server...") - - let config = await loadConfig() - self.config = Some(config) - - let db = Postgres.makeClient(config.database) - self.db = Some(db) - await Postgres.connect(db) - - let _ = setupRoutes(self) - - let port = config.port - let _ = self.app->Elysia.listen(port) - Console.log(`Dashboard API listening on port ${Int.toString(port)}`) - } -} - -let server = DashboardServer.make() -let _ = DashboardServer.initialize(server) diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/AuditController.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/AuditController.ast index 3806a59..86e14cb 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/AuditController.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/AuditController.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/AuditController.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/AuditController.res deleted file mode 100644 index f7ca3cc..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/AuditController.res +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Audit Controller — Compliance Verification Management - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module AuditController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * LIST: Returns a paginated log of audit events. - */ - let list = async (self: t, _workflowId: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM audits") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => { - success: false, - error: {code: "DB_ERROR", message: "Not connected"}, - } - } - } catch { - | _ => { - success: false, - error: {code: "DB_ERROR", message: "Failed to fetch audits"}, - } - } - } - - /** - * STATISTICS: Aggregates audit results. - */ - let getStats = async (self: t): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT COUNT(*) FROM audits") - { - success: true, - data: Obj.magic({"compliance_score": 100.0, "total_audits": 0}), - } - } - | None => { - success: false, - error: {code: "DB_ERROR", message: "Not connected"}, - } - } - } catch { - | _ => { - success: false, - error: {code: "DB_ERROR", message: "Failed to fetch audit stats"}, - } - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/BaselineController.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/BaselineController.ast index 24bc95f..e19c606 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/BaselineController.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/BaselineController.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/BaselineController.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/BaselineController.res deleted file mode 100644 index 0cb7e3a..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/BaselineController.res +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Baseline Controller — Normative State Management - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module BaselineController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * GET NORMATIVE: Retrieves the authoritative policy snapshot. - */ - let getNormative = async (self: t, workflowId: string): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql( - sql, - `SELECT * FROM baselines WHERE workflow_id = '${workflowId}' AND is_normative = true LIMIT 1`, - ) - // Simplified placeholder logic - { - success: false, - error: {code: "NOT_FOUND", message: "Normative baseline not found for workflow"}, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch baseline"}} - } - } - - /** - * LIST: Returns a paginated set of historical baselines. - */ - let list = async (self: t, _workflowId: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM baselines") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch baselines"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/ConfigLoader.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/ConfigLoader.ast index caa4281..7f776cd 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/ConfigLoader.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/ConfigLoader.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/ConfigLoader.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/ConfigLoader.res deleted file mode 100644 index 1bf795a..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/ConfigLoader.res +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Config Loader — Dashboard Specification Ingestion - * Fully ported to ReScript v12 - */ - -module Path = { - @module("path") external join: (string, string) => string = "join" - @module("path") external dirname: string => string = "dirname" -} - -module Fs = { - @module("fs") external readFileSync: (string, string) => string = "readFileSync" - @module("fs") external existsSync: string => bool = "existsSync" -} - -// Simple TOML parser implementation -let parseSimpleTOML = (content: string): JSON.t => { - let result = Dict.make() - let currentSection = ref(result) - - let lines = String.split(content, "\n") - lines->Array.forEach(line => { - let trimmed = String.trim(line) - if String.startsWith(trimmed, "#") || trimmed == "" { - () // Skip comments and empty lines - } else if String.startsWith(trimmed, "[") && String.endsWith(trimmed, "]") { - let sectionName = String.substring(trimmed, ~start=1, ~end=String.length(trimmed) - 1) - let section = Dict.make() - Dict.set(result, sectionName, JSON.Encode.object(section)) - currentSection := section - } else { - let parts = String.split(trimmed, "=") - if Array.length(parts) == 2 { - let key = String.trim(Belt.Array.getExn(parts, 0)) - let value = String.trim(Belt.Array.getExn(parts, 1)) - - // Basic type inference - let jsonValue = if String.startsWith(value, "\"") && String.endsWith(value, "\"") { - JSON.Encode.string(String.substring(value, ~start=1, ~end=String.length(value) - 1)) - } else if value == "true" { - JSON.Encode.bool(true) - } else if value == "false" { - JSON.Encode.bool(false) - } else { - switch Int.fromString(value) { - | Some(n) => JSON.Encode.int(n) - | None => JSON.Encode.string(value) - } - } - Dict.set(currentSection.contents, key, jsonValue) - } - } - }) - - JSON.Encode.object(result) -} - -let loadConfig = async (~configPath: option=?): JSON.t => { - let path = switch configPath { - | Some(p) => p - | None => Path.join(%raw(`import.meta.dirname`), "../dashboard-config.toml") - } - - if Fs.existsSync(path) { - let content = Fs.readFileSync(path, "utf-8") - parseSimpleTOML(content) - } else { - // Return default config as JSON - Obj.magic({ - "server": {"port": 4000, "host": "localhost"}, - "database": {"host": "localhost", "port": 5432}, - }) - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/DashboardEvents.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/DashboardEvents.ast index cfe05d9..3e36731 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/DashboardEvents.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/DashboardEvents.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/DashboardEvents.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/DashboardEvents.res deleted file mode 100644 index 79ab1df..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/DashboardEvents.res +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Dashboard Events — Real-Time WebSocket Broadcasting - * Fully ported to ReScript v12 - */ - -module WebSocket = { - type t - @send external send: (t, string) => unit = "send" -} - -module DashboardEvents = { - type t = { - connections: Set.t, - mutable heartbeatInterval: option, - } - - let make = () => { - { - connections: Set.make(), - heartbeatInterval: None, - } - } - - let createMessage = (type_: string, payload: JSON.t): JSON.t => { - Obj.magic({ - "type": type_, - "payload": payload, - "timestamp": Date.now()->Float.toString, - }) - } - - let sendToClient = (ws: WebSocket.t, type_: string, payload: JSON.t) => { - let message = createMessage(type_, payload) - ws->WebSocket.send(JSON.stringify(message)) - } - - let broadcast = (self: t, type_: string, payload: JSON.t) => { - let message = createMessage(type_, payload) - let messageStr = JSON.stringify(message) - - self.connections->Set.forEach(ws => { - try { - ws->WebSocket.send(messageStr) - } catch { - | _ => { - let _ = self.connections->Set.delete(ws) - } - } - }) - } - - let broadcastExecutionProgress = (self: t, executionId: string, progress: float, message: option) => { - self->broadcast("execution_progress", Obj.magic({ - "execution_id": executionId, - "progress": progress, - "message": message, - "timestamp": Date.now()->Float.toString, - })) - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/ExecutionController.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/ExecutionController.ast index 5b15dbf..330128a 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/ExecutionController.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/ExecutionController.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/ExecutionController.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/ExecutionController.res deleted file mode 100644 index 0992334..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/ExecutionController.res +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Execution Controller — Swarm Trace Observability - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module ExecutionController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * LIST: Returns a paginated log of execution attempts. - */ - let list = async (self: t, _status: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM executions") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch executions"}} - } - } - - /** - * STATISTICS: Aggregates execution performance. - */ - let getStats = async (self: t): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT COUNT(*) FROM executions") - { - success: true, - data: { - total: 0, - running: 0, - completed_today: 0, - failed_today: 0, - success_rate: 100.0, - avg_duration_ms: 0.0, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch execution stats"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/HealthRoutes.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/HealthRoutes.ast index 93b2a29..3ec4ee7 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/HealthRoutes.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/HealthRoutes.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/HealthRoutes.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/HealthRoutes.res deleted file mode 100644 index 38d9120..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/HealthRoutes.res +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Health Check API Routes — Service Observability Endpoints - * Fully ported to ReScript v12 - */ - -module Elysia = { - type t - @send external get: (t, string, 'handler) => t = "get" - @send external group: (t, string, t => t) => t = "group" -} - -module Postgres = { - type client - @send external healthCheck: client => promise = "healthCheck" -} - -type memoryUsage = { - rss: float, - heapTotal: float, - heapUsed: float, -} - -@val @scope("process") -external memoryUsage: unit => memoryUsage = "memoryUsage" - -@val @scope("process") -external uptime: unit => float = "uptime" - -let setupHealthRoutes = (app: Elysia.t, db: Postgres.client) => { - app->Elysia.group("/health", app => { - app - ->Elysia.get("/", async _ => { - let dbOk = await Postgres.healthCheck(db) - let mem = memoryUsage() - - { - "status": dbOk ? "healthy" : "degraded", - "database": dbOk ? "connected" : "disconnected", - "memoryMb": Float.toInt(mem.heapUsed /. 1024.0 /. 1024.0), - "timestamp": Date.now(), - } - }) - ->Elysia.get("/detailed", async _ => { - let dbOk = await Postgres.healthCheck(db) - let mem = memoryUsage() - - { - "status": dbOk ? "healthy" : "unhealthy", - "process": { - "uptime": uptime(), - "pid": %raw(`process.pid`), - "arch": %raw(`process.arch`), - }, - "memory": { - "rss": mem.rss, - "heapTotal": mem.heapTotal, - "heapUsed": mem.heapUsed, - }, - "database": { - "connected": dbOk, - } - } - }) - }) -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/PostgresClient.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/PostgresClient.ast index 3eeb5cb..09472c8 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/PostgresClient.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/PostgresClient.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/PostgresClient.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/PostgresClient.res deleted file mode 100644 index d2cfb08..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/PostgresClient.res +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * PostgreSQL Client — Ecto Database Bridge - * Fully ported to ReScript v12 - */ - -module Types = { - type sql - type queryResult<'a> = array<'a> -} - -@module("postgres") -external makeSql: JSON.t => Types.sql = "default" - -module PostgresClient = { - type t = { - mutable sql: option, - mutable connected: bool, - config: JSON.t, - } - - @send - external querySql: (Types.sql, string) => promise> = "unsafe" - - let make = (config: JSON.t) => { - { - sql: None, - connected: false, - config: config, - } - } - - let connect = async (self: t) => { - try { - let sql = makeSql(self.config) - self.sql = Some(sql) - // Perform simple SELECT 1 heartbeat - let _ = await sql->querySql("SELECT 1 as connected") - self.connected = true - Console.log("Postgres connected successfully") - } catch { - | _ => - Console.error("DB Connection failure") - failwith("Database connection failed") - } - } - - let healthCheck = async (self: t): bool => { - switch self.sql { - | None => false - | Some(sql) => - try { - let _ = await sql->querySql("SELECT 1") - true - } catch { - | _ => false - } - } - } - - let getWorkflows = async (self: t, _limit: int, _offset: int) => { - switch self.sql { - | None => failwith("Not connected") - | Some(sql) => - await sql->querySql("SELECT * FROM workflows ORDER BY updated_at DESC") - } - } - - let getSymbolsByWorkflow = async (self: t, workflowId: string) => { - switch self.sql { - | None => failwith("Not connected") - | Some(sql) => - await sql->querySql(`SELECT s.* FROM symbols s JOIN workflow_symbols ws ON s.id = ws.symbol_id WHERE ws.workflow_id = '${workflowId}'`) - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/StreamHandler.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/StreamHandler.ast index 243cbac..79b9879 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/StreamHandler.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/StreamHandler.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/StreamHandler.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/StreamHandler.res deleted file mode 100644 index 55924a5..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/StreamHandler.res +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Stream Handler — Real-Time Execution Observability - * Fully ported to ReScript v12 - */ - -module StreamHandler = { - type t = { - activeStreams: Map.t>, - events: DashboardEvents.DashboardEvents.t, - } - - let make = (events: DashboardEvents.DashboardEvents.t) => { - { - activeStreams: Map.make(), - events: events, - } - } - - let subscribe = (self: t, executionId: string, ws: DashboardEvents.WebSocket.t) => { - let subscribers = switch self.activeStreams->Map.get(executionId) { - | Some(s) => s - | None => { - let s = Set.make() - self.activeStreams->Map.set(executionId, s) - s - } - } - subscribers->Set.add(ws) - } - - let streamLog = (self: t, executionId: string, level: string, message: string) => { - switch self.activeStreams->Map.get(executionId) { - | None => () - | Some(subscribers) => - subscribers->Set.forEach(ws => { - try { - DashboardEvents.DashboardEvents.sendToClient( - ws, - "log_entry", - Obj.magic({ - "execution_id": executionId, - "level": level, - "message": message, - "timestamp": Date.now()->Float.toString, - }), - ) - } catch { - | _ => { - let _ = subscribers->Set.delete(ws) - } - } - }) - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/SymbolController.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/SymbolController.ast index 309b79e..e7c4bc4 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/SymbolController.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/SymbolController.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/SymbolController.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/SymbolController.res deleted file mode 100644 index 8b35bf4..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/SymbolController.res +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Symbol Controller — Atomic Logic Unit Management - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module SymbolController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * LIST: Returns a paginated set of symbols. - */ - let list = async (self: t, _type: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM symbols") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch symbols"}} - } - } - - /** - * SEARCH: Filters the symbol library using a name match. - */ - let search = async (self: t, query: string, _type: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql( - sql, - `SELECT * FROM symbols WHERE name ILIKE '%${query}%'`, - ) - { - success: true, - data: [], - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to search symbols"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/Types.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/Types.ast index 506fa83..67fea54 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/Types.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/Types.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/Types.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/Types.res deleted file mode 100644 index b4c8448..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/Types.res +++ /dev/null @@ -1,348 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * WP Praxis Dashboard - Type Definitions - * Shared types for the symbolic engine dashboard - * Fully ported to ReScript v12 - */ - -// ============================================================================ -// Core Symbol Types -// ============================================================================ - -type symbolType = [ - | #action - | #query - | #transformation - | #validation - | #audit -] - -type symbolMetadata = { - description?: string, - version?: string, - author?: string, - tags?: array, - dependencies?: array, -} - -type symbol = { - id: string, - name: string, - @as("type") type_: symbolType, - context: string, - dispatch: string, - parameters: Dict.t, - metadata: symbolMetadata, - created_at: string, - updated_at: string, -} - -// ============================================================================ -// Workflow Types -// ============================================================================ - -type workflowDependencyType = [ - | #required - | #optional - | #conditional -] - -type workflowDependency = { - from_symbol: string, - to_symbol: string, - @as("type") type_: workflowDependencyType, -} - -type workflowStatus = [ - | #draft - | #active - | #paused - | #archived - | #error -] - -type workflow = { - id: string, - name: string, - description?: string, - symbols: array, - dependencies: array, - status: workflowStatus, - manifest_path: string, - created_at: string, - updated_at: string, - last_execution?: string, -} - -// ============================================================================ -// Execution Types -// ============================================================================ - -type executionStatus = [ - | #pending - | #running - | #completed - | #failed - | #cancelled - | #timeout -] - -type log_level = [ - | #debug - | #info - | #warn - | #error -] - -type executionLog = { - timestamp: string, - level: log_level, - message: string, - context?: Dict.t, -} - -type executionMetrics = { - cpu_time_ms?: float, - memory_mb?: float, - io_operations?: int, - cache_hits?: int, - cache_misses?: int, -} - -type changeType = [ - | #create - | #update - | #delete - | #move - | #copy -] - -type change = { - id: string, - @as("type") type_: changeType, - path: string, - old_value?: JSON.t, - new_value?: JSON.t, - timestamp: string, -} - -type executionResult = { - success: bool, - output?: JSON.t, - changes?: array, - metrics?: executionMetrics, -} - -type executionError = { - code: string, - message: string, - stack?: string, - context?: Dict.t, -} - -type execution = { - id: string, - workflow_id: string, - symbol_id?: string, - status: executionStatus, - started_at: string, - completed_at?: string, - duration_ms?: float, - result?: executionResult, - error?: executionError, - logs: array, - metadata: Dict.t, -} - -// ============================================================================ -// Audit Types -// ============================================================================ - -type deviationType = [ - | #missing - | #unexpected - | #modified - | #type_mismatch - | #value_mismatch - | #permission - | #integrity -] - -type severity = [ - | #low - | #medium - | #high - | #critical -] - -type deviation = { - id: string, - @as("type") type_: deviationType, - severity: severity, - path: string, - expected: JSON.t, - actual: JSON.t, - message: string, - context?: Dict.t, -} - -type auditSummary = { - total_deviations: int, - by_severity: Dict.t, - by_type: Dict.t, - compliance_score: float, -} - -type audit = { - id: string, - workflow_id: string, - execution_id: string, - baseline_id?: string, - started_at: string, - completed_at?: string, - status: [ | #running | #completed | #failed ], - deviations: array, - summary: auditSummary, -} - -// ============================================================================ -// Baseline Types -// ============================================================================ - -type baselineSnapshot = { - version: string, - timestamp: string, - state: Dict.t, - checksums: Dict.t, - metadata: Dict.t, -} - -type baseline = { - id: string, - name: string, - description?: string, - workflow_id: string, - snapshot: baselineSnapshot, - created_at: string, - created_by?: string, - is_normative: bool, -} - -// ============================================================================ -// Statistics Types -// ============================================================================ - -type workflowStats = { - total: int, - active: int, - paused: int, - error: int, -} - -type executionStats = { - total: int, - running: int, - completed_today: int, - failed_today: int, - success_rate: float, - avg_duration_ms: float, -} - -type auditStats = { - total_audits: int, - total_deviations: int, - critical_deviations: int, - avg_compliance_score: float, -} - -type systemStats = { - uptime_seconds: float, - memory_usage_mb: float, - cpu_usage_percent: float, - active_connections: int, -} - -type dashboardStats = { - workflows: workflowStats, - executions: executionStats, - audits: auditStats, - system: systemStats, - timestamp: string, -} - -// ============================================================================ -// API Request/Response Types -// ============================================================================ - -type pagination = { - page: int, - limit: int, - total: int, - pages: int, -} - -type apiMetadata = { - timestamp: string, - request_id?: string, - pagination?: pagination, -} - -type apiError = { - code: string, - message: string, - details?: Dict.t, -} - -type apiResponse<'a> = { - success: bool, - data?: 'a, - error?: apiError, - metadata?: apiMetadata, -} - -// ============================================================================ -// Config Types -// ============================================================================ - -type corsConfig = { - enabled: bool, - origins: array, - methods: array, - credentials: bool, -} - -type webSocketConfig = { - enabled: bool, - path: string, - heartbeat_interval: int, - max_payload: int, -} - -type serverConfig = { - host: string, - port: int, - env: [ | #development | #staging | #production ], - cors: corsConfig, - websocket: webSocketConfig, -} - -type databaseConfig = { - host: string, - port: int, - database: string, - user: string, - password: string, - max_connections: int, - idle_timeout: int, - connection_timeout: int, - ssl: { - enabled: bool, - reject_unauthorized: bool, - }, -} - -type dashboardConfig = { - server: serverConfig, - database: databaseConfig, - // Additional config types omitted for brevity, can be added as needed -} diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/WorkflowController.ast b/praxis/SymbolicEngine/dashboard/lib/ocaml/WorkflowController.ast index a72df59..ef30a06 100644 Binary files a/praxis/SymbolicEngine/dashboard/lib/ocaml/WorkflowController.ast and b/praxis/SymbolicEngine/dashboard/lib/ocaml/WorkflowController.ast differ diff --git a/praxis/SymbolicEngine/dashboard/lib/ocaml/WorkflowController.res b/praxis/SymbolicEngine/dashboard/lib/ocaml/WorkflowController.res deleted file mode 100644 index 69b6826..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/ocaml/WorkflowController.res +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Workflow Controller — Symbolic Logic Orchestration - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module WorkflowController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * INVENTORY: Lists workflows. - */ - let list = async (self: t, _status: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM workflows") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch workflows"}} - } - } - - /** - * PROVENANCE: Creates a new workflow record. - */ - let create = async ( - self: t, - name: string, - manifestPath: string, - ): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql( - sql, - `INSERT INTO workflows (name, manifest_path) VALUES ('${name}', '${manifestPath}')`, - ) - // Simplified placeholder logic - { - success: false, - error: {code: "ERROR", message: "Creation placeholder"}, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to create workflow"}} - } - } - - /** - * SYMBOL INSPECTION: Retrieves symbols for a specific workflow. - */ - let getSymbols = async (self: t, workflowId: string): apiResponse> => { - try { - let _results = await PostgresClient.getSymbolsByWorkflow(self.db, workflowId) - { - success: true, - data: [], - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch symbols"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/lib/rescript.lock b/praxis/SymbolicEngine/dashboard/lib/rescript.lock deleted file mode 100644 index 7633400..0000000 --- a/praxis/SymbolicEngine/dashboard/lib/rescript.lock +++ /dev/null @@ -1 +0,0 @@ -138355 \ No newline at end of file diff --git a/praxis/SymbolicEngine/dashboard/package.json b/praxis/SymbolicEngine/dashboard/package.json index 96be5ce..36be36f 100644 --- a/praxis/SymbolicEngine/dashboard/package.json +++ b/praxis/SymbolicEngine/dashboard/package.json @@ -25,10 +25,6 @@ "zod": "^3.22.4" }, "devDependencies": { - "@types/bun": "latest", - "@types/ws": "^8.5.10", - "@typescript-eslint/eslint-plugin": "^6.19.0", - "@typescript-eslint/parser": "^6.19.0", "bun-types": "latest", "eslint": "^8.56.0", "prettier": "^3.2.4" diff --git a/praxis/SymbolicEngine/dashboard/rescript.json b/praxis/SymbolicEngine/dashboard/rescript.json deleted file mode 100644 index d4fab33..0000000 --- a/praxis/SymbolicEngine/dashboard/rescript.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "@wp-praxis/dashboard", - "version": "0.1.0", - "sources": [ - { - "dir": "src", - "subdirs": true - } - ], - "package-specs": [ - { - "module": "esmodule", - "in-source": true - } - ], - "suffix": ".res.js", - "dependencies": [ - "@rescript/core" - ], - "compiler-flags": ["-open RescriptCore"], - "uncurried": true -} diff --git a/praxis/SymbolicEngine/dashboard/src/ApiServer.res b/praxis/SymbolicEngine/dashboard/src/ApiServer.res deleted file mode 100644 index 556a6cb..0000000 --- a/praxis/SymbolicEngine/dashboard/src/ApiServer.res +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * WP Praxis Dashboard — API Server Orchestrator - * Fully ported to ReScript v12 - */ - -module Elysia = { - type t - type options<'a> = 'a - @module("elysia") @new external make: unit => t = "Elysia" - @send external use: (t, 'plugin) => t = "use" - @send external get: (t, string, 'handler) => t = "get" - @send external post: (t, string, 'handler) => t = "post" - @send external group: (t, string, t => t) => t = "group" - @send external listen: (t, int) => t = "listen" -} - -module Cors = { - @module("@elysiajs/cors") external cors: unit => 'plugin = "cors" -} - -module Postgres = { - type client - @module("./db/postgres-client.res.mjs") @new - external makeClient: 'config => client = "PostgresClient" - @send external connect: client => promise = "connect" -} - -type serverConfig = { - port: int, - database: JSON.t, -} - -@module("./config-loader.res.mjs") -external loadConfig: unit => promise = "loadConfig" - -module DashboardServer = { - type t = { - mutable config: option, - mutable db: option, - app: Elysia.t, - } - - let make = () => { - { - config: None, - db: None, - app: Elysia.make(), - } - } - - let setupRoutes = (self: t) => { - self.app - ->Elysia.use(Cors.cors()) - ->Elysia.group("/api", app => { - app - ->Elysia.get("/health", _ => {"status": "ok", "timestamp": Date.now()}) - ->Elysia.group("/workflows", app => { - app - ->Elysia.get("/", _ => %raw(`[]`)) // Placeholder for workflow list - ->Elysia.get("/:id", _ => %raw(`{}`)) - }) - }) - } - - let initialize = async (self: t) => { - Console.log("Initializing Dashboard Server...") - - let config = await loadConfig() - self.config = Some(config) - - let db = Postgres.makeClient(config.database) - self.db = Some(db) - await Postgres.connect(db) - - let _ = setupRoutes(self) - - let port = config.port - let _ = self.app->Elysia.listen(port) - Console.log(`Dashboard API listening on port ${Int.toString(port)}`) - } -} - -let server = DashboardServer.make() -let _ = DashboardServer.initialize(server) diff --git a/praxis/SymbolicEngine/dashboard/src/ApiServer.res.js b/praxis/SymbolicEngine/dashboard/src/ApiServer.res.js index 281071e..7f08d1d 100644 --- a/praxis/SymbolicEngine/dashboard/src/ApiServer.res.js +++ b/praxis/SymbolicEngine/dashboard/src/ApiServer.res.js @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE import * as Elysia from "elysia"; import * as Cors from "@elysiajs/cors"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as Primitive_option from "@/runtime/lib/es6/Primitive_option.js"; import * as ConfigLoaderResMjs from "./config-loader.res.mjs"; import * as PostgresClientResMjs from "./db/postgres-client.res.mjs"; diff --git a/praxis/SymbolicEngine/dashboard/src/ConfigLoader.res b/praxis/SymbolicEngine/dashboard/src/ConfigLoader.res deleted file mode 100644 index 1bf795a..0000000 --- a/praxis/SymbolicEngine/dashboard/src/ConfigLoader.res +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Config Loader — Dashboard Specification Ingestion - * Fully ported to ReScript v12 - */ - -module Path = { - @module("path") external join: (string, string) => string = "join" - @module("path") external dirname: string => string = "dirname" -} - -module Fs = { - @module("fs") external readFileSync: (string, string) => string = "readFileSync" - @module("fs") external existsSync: string => bool = "existsSync" -} - -// Simple TOML parser implementation -let parseSimpleTOML = (content: string): JSON.t => { - let result = Dict.make() - let currentSection = ref(result) - - let lines = String.split(content, "\n") - lines->Array.forEach(line => { - let trimmed = String.trim(line) - if String.startsWith(trimmed, "#") || trimmed == "" { - () // Skip comments and empty lines - } else if String.startsWith(trimmed, "[") && String.endsWith(trimmed, "]") { - let sectionName = String.substring(trimmed, ~start=1, ~end=String.length(trimmed) - 1) - let section = Dict.make() - Dict.set(result, sectionName, JSON.Encode.object(section)) - currentSection := section - } else { - let parts = String.split(trimmed, "=") - if Array.length(parts) == 2 { - let key = String.trim(Belt.Array.getExn(parts, 0)) - let value = String.trim(Belt.Array.getExn(parts, 1)) - - // Basic type inference - let jsonValue = if String.startsWith(value, "\"") && String.endsWith(value, "\"") { - JSON.Encode.string(String.substring(value, ~start=1, ~end=String.length(value) - 1)) - } else if value == "true" { - JSON.Encode.bool(true) - } else if value == "false" { - JSON.Encode.bool(false) - } else { - switch Int.fromString(value) { - | Some(n) => JSON.Encode.int(n) - | None => JSON.Encode.string(value) - } - } - Dict.set(currentSection.contents, key, jsonValue) - } - } - }) - - JSON.Encode.object(result) -} - -let loadConfig = async (~configPath: option=?): JSON.t => { - let path = switch configPath { - | Some(p) => p - | None => Path.join(%raw(`import.meta.dirname`), "../dashboard-config.toml") - } - - if Fs.existsSync(path) { - let content = Fs.readFileSync(path, "utf-8") - parseSimpleTOML(content) - } else { - // Return default config as JSON - Obj.magic({ - "server": {"port": 4000, "host": "localhost"}, - "database": {"host": "localhost", "port": 5432}, - }) - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/ConfigLoader.res.js b/praxis/SymbolicEngine/dashboard/src/ConfigLoader.res.js index a5a9eff..7ba8705 100644 --- a/praxis/SymbolicEngine/dashboard/src/ConfigLoader.res.js +++ b/praxis/SymbolicEngine/dashboard/src/ConfigLoader.res.js @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE import * as Fs from "fs"; import * as Path from "path"; -import * as Core__Int from "@rescript/core/src/Core__Int.res.js"; -import * as Belt_Array from "@rescript/runtime/lib/es6/Belt_Array.js"; +import * as Core__Int from "@/core/src/Core__Int.res.js"; +import * as Belt_Array from "@/runtime/lib/es6/Belt_Array.js"; let Path$1 = {}; diff --git a/praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res b/praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res deleted file mode 100644 index 89e14a1..0000000 --- a/praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Praxis API Routes — Central Routing Manifest - * Fully ported to ReScript v12 - */ - -open Types -open AuditController -open BaselineController -open ExecutionController -open SymbolController -open WorkflowController - -module Elysia = { - type t - type context<'q, 'p, 'b> = { - query: 'q, - params: 'p, - body: 'b, - } - @send external get: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "get" - @send external post: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "post" - @send external patch: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "patch" - @send external delete: (t, string, context<'q, 'p, 'b> => promise<'res>) => t = "delete" - @send external group: (t, string, t => t) => t = "group" -} - -let setupAuditRoutes = (app: Elysia.t, controller: AuditController.t) => { - app->Elysia.group("/audits", app => { - app - ->Elysia.get("/", async _ctx => { - let workflowId = %raw(`ctx.query.workflow_id`) - await AuditController.list(controller, workflowId) - }) - ->Elysia.get("/stats", async _ => { - await AuditController.getStats(controller) - }) - }) -} - -let setupBaselineRoutes = (app: Elysia.t, controller: BaselineController.t) => { - app->Elysia.group("/baselines", app => { - app - ->Elysia.get("/", async _ctx => { - let workflowId = %raw(`ctx.query.workflow_id`) - await BaselineController.list(controller, workflowId) - }) - ->Elysia.get("/normative/:workflow_id", async _ctx => { - let workflowId = %raw(`ctx.params.workflow_id`) - await BaselineController.getNormative(controller, workflowId) - }) - }) -} - -let setupExecutionRoutes = (app: Elysia.t, controller: ExecutionController.t) => { - app->Elysia.group("/executions", app => { - app - ->Elysia.get("/", async _ctx => { - let status = %raw(`ctx.query.status`) - await ExecutionController.list(controller, status) - }) - ->Elysia.get("/stats", async _ => { - await ExecutionController.getStats(controller) - }) - }) -} - -let setupSymbolRoutes = (app: Elysia.t, controller: SymbolController.t) => { - app->Elysia.group("/symbols", app => { - app - ->Elysia.get("/", async _ => { - await SymbolController.list(controller, None) - }) - ->Elysia.get("/search", async _ctx => { - let q = %raw(`ctx.query.q`) - let type_ = %raw(`ctx.query.type`) - await SymbolController.search(controller, q, type_) - }) - }) -} - -let setupWorkflowRoutes = (app: Elysia.t, controller: WorkflowController.t) => { - app->Elysia.group("/workflows", app => { - app - ->Elysia.get("/", async _ctx => { - let status = %raw(`ctx.query.status`) - await WorkflowController.list(controller, status) - }) - ->Elysia.post("/", async _ctx => { - let name = %raw(`ctx.body.name`) - let path = %raw(`ctx.body.manifest_path`) - await WorkflowController.create(controller, name, path) - }) - ->Elysia.get("/:id/symbols", async _ctx => { - let id = %raw(`ctx.params.id`) - await WorkflowController.getSymbols(controller, id) - }) - }) -} diff --git a/praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res.js b/praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res.js index db91600..6481127 100644 --- a/praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res.js +++ b/praxis/SymbolicEngine/dashboard/src/api/ApiRoutes.res.js @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE import * as AuditController from "./controllers/AuditController.res.js"; import * as SymbolController from "./controllers/SymbolController.res.js"; diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res b/praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res deleted file mode 100644 index f7ca3cc..0000000 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Audit Controller — Compliance Verification Management - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module AuditController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * LIST: Returns a paginated log of audit events. - */ - let list = async (self: t, _workflowId: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM audits") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => { - success: false, - error: {code: "DB_ERROR", message: "Not connected"}, - } - } - } catch { - | _ => { - success: false, - error: {code: "DB_ERROR", message: "Failed to fetch audits"}, - } - } - } - - /** - * STATISTICS: Aggregates audit results. - */ - let getStats = async (self: t): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT COUNT(*) FROM audits") - { - success: true, - data: Obj.magic({"compliance_score": 100.0, "total_audits": 0}), - } - } - | None => { - success: false, - error: {code: "DB_ERROR", message: "Not connected"}, - } - } - } catch { - | _ => { - success: false, - error: {code: "DB_ERROR", message: "Failed to fetch audit stats"}, - } - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res.js b/praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res.js index 55bf910..2528659 100644 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res.js +++ b/praxis/SymbolicEngine/dashboard/src/api/controllers/AuditController.res.js @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as Primitive_option from "@/runtime/lib/es6/Primitive_option.js"; function make(db) { return { diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/BaselineController.res b/praxis/SymbolicEngine/dashboard/src/api/controllers/BaselineController.res deleted file mode 100644 index 0cb7e3a..0000000 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/BaselineController.res +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Baseline Controller — Normative State Management - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module BaselineController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * GET NORMATIVE: Retrieves the authoritative policy snapshot. - */ - let getNormative = async (self: t, workflowId: string): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql( - sql, - `SELECT * FROM baselines WHERE workflow_id = '${workflowId}' AND is_normative = true LIMIT 1`, - ) - // Simplified placeholder logic - { - success: false, - error: {code: "NOT_FOUND", message: "Normative baseline not found for workflow"}, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch baseline"}} - } - } - - /** - * LIST: Returns a paginated set of historical baselines. - */ - let list = async (self: t, _workflowId: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM baselines") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch baselines"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/BaselineController.res.js b/praxis/SymbolicEngine/dashboard/src/api/controllers/BaselineController.res.js index dd245c4..05c0bb4 100644 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/BaselineController.res.js +++ b/praxis/SymbolicEngine/dashboard/src/api/controllers/BaselineController.res.js @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as Primitive_option from "@/runtime/lib/es6/Primitive_option.js"; function make(db) { return { diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/ExecutionController.res b/praxis/SymbolicEngine/dashboard/src/api/controllers/ExecutionController.res deleted file mode 100644 index 0992334..0000000 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/ExecutionController.res +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Execution Controller — Swarm Trace Observability - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module ExecutionController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * LIST: Returns a paginated log of execution attempts. - */ - let list = async (self: t, _status: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM executions") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch executions"}} - } - } - - /** - * STATISTICS: Aggregates execution performance. - */ - let getStats = async (self: t): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT COUNT(*) FROM executions") - { - success: true, - data: { - total: 0, - running: 0, - completed_today: 0, - failed_today: 0, - success_rate: 100.0, - avg_duration_ms: 0.0, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch execution stats"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/ExecutionController.res.js b/praxis/SymbolicEngine/dashboard/src/api/controllers/ExecutionController.res.js index 26e1117..d218d71 100644 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/ExecutionController.res.js +++ b/praxis/SymbolicEngine/dashboard/src/api/controllers/ExecutionController.res.js @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as Primitive_option from "@/runtime/lib/es6/Primitive_option.js"; function make(db) { return { diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/SymbolController.res b/praxis/SymbolicEngine/dashboard/src/api/controllers/SymbolController.res deleted file mode 100644 index 8b35bf4..0000000 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/SymbolController.res +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Symbol Controller — Atomic Logic Unit Management - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module SymbolController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * LIST: Returns a paginated set of symbols. - */ - let list = async (self: t, _type: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM symbols") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch symbols"}} - } - } - - /** - * SEARCH: Filters the symbol library using a name match. - */ - let search = async (self: t, query: string, _type: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql( - sql, - `SELECT * FROM symbols WHERE name ILIKE '%${query}%'`, - ) - { - success: true, - data: [], - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to search symbols"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/SymbolController.res.js b/praxis/SymbolicEngine/dashboard/src/api/controllers/SymbolController.res.js index 1d66558..20bf485 100644 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/SymbolController.res.js +++ b/praxis/SymbolicEngine/dashboard/src/api/controllers/SymbolController.res.js @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as Primitive_option from "@/runtime/lib/es6/Primitive_option.js"; function make(db) { return { diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/WorkflowController.res b/praxis/SymbolicEngine/dashboard/src/api/controllers/WorkflowController.res deleted file mode 100644 index 69b6826..0000000 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/WorkflowController.res +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Workflow Controller — Symbolic Logic Orchestration - * Fully ported to ReScript v12 - */ - -open Types -open PostgresClient - -module WorkflowController = { - type t = {db: PostgresClient.t} - - let make = (db: PostgresClient.t) => {db: db} - - /** - * INVENTORY: Lists workflows. - */ - let list = async (self: t, _status: option): apiResponse> => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql(sql, "SELECT * FROM workflows") - { - success: true, - data: [], - metadata: { - timestamp: Date.now()->Float.toString, - pagination: { - page: 1, - limit: 20, - total: 0, - pages: 1, - }, - }, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch workflows"}} - } - } - - /** - * PROVENANCE: Creates a new workflow record. - */ - let create = async ( - self: t, - name: string, - manifestPath: string, - ): apiResponse => { - try { - switch self.db.sql { - | Some(sql) => { - let _results = await PostgresClient.querySql( - sql, - `INSERT INTO workflows (name, manifest_path) VALUES ('${name}', '${manifestPath}')`, - ) - // Simplified placeholder logic - { - success: false, - error: {code: "ERROR", message: "Creation placeholder"}, - } - } - | None => {success: false, error: {code: "DB_ERROR", message: "Not connected"}} - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to create workflow"}} - } - } - - /** - * SYMBOL INSPECTION: Retrieves symbols for a specific workflow. - */ - let getSymbols = async (self: t, workflowId: string): apiResponse> => { - try { - let _results = await PostgresClient.getSymbolsByWorkflow(self.db, workflowId) - { - success: true, - data: [], - } - } catch { - | _ => {success: false, error: {code: "DB_ERROR", message: "Failed to fetch symbols"}} - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/api/controllers/WorkflowController.res.js b/praxis/SymbolicEngine/dashboard/src/api/controllers/WorkflowController.res.js index 6ca8a60..d757a5d 100644 --- a/praxis/SymbolicEngine/dashboard/src/api/controllers/WorkflowController.res.js +++ b/praxis/SymbolicEngine/dashboard/src/api/controllers/WorkflowController.res.js @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE import * as PostgresClient from "../../db/PostgresClient.res.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as Primitive_option from "@/runtime/lib/es6/Primitive_option.js"; function make(db) { return { diff --git a/praxis/SymbolicEngine/dashboard/src/api/routes/HealthRoutes.res b/praxis/SymbolicEngine/dashboard/src/api/routes/HealthRoutes.res deleted file mode 100644 index 38d9120..0000000 --- a/praxis/SymbolicEngine/dashboard/src/api/routes/HealthRoutes.res +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Health Check API Routes — Service Observability Endpoints - * Fully ported to ReScript v12 - */ - -module Elysia = { - type t - @send external get: (t, string, 'handler) => t = "get" - @send external group: (t, string, t => t) => t = "group" -} - -module Postgres = { - type client - @send external healthCheck: client => promise = "healthCheck" -} - -type memoryUsage = { - rss: float, - heapTotal: float, - heapUsed: float, -} - -@val @scope("process") -external memoryUsage: unit => memoryUsage = "memoryUsage" - -@val @scope("process") -external uptime: unit => float = "uptime" - -let setupHealthRoutes = (app: Elysia.t, db: Postgres.client) => { - app->Elysia.group("/health", app => { - app - ->Elysia.get("/", async _ => { - let dbOk = await Postgres.healthCheck(db) - let mem = memoryUsage() - - { - "status": dbOk ? "healthy" : "degraded", - "database": dbOk ? "connected" : "disconnected", - "memoryMb": Float.toInt(mem.heapUsed /. 1024.0 /. 1024.0), - "timestamp": Date.now(), - } - }) - ->Elysia.get("/detailed", async _ => { - let dbOk = await Postgres.healthCheck(db) - let mem = memoryUsage() - - { - "status": dbOk ? "healthy" : "unhealthy", - "process": { - "uptime": uptime(), - "pid": %raw(`process.pid`), - "arch": %raw(`process.arch`), - }, - "memory": { - "rss": mem.rss, - "heapTotal": mem.heapTotal, - "heapUsed": mem.heapUsed, - }, - "database": { - "connected": dbOk, - } - } - }) - }) -} diff --git a/praxis/SymbolicEngine/dashboard/src/api/routes/HealthRoutes.res.js b/praxis/SymbolicEngine/dashboard/src/api/routes/HealthRoutes.res.js index ab211ff..5963e32 100644 --- a/praxis/SymbolicEngine/dashboard/src/api/routes/HealthRoutes.res.js +++ b/praxis/SymbolicEngine/dashboard/src/api/routes/HealthRoutes.res.js @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE let Elysia = {}; diff --git a/praxis/SymbolicEngine/dashboard/src/db/PostgresClient.res b/praxis/SymbolicEngine/dashboard/src/db/PostgresClient.res deleted file mode 100644 index d2cfb08..0000000 --- a/praxis/SymbolicEngine/dashboard/src/db/PostgresClient.res +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * PostgreSQL Client — Ecto Database Bridge - * Fully ported to ReScript v12 - */ - -module Types = { - type sql - type queryResult<'a> = array<'a> -} - -@module("postgres") -external makeSql: JSON.t => Types.sql = "default" - -module PostgresClient = { - type t = { - mutable sql: option, - mutable connected: bool, - config: JSON.t, - } - - @send - external querySql: (Types.sql, string) => promise> = "unsafe" - - let make = (config: JSON.t) => { - { - sql: None, - connected: false, - config: config, - } - } - - let connect = async (self: t) => { - try { - let sql = makeSql(self.config) - self.sql = Some(sql) - // Perform simple SELECT 1 heartbeat - let _ = await sql->querySql("SELECT 1 as connected") - self.connected = true - Console.log("Postgres connected successfully") - } catch { - | _ => - Console.error("DB Connection failure") - failwith("Database connection failed") - } - } - - let healthCheck = async (self: t): bool => { - switch self.sql { - | None => false - | Some(sql) => - try { - let _ = await sql->querySql("SELECT 1") - true - } catch { - | _ => false - } - } - } - - let getWorkflows = async (self: t, _limit: int, _offset: int) => { - switch self.sql { - | None => failwith("Not connected") - | Some(sql) => - await sql->querySql("SELECT * FROM workflows ORDER BY updated_at DESC") - } - } - - let getSymbolsByWorkflow = async (self: t, workflowId: string) => { - switch self.sql { - | None => failwith("Not connected") - | Some(sql) => - await sql->querySql(`SELECT s.* FROM symbols s JOIN workflow_symbols ws ON s.id = ws.symbol_id WHERE ws.workflow_id = '${workflowId}'`) - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/db/PostgresClient.res.js b/praxis/SymbolicEngine/dashboard/src/db/PostgresClient.res.js index dc3e26f..28619c6 100644 --- a/praxis/SymbolicEngine/dashboard/src/db/PostgresClient.res.js +++ b/praxis/SymbolicEngine/dashboard/src/db/PostgresClient.res.js @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE import Postgres from "postgres"; -import * as Pervasives from "@rescript/runtime/lib/es6/Pervasives.js"; -import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; +import * as Pervasives from "@/runtime/lib/es6/Pervasives.js"; +import * as Primitive_option from "@/runtime/lib/es6/Primitive_option.js"; let Types = {}; diff --git a/praxis/SymbolicEngine/dashboard/src/db/state-aggregator.ts b/praxis/SymbolicEngine/dashboard/src/db/state-aggregator.ts deleted file mode 100644 index e8b1931..0000000 --- a/praxis/SymbolicEngine/dashboard/src/db/state-aggregator.ts +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * State Aggregator — Multi-Source Telemetry Consolidation. - * - * This module implements the "Unified Observability" layer for the - * Praxis Dashboard. It aggregates real-time and historical state - * data from heterogeneous sources into a consistent schema. - * - * DATA SOURCES: - * 1. **PostgreSQL (Ecto)**: Master record for Workflows and Symbols. - * 2. **Swarm API**: Current status of the distributed worker cluster. - * 3. **PowerShell Kernel**: Local system state and role validation. - * - * PERFORMANCE: Implements a non-blocking internal cache with a - * 5-second TTL to minimize database pressure during high-frequency - * dashboard refreshes. - */ - -import type { DashboardStats, StateConfig } from '@types/index'; -import { PostgresClient } from './postgres-client'; - -export class StateAggregator { - /** - * CONSOLIDATION: Triggers parallel retrieval from all active sources. - * Uses `Promise.all` to ensure the dashboard remains responsive - * even if one source is high-latency. - */ - async getDashboardStats(): Promise { - const [workflows, executions, audits, system] = await Promise.all([ - this.getWorkflowStats(), - this.getExecutionStats(), - this.getAuditStats(), - this.getSystemStats(), - ]); - - return { workflows, executions, audits, system, timestamp: new Date().toISOString() }; - } - - /** - * EXTERNAL PROBE (Swarm): Fetches live worker statistics via HTTP. - */ - private async getSwarmState(): Promise | null> { - // ... [Implementation using Fetch API with caching] - } - - /** - * EXTERNAL PROBE (PowerShell): Executes a local `pwsh` command to - * retrieve the low-level system baseline. - */ - async getPowerShellState(): Promise | null> { - // ... [Implementation using Bun.spawn] - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/types/Types.res b/praxis/SymbolicEngine/dashboard/src/types/Types.res deleted file mode 100644 index b4c8448..0000000 --- a/praxis/SymbolicEngine/dashboard/src/types/Types.res +++ /dev/null @@ -1,348 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * WP Praxis Dashboard - Type Definitions - * Shared types for the symbolic engine dashboard - * Fully ported to ReScript v12 - */ - -// ============================================================================ -// Core Symbol Types -// ============================================================================ - -type symbolType = [ - | #action - | #query - | #transformation - | #validation - | #audit -] - -type symbolMetadata = { - description?: string, - version?: string, - author?: string, - tags?: array, - dependencies?: array, -} - -type symbol = { - id: string, - name: string, - @as("type") type_: symbolType, - context: string, - dispatch: string, - parameters: Dict.t, - metadata: symbolMetadata, - created_at: string, - updated_at: string, -} - -// ============================================================================ -// Workflow Types -// ============================================================================ - -type workflowDependencyType = [ - | #required - | #optional - | #conditional -] - -type workflowDependency = { - from_symbol: string, - to_symbol: string, - @as("type") type_: workflowDependencyType, -} - -type workflowStatus = [ - | #draft - | #active - | #paused - | #archived - | #error -] - -type workflow = { - id: string, - name: string, - description?: string, - symbols: array, - dependencies: array, - status: workflowStatus, - manifest_path: string, - created_at: string, - updated_at: string, - last_execution?: string, -} - -// ============================================================================ -// Execution Types -// ============================================================================ - -type executionStatus = [ - | #pending - | #running - | #completed - | #failed - | #cancelled - | #timeout -] - -type log_level = [ - | #debug - | #info - | #warn - | #error -] - -type executionLog = { - timestamp: string, - level: log_level, - message: string, - context?: Dict.t, -} - -type executionMetrics = { - cpu_time_ms?: float, - memory_mb?: float, - io_operations?: int, - cache_hits?: int, - cache_misses?: int, -} - -type changeType = [ - | #create - | #update - | #delete - | #move - | #copy -] - -type change = { - id: string, - @as("type") type_: changeType, - path: string, - old_value?: JSON.t, - new_value?: JSON.t, - timestamp: string, -} - -type executionResult = { - success: bool, - output?: JSON.t, - changes?: array, - metrics?: executionMetrics, -} - -type executionError = { - code: string, - message: string, - stack?: string, - context?: Dict.t, -} - -type execution = { - id: string, - workflow_id: string, - symbol_id?: string, - status: executionStatus, - started_at: string, - completed_at?: string, - duration_ms?: float, - result?: executionResult, - error?: executionError, - logs: array, - metadata: Dict.t, -} - -// ============================================================================ -// Audit Types -// ============================================================================ - -type deviationType = [ - | #missing - | #unexpected - | #modified - | #type_mismatch - | #value_mismatch - | #permission - | #integrity -] - -type severity = [ - | #low - | #medium - | #high - | #critical -] - -type deviation = { - id: string, - @as("type") type_: deviationType, - severity: severity, - path: string, - expected: JSON.t, - actual: JSON.t, - message: string, - context?: Dict.t, -} - -type auditSummary = { - total_deviations: int, - by_severity: Dict.t, - by_type: Dict.t, - compliance_score: float, -} - -type audit = { - id: string, - workflow_id: string, - execution_id: string, - baseline_id?: string, - started_at: string, - completed_at?: string, - status: [ | #running | #completed | #failed ], - deviations: array, - summary: auditSummary, -} - -// ============================================================================ -// Baseline Types -// ============================================================================ - -type baselineSnapshot = { - version: string, - timestamp: string, - state: Dict.t, - checksums: Dict.t, - metadata: Dict.t, -} - -type baseline = { - id: string, - name: string, - description?: string, - workflow_id: string, - snapshot: baselineSnapshot, - created_at: string, - created_by?: string, - is_normative: bool, -} - -// ============================================================================ -// Statistics Types -// ============================================================================ - -type workflowStats = { - total: int, - active: int, - paused: int, - error: int, -} - -type executionStats = { - total: int, - running: int, - completed_today: int, - failed_today: int, - success_rate: float, - avg_duration_ms: float, -} - -type auditStats = { - total_audits: int, - total_deviations: int, - critical_deviations: int, - avg_compliance_score: float, -} - -type systemStats = { - uptime_seconds: float, - memory_usage_mb: float, - cpu_usage_percent: float, - active_connections: int, -} - -type dashboardStats = { - workflows: workflowStats, - executions: executionStats, - audits: auditStats, - system: systemStats, - timestamp: string, -} - -// ============================================================================ -// API Request/Response Types -// ============================================================================ - -type pagination = { - page: int, - limit: int, - total: int, - pages: int, -} - -type apiMetadata = { - timestamp: string, - request_id?: string, - pagination?: pagination, -} - -type apiError = { - code: string, - message: string, - details?: Dict.t, -} - -type apiResponse<'a> = { - success: bool, - data?: 'a, - error?: apiError, - metadata?: apiMetadata, -} - -// ============================================================================ -// Config Types -// ============================================================================ - -type corsConfig = { - enabled: bool, - origins: array, - methods: array, - credentials: bool, -} - -type webSocketConfig = { - enabled: bool, - path: string, - heartbeat_interval: int, - max_payload: int, -} - -type serverConfig = { - host: string, - port: int, - env: [ | #development | #staging | #production ], - cors: corsConfig, - websocket: webSocketConfig, -} - -type databaseConfig = { - host: string, - port: int, - database: string, - user: string, - password: string, - max_connections: int, - idle_timeout: int, - connection_timeout: int, - ssl: { - enabled: bool, - reject_unauthorized: bool, - }, -} - -type dashboardConfig = { - server: serverConfig, - database: databaseConfig, - // Additional config types omitted for brevity, can be added as needed -} diff --git a/praxis/SymbolicEngine/dashboard/src/types/Types.res.js b/praxis/SymbolicEngine/dashboard/src/types/Types.res.js index 747d24d..af76dec 100644 --- a/praxis/SymbolicEngine/dashboard/src/types/Types.res.js +++ b/praxis/SymbolicEngine/dashboard/src/types/Types.res.js @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res b/praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res deleted file mode 100644 index 79ab1df..0000000 --- a/praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Dashboard Events — Real-Time WebSocket Broadcasting - * Fully ported to ReScript v12 - */ - -module WebSocket = { - type t - @send external send: (t, string) => unit = "send" -} - -module DashboardEvents = { - type t = { - connections: Set.t, - mutable heartbeatInterval: option, - } - - let make = () => { - { - connections: Set.make(), - heartbeatInterval: None, - } - } - - let createMessage = (type_: string, payload: JSON.t): JSON.t => { - Obj.magic({ - "type": type_, - "payload": payload, - "timestamp": Date.now()->Float.toString, - }) - } - - let sendToClient = (ws: WebSocket.t, type_: string, payload: JSON.t) => { - let message = createMessage(type_, payload) - ws->WebSocket.send(JSON.stringify(message)) - } - - let broadcast = (self: t, type_: string, payload: JSON.t) => { - let message = createMessage(type_, payload) - let messageStr = JSON.stringify(message) - - self.connections->Set.forEach(ws => { - try { - ws->WebSocket.send(messageStr) - } catch { - | _ => { - let _ = self.connections->Set.delete(ws) - } - } - }) - } - - let broadcastExecutionProgress = (self: t, executionId: string, progress: float, message: option) => { - self->broadcast("execution_progress", Obj.magic({ - "execution_id": executionId, - "progress": progress, - "message": message, - "timestamp": Date.now()->Float.toString, - })) - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res.js b/praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res.js index 29d9584..50dc7c7 100644 --- a/praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res.js +++ b/praxis/SymbolicEngine/dashboard/src/websocket/DashboardEvents.res.js @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE let WebSocket = {}; diff --git a/praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res b/praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res deleted file mode 100644 index 55924a5..0000000 --- a/praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * Stream Handler — Real-Time Execution Observability - * Fully ported to ReScript v12 - */ - -module StreamHandler = { - type t = { - activeStreams: Map.t>, - events: DashboardEvents.DashboardEvents.t, - } - - let make = (events: DashboardEvents.DashboardEvents.t) => { - { - activeStreams: Map.make(), - events: events, - } - } - - let subscribe = (self: t, executionId: string, ws: DashboardEvents.WebSocket.t) => { - let subscribers = switch self.activeStreams->Map.get(executionId) { - | Some(s) => s - | None => { - let s = Set.make() - self.activeStreams->Map.set(executionId, s) - s - } - } - subscribers->Set.add(ws) - } - - let streamLog = (self: t, executionId: string, level: string, message: string) => { - switch self.activeStreams->Map.get(executionId) { - | None => () - | Some(subscribers) => - subscribers->Set.forEach(ws => { - try { - DashboardEvents.DashboardEvents.sendToClient( - ws, - "log_entry", - Obj.magic({ - "execution_id": executionId, - "level": level, - "message": message, - "timestamp": Date.now()->Float.toString, - }), - ) - } catch { - | _ => { - let _ = subscribers->Set.delete(ws) - } - } - }) - } - } -} diff --git a/praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res.js b/praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res.js index 82632d2..aab0ce3 100644 --- a/praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res.js +++ b/praxis/SymbolicEngine/dashboard/src/websocket/StreamHandler.res.js @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE import * as DashboardEvents from "./DashboardEvents.res.js"; diff --git a/praxis/SymbolicEngine/dashboard/tsconfig.json b/praxis/SymbolicEngine/dashboard/tsconfig.json deleted file mode 100644 index a0b9f33..0000000 --- a/praxis/SymbolicEngine/dashboard/tsconfig.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "compilerOptions": { - // Type Checking - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedIndexedAccess": true, - "noImplicitOverride": true, - "allowUnusedLabels": false, - "allowUnreachableCode": false, - - // Modules - "module": "ESNext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "allowImportingTsExtensions": true, - - // Emit - "noEmit": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - - // JavaScript Support - "allowJs": true, - "checkJs": false, - - // Interop Constraints - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - - // Language and Environment - "target": "ESNext", - "lib": ["ESNext", "DOM", "DOM.Iterable"], - - // Projects - "composite": true, - "incremental": true, - - // Bun-specific - "types": ["bun-types"], - - // Paths - "baseUrl": ".", - "paths": { - "@/*": ["src/*"], - "@api/*": ["src/api/*"], - "@db/*": ["src/db/*"], - "@websocket/*": ["src/websocket/*"], - "@types/*": ["src/types/*"] - } - }, - "include": [ - "src/**/*", - "js/**/*", - "injector/**/*" - ], - "exclude": [ - "node_modules", - "dist", - "**/*.spec.ts", - "**/*.test.ts" - ] -} diff --git a/praxis/SymbolicEngine/graphql/README.md b/praxis/SymbolicEngine/graphql/README.md index 4173e12..9492f88 100644 --- a/praxis/SymbolicEngine/graphql/README.md +++ b/praxis/SymbolicEngine/graphql/README.md @@ -72,7 +72,7 @@ Visit `http://localhost:4000/graphql` in your browser to access the interactive - **Runtime**: Bun (high-performance JavaScript runtime) - **GraphQL Server**: Apollo Server 4 -- **TypeScript**: Full type safety +- ****: Full type safety - **Database**: PostgreSQL (via pg driver, connects to Ecto schema) - **Swarm State**: SQLite (better-sqlite3) - **WebSocket**: graphql-ws for real-time subscriptions @@ -85,14 +85,14 @@ Visit `http://localhost:4000/graphql` in your browser to access the interactive graphql/ ├── schema.graphql # GraphQL schema definition ├── package.json # Dependencies and scripts -├── tsconfig.json # TypeScript configuration +├── onfig.json # configuration ├── codegen.yml # GraphQL codegen config ├── .env.example # Environment template │ ├── src/ │ ├── server.ts # Main Apollo Server │ ├── context.ts # GraphQL context builder -│ ├── types.ts # TypeScript type definitions +│ ├── types.ts # type definitions │ │ │ ├── resolvers/ # GraphQL resolvers │ │ ├── index.ts # Combined resolvers @@ -127,7 +127,7 @@ graphql/ │ ├── playground.html # GraphiQL playground │ ├── example-queries.graphql # Example queries │ └── js/ -│ └── graphql-client.ts # TypeScript client +│ └── graphql-client.ts # client │ └── tests/ # Tests ├── schema.test.ts # Schema validation @@ -289,11 +289,11 @@ subscription AuditCompletions { } ``` -## TypeScript Client +## Client -Use the TypeScript client library for type-safe API access: +Use the client library for type-safe API access: -```typescript +``` import { createClient } from './client/js/graphql-client'; const client = createClient({ @@ -319,7 +319,7 @@ const unsubscribe = client.subscribeToWorkflow('1', (workflow) => { All database queries are batched and cached using DataLoader to prevent N+1 query problems: -```typescript +``` // These resolve efficiently even in nested queries workflow { executions { @@ -413,7 +413,7 @@ Logs are written to: ### Code Generation -Generate TypeScript types from schema: +Generate types from schema: ```bash bun run codegen diff --git a/praxis/SymbolicEngine/graphql/SCHEMA_GUIDE.md b/praxis/SymbolicEngine/graphql/SCHEMA_GUIDE.md index c126344..4124234 100644 --- a/praxis/SymbolicEngine/graphql/SCHEMA_GUIDE.md +++ b/praxis/SymbolicEngine/graphql/SCHEMA_GUIDE.md @@ -704,7 +704,7 @@ query { ### Handling Errors in Client -```typescript +``` const { data, errors } = await client.query({ query }); if (errors) { @@ -806,7 +806,7 @@ query GetSymbol($id: ID!) { All nullable fields should be handled: -```typescript +``` workflow.executions?.forEach(exec => { const duration = exec.duration ?? 0; const node = exec.node?.name ?? 'unassigned'; @@ -841,7 +841,7 @@ subscription { Always handle potential errors: -```typescript +``` try { const { data, errors } = await client.query({ ... }); diff --git a/praxis/SymbolicEngine/graphql/client/js/graphql-client.ts b/praxis/SymbolicEngine/graphql/client/js/graphql-client.ts deleted file mode 100644 index bab3cd3..0000000 --- a/praxis/SymbolicEngine/graphql/client/js/graphql-client.ts +++ /dev/null @@ -1,243 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis GraphQL Client - * - * TypeScript client library for interacting with the GraphQL API - */ - -export interface GraphQLClientConfig { - endpoint: string; - token?: string; - headers?: Record; -} - -export interface GraphQLRequest { - query: string; - variables?: Record; - operationName?: string; -} - -export interface GraphQLResponse { - data?: T; - errors?: Array<{ - message: string; - locations?: Array<{ line: number; column: number }>; - path?: string[]; - extensions?: Record; - }>; -} - -export class WpPraxisGraphQLClient { - private endpoint: string; - private headers: Record; - - constructor(config: GraphQLClientConfig) { - this.endpoint = config.endpoint; - this.headers = { - 'Content-Type': 'application/json', - ...(config.token ? { Authorization: `Bearer ${config.token}` } : {}), - ...config.headers, - }; - } - - async query(request: GraphQLRequest): Promise> { - const response = await fetch(this.endpoint, { - method: 'POST', - headers: this.headers, - body: JSON.stringify(request), - }); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - return response.json(); - } - - async mutate(request: GraphQLRequest): Promise> { - return this.query(request); - } - - subscribe(request: GraphQLRequest, callbacks: { - onData: (data: any) => void; - onError?: (error: Error) => void; - onComplete?: () => void; - }): () => void { - // Convert HTTP endpoint to WebSocket endpoint - const wsEndpoint = this.endpoint.replace(/^http/, 'ws'); - - const ws = new WebSocket(wsEndpoint, 'graphql-ws'); - - ws.onopen = () => { - // Send connection init - ws.send(JSON.stringify({ type: 'connection_init' })); - - // Send subscription - ws.send( - JSON.stringify({ - type: 'start', - id: '1', - payload: request, - }) - ); - }; - - ws.onmessage = (event) => { - const message = JSON.parse(event.data); - - switch (message.type) { - case 'data': - callbacks.onData(message.payload.data); - break; - case 'error': - callbacks.onError?.(new Error(message.payload.message)); - break; - case 'complete': - callbacks.onComplete?.(); - ws.close(); - break; - } - }; - - ws.onerror = (error) => { - callbacks.onError?.(new Error('WebSocket error')); - }; - - // Return unsubscribe function - return () => { - ws.send(JSON.stringify({ type: 'stop', id: '1' })); - ws.close(); - }; - } - - // Convenience methods - async getSymbols(filters?: { - type?: string; - context?: string; - status?: string; - limit?: number; - }) { - return this.query({ - query: ` - query GetSymbols($type: SymbolType, $context: SymbolContext, $status: SymbolStatus, $limit: Int) { - symbols(type: $type, context: $context, status: $status, limit: $limit) { - id - name - type - context - status - dispatchTarget - priority - } - } - `, - variables: filters, - }); - } - - async getWorkflow(id: string) { - return this.query({ - query: ` - query GetWorkflow($id: ID!) { - workflow(id: $id) { - id - name - status - manifestPath - startedAt - completedAt - executions { - id - status - symbol { - name - } - } - } - } - `, - variables: { id }, - }); - } - - async executeWorkflow(workflowId: string, parameters?: Record) { - return this.mutate({ - query: ` - mutation ExecuteWorkflow($input: ExecuteWorkflowInput!) { - executeWorkflow(input: $input) { - id - status - startedAt - } - } - `, - variables: { - input: { workflowId, parameters }, - }, - }); - } - - async getStats() { - return this.query({ - query: ` - query GetStats { - stats { - uptime - version - symbols { - total - byType { - type - count - } - } - workflows { - total - running - completed - failed - successRate - } - nodes { - total - online - utilizationRate - } - } - } - `, - }); - } - - subscribeToWorkflow(workflowId: string, onUpdate: (workflow: any) => void) { - return this.subscribe( - { - query: ` - subscription WorkflowUpdates($id: ID) { - workflowUpdated(id: $id) { - id - name - status - startedAt - completedAt - } - } - `, - variables: { id: workflowId }, - }, - { - onData: (data) => onUpdate(data.workflowUpdated), - onError: (error) => console.error('Subscription error:', error), - } - ); - } -} - -// Export a factory function -export function createClient(config: GraphQLClientConfig): WpPraxisGraphQLClient { - return new WpPraxisGraphQLClient(config); -} - -// Default export -export default WpPraxisGraphQLClient; diff --git a/praxis/SymbolicEngine/graphql/codegen.yml b/praxis/SymbolicEngine/graphql/codegen.yml index 581dda1..30fa161 100644 --- a/praxis/SymbolicEngine/graphql/codegen.yml +++ b/praxis/SymbolicEngine/graphql/codegen.yml @@ -2,8 +2,6 @@ schema: ./schema.graphql generates: ./src/generated/types.ts: plugins: - - typescript - - typescript-resolvers config: contextType: ../types#GraphQLContext scalars: diff --git a/praxis/SymbolicEngine/graphql/deno.json b/praxis/SymbolicEngine/graphql/deno.json deleted file mode 100644 index 275b0c3..0000000 --- a/praxis/SymbolicEngine/graphql/deno.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@wp-praxis/graphql-api", - "version": "0.1.0", - "tasks": { - "build": "deno run --node-modules-dir=auto -A npm:rescript", - "dev": "deno run --node-modules-dir=auto -A npm:rescript -w", - "clean": "deno run --node-modules-dir=auto -A npm:rescript clean" - }, - "imports": { - "rescript": "npm:rescript@^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.1", - "@rescript/runtime/": "npm:/@rescript/runtime@12.2.0/", - "jsonwebtoken": "npm:jsonwebtoken@^9.0.2" - } -} diff --git a/praxis/SymbolicEngine/graphql/deno.lock b/praxis/SymbolicEngine/graphql/deno.lock deleted file mode 100644 index afebf7c..0000000 --- a/praxis/SymbolicEngine/graphql/deno.lock +++ /dev/null @@ -1,4029 +0,0 @@ -{ - "version": "5", - "specifiers": { - "npm:@apollo/server@^4.10.0": "4.13.0_graphql@16.13.1", - "npm:@apollo/subgraph@^2.7.0": "2.13.1_graphql@16.13.1", - "npm:@graphql-codegen/cli@5": "5.0.7_graphql@16.13.1_typescript@5.9.3", - "npm:@graphql-codegen/typescript-resolvers@^4.0.4": "4.5.2_graphql@16.13.1", - "npm:@graphql-codegen/typescript@^4.0.4": "4.1.6_graphql@16.13.1", - "npm:@graphql-inspector/cli@^5.0.2": "5.0.11_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2", - "npm:@graphql-tools/load-files@7": "7.0.1_graphql@16.13.1", - "npm:@graphql-tools/schema@^10.0.3": "10.0.31_graphql@16.13.1", - "npm:@rescript/core@^1.6.1": "1.6.1_rescript@12.2.0", - "npm:@rescript/runtime@12.2.0": "12.2.0", - "npm:@types/bcrypt@^5.0.2": "5.0.2", - "npm:@types/better-sqlite3@^7.6.8": "7.6.13", - "npm:@types/cors@^2.8.17": "2.8.19", - "npm:@types/express@^4.17.21": "4.17.25", - "npm:@types/jsonwebtoken@^9.0.5": "9.0.10", - "npm:@types/pg@^8.10.9": "8.18.0", - "npm:@types/uuid@^9.0.7": "9.0.8", - "npm:@types/ws@^8.5.10": "8.18.1", - "npm:bcrypt@^5.1.1": "5.1.1", - "npm:better-sqlite3@^9.2.2": "9.6.0", - "npm:bun-types@latest": "1.3.10", - "npm:cors@^2.8.5": "2.8.6", - "npm:dataloader@^2.2.2": "2.2.3", - "npm:date-fns@^3.3.0": "3.6.0", - "npm:express@^4.18.2": "4.22.1", - "npm:graphql-scalars@^1.22.4": "1.25.0_graphql@16.13.1", - "npm:graphql-subscriptions@2": "2.0.0_graphql@16.13.1", - "npm:graphql-ws@^5.15.0": "5.16.2_graphql@16.13.1", - "npm:graphql@^16.8.1": "16.13.1", - "npm:ioredis@^5.3.2": "5.10.0", - "npm:jsonwebtoken@^9.0.2": "9.0.3", - "npm:pg@^8.11.3": "8.20.0", - "npm:rescript@*": "12.2.0", - "npm:rescript@12": "12.2.0", - "npm:typescript@^5.3.3": "5.9.3", - "npm:uuid@^9.0.1": "9.0.1", - "npm:winston@^3.11.0": "3.19.0", - "npm:ws@^8.16.0": "8.19.0" - }, - "npm": { - "@ampproject/remapping@2.3.0": { - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": [ - "@jridgewell/gen-mapping", - "@jridgewell/trace-mapping" - ] - }, - "@apollo/cache-control-types@1.0.3_graphql@16.13.1": { - "integrity": "sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==", - "dependencies": [ - "graphql" - ] - }, - "@apollo/federation-internals@2.13.1_graphql@16.13.1": { - "integrity": "sha512-3w+pEjew3xDHTjM4INvBiy0+F/Puje7NSnH0S9WkFiiSjYDu9wwHW6yw5Frx8jN1T17lGOgAGbx1S+YTosCs6Q==", - "dependencies": [ - "@types/uuid", - "chalk", - "graphql", - "js-levenshtein", - "uuid" - ] - }, - "@apollo/protobufjs@1.2.7": { - "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", - "dependencies": [ - "@protobufjs/aspromise", - "@protobufjs/base64", - "@protobufjs/codegen", - "@protobufjs/eventemitter", - "@protobufjs/fetch", - "@protobufjs/float", - "@protobufjs/inquire", - "@protobufjs/path", - "@protobufjs/pool", - "@protobufjs/utf8", - "@types/long", - "long" - ], - "scripts": true, - "bin": true - }, - "@apollo/server-gateway-interface@1.1.1_graphql@16.13.1": { - "integrity": "sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==", - "dependencies": [ - "@apollo/usage-reporting-protobuf", - "@apollo/utils.fetcher", - "@apollo/utils.keyvaluecache", - "@apollo/utils.logger", - "graphql" - ], - "deprecated": true - }, - "@apollo/server@4.13.0_graphql@16.13.1": { - "integrity": "sha512-t4GzaRiYIcPwYy40db6QjZzgvTr9ztDKBddykUXmBb2SVjswMKXbkaJ5nPeHqmT3awr9PAaZdCZdZhRj55I/8A==", - "dependencies": [ - "@apollo/cache-control-types", - "@apollo/server-gateway-interface", - "@apollo/usage-reporting-protobuf", - "@apollo/utils.createhash", - "@apollo/utils.fetcher", - "@apollo/utils.isnodelike", - "@apollo/utils.keyvaluecache", - "@apollo/utils.logger", - "@apollo/utils.usagereporting", - "@apollo/utils.withrequired", - "@graphql-tools/schema@9.0.19_graphql@16.13.1", - "@types/express", - "@types/express-serve-static-core", - "@types/node-fetch", - "async-retry", - "content-type", - "cors", - "express", - "graphql", - "loglevel", - "lru-cache@7.18.3", - "negotiator", - "node-abort-controller", - "node-fetch@2.7.0", - "uuid", - "whatwg-mimetype@3.0.0" - ], - "deprecated": true - }, - "@apollo/subgraph@2.13.1_graphql@16.13.1": { - "integrity": "sha512-SmFYNd/0uzVt9OyyofSMydgYpzDRPF2gyVY0a32xb2RTCtnNpGnCMaOd9kN9V5Tm31Zspcbqycj1l64zMu0egQ==", - "dependencies": [ - "@apollo/cache-control-types", - "@apollo/federation-internals", - "graphql" - ] - }, - "@apollo/usage-reporting-protobuf@4.1.1": { - "integrity": "sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==", - "dependencies": [ - "@apollo/protobufjs" - ] - }, - "@apollo/utils.createhash@2.0.2": { - "integrity": "sha512-UkS3xqnVFLZ3JFpEmU/2cM2iKJotQXMoSTgxXsfQgXLC5gR1WaepoXagmYnPSA7Q/2cmnyTYK5OgAgoC4RULPg==", - "dependencies": [ - "@apollo/utils.isnodelike", - "sha.js" - ] - }, - "@apollo/utils.dropunuseddefinitions@2.0.1_graphql@16.13.1": { - "integrity": "sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==", - "dependencies": [ - "graphql" - ] - }, - "@apollo/utils.fetcher@2.0.1": { - "integrity": "sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==" - }, - "@apollo/utils.isnodelike@2.0.1": { - "integrity": "sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==" - }, - "@apollo/utils.keyvaluecache@2.1.1": { - "integrity": "sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==", - "dependencies": [ - "@apollo/utils.logger", - "lru-cache@7.18.3" - ] - }, - "@apollo/utils.logger@2.0.1": { - "integrity": "sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==" - }, - "@apollo/utils.printwithreducedwhitespace@2.0.1_graphql@16.13.1": { - "integrity": "sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==", - "dependencies": [ - "graphql" - ] - }, - "@apollo/utils.removealiases@2.0.1_graphql@16.13.1": { - "integrity": "sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==", - "dependencies": [ - "graphql" - ] - }, - "@apollo/utils.sortast@2.0.1_graphql@16.13.1": { - "integrity": "sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==", - "dependencies": [ - "graphql", - "lodash.sortby" - ] - }, - "@apollo/utils.stripsensitiveliterals@2.0.1_graphql@16.13.1": { - "integrity": "sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==", - "dependencies": [ - "graphql" - ] - }, - "@apollo/utils.usagereporting@2.1.0_graphql@16.13.1": { - "integrity": "sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==", - "dependencies": [ - "@apollo/usage-reporting-protobuf", - "@apollo/utils.dropunuseddefinitions", - "@apollo/utils.printwithreducedwhitespace", - "@apollo/utils.removealiases", - "@apollo/utils.sortast", - "@apollo/utils.stripsensitiveliterals", - "graphql" - ] - }, - "@apollo/utils.withrequired@2.0.1": { - "integrity": "sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==" - }, - "@ardatan/relay-compiler@13.0.0_graphql@16.13.1": { - "integrity": "sha512-ite4+xng5McO8MflWCi0un0YmnorTujsDnfPfhzYzAgoJ+jkI1pZj6jtmTl8Jptyi1H+Pa0zlatJIsxDD++ETA==", - "dependencies": [ - "@babel/runtime", - "graphql", - "immutable", - "invariant" - ] - }, - "@ardatan/sync-fetch@0.0.1": { - "integrity": "sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA==", - "dependencies": [ - "node-fetch@2.7.0" - ] - }, - "@babel/code-frame@7.29.0": { - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dependencies": [ - "@babel/helper-validator-identifier", - "js-tokens", - "picocolors" - ] - }, - "@babel/compat-data@7.29.0": { - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==" - }, - "@babel/core@7.26.10": { - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", - "dependencies": [ - "@ampproject/remapping", - "@babel/code-frame", - "@babel/generator", - "@babel/helper-compilation-targets", - "@babel/helper-module-transforms", - "@babel/helpers", - "@babel/parser", - "@babel/template", - "@babel/traverse", - "@babel/types", - "convert-source-map", - "debug@4.4.3", - "gensync", - "json5", - "semver@6.3.1" - ] - }, - "@babel/generator@7.29.1": { - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "dependencies": [ - "@babel/parser", - "@babel/types", - "@jridgewell/gen-mapping", - "@jridgewell/trace-mapping", - "jsesc" - ] - }, - "@babel/helper-compilation-targets@7.28.6": { - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "dependencies": [ - "@babel/compat-data", - "@babel/helper-validator-option", - "browserslist", - "lru-cache@5.1.1", - "semver@6.3.1" - ] - }, - "@babel/helper-globals@7.28.0": { - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==" - }, - "@babel/helper-module-imports@7.28.6": { - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dependencies": [ - "@babel/traverse", - "@babel/types" - ] - }, - "@babel/helper-module-transforms@7.28.6_@babel+core@7.26.10": { - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "dependencies": [ - "@babel/core", - "@babel/helper-module-imports", - "@babel/helper-validator-identifier", - "@babel/traverse" - ] - }, - "@babel/helper-plugin-utils@7.28.6": { - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==" - }, - "@babel/helper-string-parser@7.27.1": { - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==" - }, - "@babel/helper-validator-identifier@7.28.5": { - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==" - }, - "@babel/helper-validator-option@7.27.1": { - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==" - }, - "@babel/helpers@7.28.6": { - "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", - "dependencies": [ - "@babel/template", - "@babel/types" - ] - }, - "@babel/parser@7.29.0": { - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", - "dependencies": [ - "@babel/types" - ], - "bin": true - }, - "@babel/plugin-syntax-import-assertions@7.28.6_@babel+core@7.26.10": { - "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", - "dependencies": [ - "@babel/core", - "@babel/helper-plugin-utils" - ] - }, - "@babel/runtime@7.28.6": { - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==" - }, - "@babel/template@7.28.6": { - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dependencies": [ - "@babel/code-frame", - "@babel/parser", - "@babel/types" - ] - }, - "@babel/traverse@7.29.0": { - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dependencies": [ - "@babel/code-frame", - "@babel/generator", - "@babel/helper-globals", - "@babel/parser", - "@babel/template", - "@babel/types", - "debug@4.4.3" - ] - }, - "@babel/types@7.29.0": { - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dependencies": [ - "@babel/helper-string-parser", - "@babel/helper-validator-identifier" - ] - }, - "@colors/colors@1.5.0": { - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" - }, - "@colors/colors@1.6.0": { - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" - }, - "@dabh/diagnostics@2.0.8": { - "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==", - "dependencies": [ - "@so-ric/colorspace", - "enabled", - "kuler" - ] - }, - "@envelop/core@5.5.1": { - "integrity": "sha512-3DQg8sFskDo386TkL5j12jyRAdip/8yzK3x7YGbZBgobZ4aKXrvDU0GppU0SnmrpQnNaiTUsxBs9LKkwQ/eyvw==", - "dependencies": [ - "@envelop/instrumentation", - "@envelop/types", - "@whatwg-node/promise-helpers", - "tslib@2.8.1" - ] - }, - "@envelop/instrumentation@1.0.0": { - "integrity": "sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw==", - "dependencies": [ - "@whatwg-node/promise-helpers", - "tslib@2.8.1" - ] - }, - "@envelop/types@5.2.1": { - "integrity": "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==", - "dependencies": [ - "@whatwg-node/promise-helpers", - "tslib@2.8.1" - ] - }, - "@fastify/busboy@3.2.0": { - "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==" - }, - "@graphql-codegen/add@5.0.3_graphql@16.13.1": { - "integrity": "sha512-SxXPmramkth8XtBlAHu4H4jYcYXM/o3p01+psU+0NADQowA8jtYkK6MW5rV6T+CxkEaNZItfSmZRPgIuypcqnA==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/cli@5.0.7_graphql@16.13.1_typescript@5.9.3": { - "integrity": "sha512-h/sxYvSaWtxZxo8GtaA8SvcHTyViaaPd7dweF/hmRDpaQU1o3iU3EZxlcJ+oLTunU0tSMFsnrIXm/mhXxI11Cw==", - "dependencies": [ - "@babel/generator", - "@babel/template", - "@babel/types", - "@graphql-codegen/client-preset", - "@graphql-codegen/core", - "@graphql-codegen/plugin-helpers", - "@graphql-tools/apollo-engine-loader", - "@graphql-tools/code-file-loader", - "@graphql-tools/git-loader", - "@graphql-tools/github-loader", - "@graphql-tools/graphql-file-loader", - "@graphql-tools/json-file-loader", - "@graphql-tools/load@8.1.8_graphql@16.13.1", - "@graphql-tools/prisma-loader", - "@graphql-tools/url-loader@8.0.33_graphql@16.13.1_ws@8.19.0", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@whatwg-node/fetch@0.10.13", - "chalk", - "cosmiconfig", - "debounce", - "detect-indent", - "graphql", - "graphql-config", - "inquirer", - "is-glob", - "jiti@1.21.7", - "json-to-pretty-yaml", - "listr2", - "log-symbols", - "micromatch", - "shell-quote", - "string-env-interpolation", - "ts-log", - "tslib@2.8.1", - "yaml", - "yargs" - ], - "bin": true - }, - "@graphql-codegen/client-preset@4.8.3_graphql@16.13.1": { - "integrity": "sha512-QpEsPSO9fnRxA6Z66AmBuGcwHjZ6dYSxYo5ycMlYgSPzAbyG8gn/kWljofjJfWqSY+T/lRn+r8IXTH14ml24vQ==", - "dependencies": [ - "@babel/helper-plugin-utils", - "@babel/template", - "@graphql-codegen/add", - "@graphql-codegen/gql-tag-operations", - "@graphql-codegen/plugin-helpers", - "@graphql-codegen/typed-document-node", - "@graphql-codegen/typescript", - "@graphql-codegen/typescript-operations", - "@graphql-codegen/visitor-plugin-common", - "@graphql-tools/documents", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@graphql-typed-document-node/core", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/core@4.0.2_graphql@16.13.1": { - "integrity": "sha512-IZbpkhwVqgizcjNiaVzNAzm/xbWT6YnGgeOLwVjm4KbJn3V2jchVtuzHH09G5/WkkLSk2wgbXNdwjM41JxO6Eg==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-tools/schema@10.0.31_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/gql-tag-operations@4.0.17_graphql@16.13.1": { - "integrity": "sha512-2pnvPdIG6W9OuxkrEZ6hvZd142+O3B13lvhrZ48yyEBh2ujtmKokw0eTwDHtlXUqjVS0I3q7+HB2y12G/m69CA==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-codegen/visitor-plugin-common", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "auto-bind", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/plugin-helpers@5.1.1_graphql@16.13.1": { - "integrity": "sha512-28GHODK2HY1NhdyRcPP3sCz0Kqxyfiz7boIZ8qIxFYmpLYnlDgiYok5fhFLVSZihyOpCs4Fa37gVHf/Q4I2FEg==", - "dependencies": [ - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "change-case-all", - "common-tags", - "graphql", - "import-from", - "lodash", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/schema-ast@4.1.0_graphql@16.13.1": { - "integrity": "sha512-kZVn0z+th9SvqxfKYgztA6PM7mhnSZaj4fiuBWvMTqA+QqQ9BBed6Pz41KuD/jr0gJtnlr2A4++/0VlpVbCTmQ==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/typed-document-node@5.1.2_graphql@16.13.1": { - "integrity": "sha512-jaxfViDqFRbNQmfKwUY8hDyjnLTw2Z7DhGutxoOiiAI0gE/LfPe0LYaVFKVmVOOD7M3bWxoWfu4slrkbWbUbEw==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-codegen/visitor-plugin-common", - "auto-bind", - "change-case-all", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/typescript-operations@4.6.1_graphql@16.13.1": { - "integrity": "sha512-k92laxhih7s0WZ8j5WMIbgKwhe64C0As6x+PdcvgZFMudDJ7rPJ/hFqJ9DCRxNjXoHmSjnr6VUuQZq4lT1RzCA==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-codegen/typescript", - "@graphql-codegen/visitor-plugin-common", - "auto-bind", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/typescript-resolvers@4.5.2_graphql@16.13.1": { - "integrity": "sha512-u7Zz30UmtJCOmfAIcCYefS/3lE8LK7bF0COPz4VOva5v/EuxmLNCFreCuj4dztEZzBmuwJOJRm278MAxiz0fzg==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-codegen/typescript", - "@graphql-codegen/visitor-plugin-common", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "auto-bind", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/typescript@4.1.6_graphql@16.13.1": { - "integrity": "sha512-vpw3sfwf9A7S+kIUjyFxuvrywGxd4lmwmyYnnDVjVE4kSQ6Td3DpqaPTy8aNQ6O96vFoi/bxbZS2BW49PwSUUA==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-codegen/schema-ast", - "@graphql-codegen/visitor-plugin-common", - "auto-bind", - "graphql", - "tslib@2.6.3" - ] - }, - "@graphql-codegen/visitor-plugin-common@5.8.0_graphql@16.13.1": { - "integrity": "sha512-lC1E1Kmuzi3WZUlYlqB4fP6+CvbKH9J+haU1iWmgsBx5/sO2ROeXJG4Dmt8gP03bI2BwjiwV5WxCEMlyeuzLnA==", - "dependencies": [ - "@graphql-codegen/plugin-helpers", - "@graphql-tools/optimize", - "@graphql-tools/relay-operation-optimizer", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "auto-bind", - "change-case-all", - "dependency-graph@0.11.0", - "graphql", - "graphql-tag", - "parse-filepath", - "tslib@2.6.3" - ] - }, - "@graphql-hive/signal@1.0.0": { - "integrity": "sha512-RiwLMc89lTjvyLEivZ/qxAC5nBHoS2CtsWFSOsN35sxG9zoo5Z+JsFHM8MlvmO9yt+MJNIyC5MLE1rsbOphlag==" - }, - "@graphql-inspector/audit-command@5.0.11_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-rnGmUa29y82rLwqlM0GYZyINC+DDoDIqIE9xq5Puo7r7FiRPW3cVw+nfthshhS1Y3H7hTYavCbkFmnHa99Uk3Q==", - "dependencies": [ - "@graphql-inspector/commands", - "@graphql-inspector/core", - "@graphql-inspector/logger", - "@graphql-tools/utils@10.8.6_graphql@16.13.1", - "cli-table3", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/cli@5.0.11_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-I/onYHaCzCgUzIikGq/Ms4W60NKj2k7acd10oJYyM/1Xfh7mp/vuX8BoAQlu/6AgOwNHmDD4TfvyYO9w4ZfDYw==", - "dependencies": [ - "@babel/core", - "@graphql-inspector/audit-command", - "@graphql-inspector/code-loader", - "@graphql-inspector/commands", - "@graphql-inspector/config", - "@graphql-inspector/coverage-command", - "@graphql-inspector/diff-command", - "@graphql-inspector/docs-command", - "@graphql-inspector/git-loader", - "@graphql-inspector/github-loader", - "@graphql-inspector/graphql-loader", - "@graphql-inspector/introspect-command", - "@graphql-inspector/json-loader", - "@graphql-inspector/loaders", - "@graphql-inspector/serve-command", - "@graphql-inspector/similar-command", - "@graphql-inspector/url-loader", - "@graphql-inspector/validate-command", - "graphql", - "tslib@2.6.2", - "yargs" - ], - "bin": true - }, - "@graphql-inspector/code-loader@5.0.1_graphql@16.13.1": { - "integrity": "sha512-kdyP76g0QrtOFRda67+aNshSf0PXYyGJLiGxoVBogpAbkzDRhZQZAsdQVKP0tdEQAn4w0zN6VBdmpF/PAeBO5A==", - "dependencies": [ - "@graphql-tools/code-file-loader", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/commands@5.0.4_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-m6SzYxjkKhor7pV33r1FSL2Wq/epzeWDE1cfPT/eFJ4qKavTBcglr+Vpien6PK1a2vy69GhviFhMoJEakrlZMA==", - "dependencies": [ - "@graphql-inspector/config", - "@graphql-inspector/loaders", - "graphql", - "tslib@2.6.2", - "yargs" - ] - }, - "@graphql-inspector/config@4.0.2_graphql@16.13.1": { - "integrity": "sha512-fnIwVpGM5AtTr4XyV8NJkDnwpXxZSBzi3BopjuXwBPXXD1F3tcVkCKNT6/5WgUQGfNPskBVbitcOPtM4hIYAOQ==", - "dependencies": [ - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/core@6.4.1_graphql@16.13.1": { - "integrity": "sha512-nkwT3bNsYVotQ/xHe7o+No89HB2RSsy/AVyZCoDElkKbPr6a4MtwYxPyXrBsS8u5nu6Czr0fAE5lF5tS5yPmeg==", - "dependencies": [ - "dependency-graph@1.0.0", - "graphql", - "object-inspect@1.13.2", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/coverage-command@6.1.5_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-5zuPPFOgYcaTKw46aPsFltNq1bAwBJhg5rhNqousCb1Q7Bfke7f+Nf8dFFUqV0RgCDiGmWksPSVo7DbN9hkOXg==", - "dependencies": [ - "@graphql-inspector/commands", - "@graphql-inspector/core", - "@graphql-inspector/logger", - "@graphql-tools/utils@10.8.6_graphql@16.13.1", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/diff-command@5.0.11_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-fa3hgvo1lliexDU/3hJbnuiIXToQG0Sem2hwHudC7PiaLfP63hwZISCz5KT4mFyxL1H7eyFwX6MFP6nF9lTAuQ==", - "dependencies": [ - "@graphql-inspector/commands", - "@graphql-inspector/core", - "@graphql-inspector/logger", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/docs-command@5.0.4_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-NTQRWYzGNJy4Bnd+0NHNjOdgaETEUG112W+Nei/tPCRTs0Vi/UiW+UkGsQ3KxJozEkwgN8od39bVWohGTOPcpA==", - "dependencies": [ - "@graphql-inspector/commands", - "graphql", - "open", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/git-loader@5.0.1_graphql@16.13.1": { - "integrity": "sha512-eZFNU/y1z4sZ9Axu8mB/J7mW+e78JnWgXG2vcT1TT2E1uzFm0x2oNONM2lgLCZGEJuwQDEnreok5CoHumIdE4Q==", - "dependencies": [ - "@graphql-tools/git-loader", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/github-loader@5.0.1_graphql@16.13.1": { - "integrity": "sha512-CDsY4V1pEDzr5z5FlYTxcPa/7pKsuT/6xQmo1JghHQuYQPZ5TjtGsyNZwgQOjISMCw7pknXfifPBrFQKt6IOEA==", - "dependencies": [ - "@graphql-tools/github-loader", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/graphql-loader@5.0.1_graphql@16.13.1": { - "integrity": "sha512-VZIcbkMhgak3sW4GehVIX/Qnwu1TmQidvaWs8YUiT+czPxKK1rqY/c/G3arwQDtqAdPMx8IwY1bT83ykfIyxfg==", - "dependencies": [ - "@graphql-tools/graphql-file-loader", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/introspect-command@5.0.11_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-7pNm3xoXL1O5BiDQ6sMCMGTqENFPTANWNWdy6Cu6dMNPdUZ1W/p78UqSFS1GL5Yh7wooPvuQRD67yTbi0Pcq6w==", - "dependencies": [ - "@graphql-inspector/commands", - "@graphql-inspector/core", - "@graphql-inspector/logger", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/json-loader@5.0.1_graphql@16.13.1": { - "integrity": "sha512-ql5zI2E/RNgLKDJ2HilTds2lUTv8ZXQfY5HG29iia85q/CIFslVTDbhzhbXRqmz4jsLd3KCi1LxpAeYQQMhCSQ==", - "dependencies": [ - "@graphql-tools/json-file-loader", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/loaders@4.0.5_@graphql-inspector+config@4.0.2__graphql@16.13.1_graphql@16.13.1": { - "integrity": "sha512-MQj82Pbo4YVgS1E3IjVvP3ByLQKQ6HHrjK+S21szXx46cKPxlc+MeKHpjfERSCmbdKAinP0MMHxVrmk7hyktow==", - "dependencies": [ - "@graphql-inspector/config", - "@graphql-tools/code-file-loader", - "@graphql-tools/load@8.0.2_graphql@16.13.1", - "@graphql-tools/utils@10.2.1_graphql@16.13.1", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/logger@5.0.1": { - "integrity": "sha512-rEo+HoQt+qjdayy7p5vcR9GeGTdKXmN0LbIm3W+jKKoXeAMlV4zHxnOW6jEhO6E0eVQxf8Sc1TlcH78i2P2a9w==", - "dependencies": [ - "chalk", - "figures", - "log-symbols", - "std-env", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/serve-command@5.0.6_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-eP1NgLvNv/K90iilBM/hr6KFUAmL686ns7drTP2icEtxajkHEP1T3DVCrV+QmiN27H4Qa1YAvNwooOnJfo9gkg==", - "dependencies": [ - "@graphql-inspector/commands", - "@graphql-inspector/logger", - "graphql", - "graphql-yoga", - "open", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/similar-command@5.0.11_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-YulyRubNYQ9Z7xc9/I+NNmWVFcUftgK40rdqNBIm8A4ug7LErxh26lw/pBY4SEj1VSX/EXqLAcH1fIXaCZva5Q==", - "dependencies": [ - "@graphql-inspector/commands", - "@graphql-inspector/core", - "@graphql-inspector/logger", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/url-loader@5.0.1_graphql@16.13.1": { - "integrity": "sha512-7OPJfTJgqptJyfsrpntsn3GEMpSZWxkJO+KaMIZfqDsiWN/zyvNqB0Amogi3d7xxtU1fnB3NCN5VWCFuiRSPXg==", - "dependencies": [ - "@graphql-tools/url-loader@8.0.2_graphql@16.13.1_ws@8.19.0", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-inspector/validate-command@5.0.11_graphql@16.13.1_@graphql-inspector+config@4.0.2__graphql@16.13.1_@graphql-inspector+loaders@4.0.5__@graphql-inspector+config@4.0.2___graphql@16.13.1__graphql@16.13.1_yargs@17.7.2": { - "integrity": "sha512-9C2UEZ9QXfTjPzu4nhaRWoyfUSNaevxhpG2MiegEE+K8PcNr8McJJsj61dvXlPxhZZAcO9R8br5p/D43gUb3rg==", - "dependencies": [ - "@graphql-inspector/commands", - "@graphql-inspector/core", - "@graphql-inspector/logger", - "@graphql-tools/utils@10.8.6_graphql@16.13.1", - "graphql", - "tslib@2.6.2" - ] - }, - "@graphql-tools/apollo-engine-loader@8.0.28_graphql@16.13.1": { - "integrity": "sha512-MzgDrUuoxp6dZeo54zLBL3cEJKJtM3N/2RqK0rbPxPq5X2z6TUA7EGg8vIFTUkt5xelAsUrm8/4ai41ZDdxOng==", - "dependencies": [ - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "@whatwg-node/fetch@0.10.13", - "graphql", - "sync-fetch@0.6.0", - "tslib@2.8.1" - ] - }, - "@graphql-tools/batch-execute@9.0.19_graphql@16.13.1": { - "integrity": "sha512-VGamgY4PLzSx48IHPoblRw0oTaBa7S26RpZXt0Y4NN90ytoE0LutlpB2484RbkfcTjv9wa64QD474+YP1kEgGA==", - "dependencies": [ - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@whatwg-node/promise-helpers", - "dataloader", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/code-file-loader@8.1.2_graphql@16.13.1": { - "integrity": "sha512-GrLzwl1QV2PT4X4TEEfuTmZYzIZHLqoTGBjczdUzSqgCCcqwWzLB3qrJxFQfI8e5s1qZ1bhpsO9NoMn7tvpmyA==", - "dependencies": [ - "@graphql-tools/graphql-tag-pluck@8.3.1_graphql@16.13.1_@babel+core@7.26.10", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "globby", - "graphql", - "tslib@2.8.1", - "unixify" - ] - }, - "@graphql-tools/delegate@10.2.23_graphql@16.13.1": { - "integrity": "sha512-xrPtl7f1LxS+B6o+W7ueuQh67CwRkfl+UKJncaslnqYdkxKmNBB4wnzVcW8ZsRdwbsla/v43PtwAvSlzxCzq2w==", - "dependencies": [ - "@graphql-tools/batch-execute", - "@graphql-tools/executor", - "@graphql-tools/schema@10.0.31_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@repeaterjs/repeater", - "@whatwg-node/promise-helpers", - "dataloader", - "dset", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/documents@1.0.1_graphql@16.13.1": { - "integrity": "sha512-aweoMH15wNJ8g7b2r4C4WRuJxZ0ca8HtNO54rkye/3duxTkW4fGBEutCx03jCIr5+a1l+4vFJNP859QnAVBVCA==", - "dependencies": [ - "graphql", - "lodash.sortby", - "tslib@2.8.1" - ] - }, - "@graphql-tools/executor-common@0.0.1_graphql@16.13.1": { - "integrity": "sha512-Gan7uiQhKvAAl0UM20Oy/n5NGBBDNm+ASHvnYuD8mP+dAH0qY+2QMCHyi5py28WAlhAwr0+CAemEyzY/ZzOjdQ==", - "dependencies": [ - "@envelop/core", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql" - ] - }, - "@graphql-tools/executor-common@0.0.4_graphql@16.13.1": { - "integrity": "sha512-SEH/OWR+sHbknqZyROCFHcRrbZeUAyjCsgpVWCRjqjqRbiJiXq6TxNIIOmpXgkrXWW/2Ev4Wms6YSGJXjdCs6Q==", - "dependencies": [ - "@envelop/core", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql" - ] - }, - "@graphql-tools/executor-common@0.0.6_graphql@16.13.1": { - "integrity": "sha512-JAH/R1zf77CSkpYATIJw+eOJwsbWocdDjY+avY7G+P5HCXxwQjAjWVkJI1QJBQYjPQDVxwf1fmTZlIN3VOadow==", - "dependencies": [ - "@envelop/core", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql" - ] - }, - "@graphql-tools/executor-graphql-ws@1.3.7_graphql@16.13.1_ws@8.19.0": { - "integrity": "sha512-9KUrlpil5nBgcb+XRUIxNQGI+c237LAfDBqYCdLGuYT+/oZz1b4rRIe6HuRk09vuxrbaMTzm7xHhn/iuwWW4eg==", - "dependencies": [ - "@graphql-tools/executor-common@0.0.1_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@whatwg-node/disposablestack@0.0.5", - "graphql", - "graphql-ws@5.16.2_graphql@16.13.1", - "isomorphic-ws", - "tslib@2.8.1", - "ws" - ] - }, - "@graphql-tools/executor-graphql-ws@2.0.7_graphql@16.13.1_ws@8.19.0": { - "integrity": "sha512-J27za7sKF6RjhmvSOwOQFeNhNHyP4f4niqPnerJmq73OtLx9Y2PGOhkXOEB0PjhvPJceuttkD2O1yMgEkTGs3Q==", - "dependencies": [ - "@graphql-tools/executor-common@0.0.6_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@whatwg-node/disposablestack@0.0.6", - "graphql", - "graphql-ws@6.0.7_graphql@16.13.1_ws@8.19.0", - "isomorphic-ws", - "tslib@2.8.1", - "ws" - ] - }, - "@graphql-tools/executor-http@1.3.3_graphql@16.13.1": { - "integrity": "sha512-LIy+l08/Ivl8f8sMiHW2ebyck59JzyzO/yF9SFS4NH6MJZUezA1xThUXCDIKhHiD56h/gPojbkpcFvM2CbNE7A==", - "dependencies": [ - "@graphql-hive/signal", - "@graphql-tools/executor-common@0.0.4_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@repeaterjs/repeater", - "@whatwg-node/disposablestack@0.0.6", - "@whatwg-node/fetch@0.10.13", - "@whatwg-node/promise-helpers", - "graphql", - "meros", - "tslib@2.8.1" - ] - }, - "@graphql-tools/executor-legacy-ws@1.1.25_graphql@16.13.1_ws@8.19.0": { - "integrity": "sha512-6uf4AEXO0QMxJ7AWKVPqEZXgYBJaiz5vf29X0boG8QtcqWy8mqkXKWLND2Swdx0SbEx0efoGFcjuKufUcB0ASQ==", - "dependencies": [ - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "@types/ws", - "graphql", - "isomorphic-ws", - "tslib@2.8.1", - "ws" - ] - }, - "@graphql-tools/executor@1.5.1_graphql@16.13.1": { - "integrity": "sha512-n94Qcu875Mji9GQ52n5UbgOTxlgvFJicBPYD+FRks9HKIQpdNPjkkrKZUYNG51XKa+bf03rxNflm4+wXhoHHrA==", - "dependencies": [ - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "@graphql-typed-document-node/core", - "@repeaterjs/repeater", - "@whatwg-node/disposablestack@0.0.6", - "@whatwg-node/promise-helpers", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/git-loader@8.0.6_graphql@16.13.1": { - "integrity": "sha512-FQFO4H5wHAmHVyuUQrjvPE8re3qJXt50TWHuzrK3dEaief7JosmlnkLMDMbMBwtwITz9u1Wpl6doPhT2GwKtlw==", - "dependencies": [ - "@graphql-tools/graphql-tag-pluck@8.3.1_graphql@16.13.1_@babel+core@7.26.10", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql", - "is-glob", - "micromatch", - "tslib@2.8.1", - "unixify" - ] - }, - "@graphql-tools/github-loader@8.0.1_graphql@16.13.1": { - "integrity": "sha512-W4dFLQJ5GtKGltvh/u1apWRFKBQOsDzFxO9cJkOYZj1VzHCpRF43uLST4VbCfWve+AwBqOuKr7YgkHoxpRMkcg==", - "dependencies": [ - "@ardatan/sync-fetch", - "@graphql-tools/executor-http", - "@graphql-tools/graphql-tag-pluck@8.3.27_graphql@16.13.1_@babel+core@7.26.10", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@whatwg-node/fetch@0.9.23", - "graphql", - "tslib@2.8.1", - "value-or-promise" - ] - }, - "@graphql-tools/graphql-file-loader@8.0.1_graphql@16.13.1": { - "integrity": "sha512-7gswMqWBabTSmqbaNyWSmRRpStWlcCkBc73E6NZNlh4YNuiyKOwbvSkOUYFOqFMfEL+cFsXgAvr87Vz4XrYSbA==", - "dependencies": [ - "@graphql-tools/import", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "globby", - "graphql", - "tslib@2.8.1", - "unixify" - ] - }, - "@graphql-tools/graphql-tag-pluck@8.3.1_graphql@16.13.1_@babel+core@7.26.10": { - "integrity": "sha512-ujits9tMqtWQQq4FI4+qnVPpJvSEn7ogKtyN/gfNT+ErIn6z1e4gyVGQpTK5sgAUXq1lW4gU/5fkFFC5/sL2rQ==", - "dependencies": [ - "@babel/core", - "@babel/parser", - "@babel/plugin-syntax-import-assertions", - "@babel/traverse", - "@babel/types", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/graphql-tag-pluck@8.3.27_graphql@16.13.1_@babel+core@7.26.10": { - "integrity": "sha512-CJ0WVXhGYsfFngpRrAAcjRHyxSDHx4dEz2W15bkwvt9he/AWhuyXm07wuGcoLrl0q0iQp1BiRjU7D8SxWZo3JQ==", - "dependencies": [ - "@babel/core", - "@babel/parser", - "@babel/plugin-syntax-import-assertions", - "@babel/traverse", - "@babel/types", - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/import@7.0.1_graphql@16.13.1": { - "integrity": "sha512-935uAjAS8UAeXThqHfYVr4HEAp6nHJ2sximZKO1RzUTq5WoALMAhhGARl0+ecm6X+cqNUwIChJbjtaa6P/ML0w==", - "dependencies": [ - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql", - "resolve-from@5.0.0", - "tslib@2.8.1" - ] - }, - "@graphql-tools/json-file-loader@8.0.1_graphql@16.13.1": { - "integrity": "sha512-lAy2VqxDAHjVyqeJonCP6TUemrpYdDuKt25a10X6zY2Yn3iFYGnuIDQ64cv3ytyGY6KPyPB+Kp+ZfOkNDG3FQA==", - "dependencies": [ - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "globby", - "graphql", - "tslib@2.8.1", - "unixify" - ] - }, - "@graphql-tools/load-files@7.0.1_graphql@16.13.1": { - "integrity": "sha512-oTNIENc9To9u8Gc3kY82C74caW6kXa8ya2GyxWRXp8gP4zK/7PmvlWJK0/GFCUH0cU3t9jM7k59zXz1+ZfP3Mw==", - "dependencies": [ - "globby", - "graphql", - "tslib@2.8.1", - "unixify" - ] - }, - "@graphql-tools/load@8.0.2_graphql@16.13.1": { - "integrity": "sha512-S+E/cmyVmJ3CuCNfDuNF2EyovTwdWfQScXv/2gmvJOti2rGD8jTt9GYVzXaxhblLivQR9sBUCNZu/w7j7aXUCA==", - "dependencies": [ - "@graphql-tools/schema@10.0.31_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "graphql", - "p-limit", - "tslib@2.8.1" - ] - }, - "@graphql-tools/load@8.1.8_graphql@16.13.1": { - "integrity": "sha512-gxO662b64qZSToK3N6XUxWG5E6HOUjlg5jEnmGvD4bMtGJ0HwEe/BaVZbBQemCfLkxYjwRIBiVfOY9o0JyjZJg==", - "dependencies": [ - "@graphql-tools/schema@10.0.31_graphql@16.13.1", - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "graphql", - "p-limit", - "tslib@2.8.1" - ] - }, - "@graphql-tools/merge@8.4.2_graphql@16.13.1": { - "integrity": "sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==", - "dependencies": [ - "@graphql-tools/utils@9.2.1_graphql@16.13.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/merge@9.1.7_graphql@16.13.1": { - "integrity": "sha512-Y5E1vTbTabvcXbkakdFUt4zUIzB1fyaEnVmIWN0l0GMed2gdD01TpZWLUm4RNAxpturvolrb24oGLQrBbPLSoQ==", - "dependencies": [ - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/optimize@2.0.0_graphql@16.13.1": { - "integrity": "sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg==", - "dependencies": [ - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/prisma-loader@8.0.17_graphql@16.13.1": { - "integrity": "sha512-fnuTLeQhqRbA156pAyzJYN0KxCjKYRU5bz1q/SKOwElSnAU4k7/G1kyVsWLh7fneY78LoMNH5n+KlFV8iQlnyg==", - "dependencies": [ - "@graphql-tools/url-loader@8.0.33_graphql@16.13.1_ws@8.19.0", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@types/js-yaml", - "@whatwg-node/fetch@0.10.13", - "chalk", - "debug@4.4.3", - "dotenv", - "graphql", - "graphql-request", - "http-proxy-agent", - "https-proxy-agent@7.0.6", - "jose", - "js-yaml", - "lodash", - "scuid", - "tslib@2.8.1", - "yaml-ast-parser" - ], - "deprecated": true - }, - "@graphql-tools/relay-operation-optimizer@7.1.1_graphql@16.13.1": { - "integrity": "sha512-va+ZieMlz6Fj18xUbwyQkZ34PsnzIdPT6Ccy1BNOQw1iclQwk52HejLMZeE/4fH+4cu80Q2HXi5+FjCKpmnJCg==", - "dependencies": [ - "@ardatan/relay-compiler", - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/schema@10.0.31_graphql@16.13.1": { - "integrity": "sha512-ZewRgWhXef6weZ0WiP7/MV47HXiuFbFpiDUVLQl6mgXsWSsGELKFxQsyUCBos60Qqy1JEFAIu3Ns6GGYjGkqkQ==", - "dependencies": [ - "@graphql-tools/merge@9.1.7_graphql@16.13.1", - "@graphql-tools/utils@11.0.0_graphql@16.13.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/schema@9.0.19_graphql@16.13.1": { - "integrity": "sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==", - "dependencies": [ - "@graphql-tools/merge@8.4.2_graphql@16.13.1", - "@graphql-tools/utils@9.2.1_graphql@16.13.1", - "graphql", - "tslib@2.8.1", - "value-or-promise" - ] - }, - "@graphql-tools/url-loader@8.0.2_graphql@16.13.1_ws@8.19.0": { - "integrity": "sha512-1dKp2K8UuFn7DFo1qX5c1cyazQv2h2ICwA9esHblEqCYrgf69Nk8N7SODmsfWg94OEaI74IqMoM12t7eIGwFzQ==", - "dependencies": [ - "@ardatan/sync-fetch", - "@graphql-tools/delegate", - "@graphql-tools/executor-graphql-ws@1.3.7_graphql@16.13.1_ws@8.19.0", - "@graphql-tools/executor-http", - "@graphql-tools/executor-legacy-ws", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@graphql-tools/wrap", - "@types/ws", - "@whatwg-node/fetch@0.9.23", - "graphql", - "isomorphic-ws", - "tslib@2.8.1", - "value-or-promise", - "ws" - ] - }, - "@graphql-tools/url-loader@8.0.33_graphql@16.13.1_ws@8.19.0": { - "integrity": "sha512-Fu626qcNHcqAj8uYd7QRarcJn5XZ863kmxsg1sm0fyjyfBJnsvC7ddFt6Hayz5kxVKfsnjxiDfPMXanvsQVBKw==", - "dependencies": [ - "@graphql-tools/executor-graphql-ws@2.0.7_graphql@16.13.1_ws@8.19.0", - "@graphql-tools/executor-http", - "@graphql-tools/executor-legacy-ws", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@graphql-tools/wrap", - "@types/ws", - "@whatwg-node/fetch@0.10.13", - "@whatwg-node/promise-helpers", - "graphql", - "isomorphic-ws", - "sync-fetch@0.6.0-2", - "tslib@2.8.1", - "ws" - ] - }, - "@graphql-tools/utils@10.11.0_graphql@16.13.1": { - "integrity": "sha512-iBFR9GXIs0gCD+yc3hoNswViL1O5josI33dUqiNStFI/MHLCEPduasceAcazRH77YONKNiviHBV8f7OgcT4o2Q==", - "dependencies": [ - "@graphql-typed-document-node/core", - "@whatwg-node/promise-helpers", - "cross-inspect@1.0.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/utils@10.2.1_graphql@16.13.1": { - "integrity": "sha512-U8OMdkkEt3Vp3uYHU2pMc6mwId7axVAcSSmcqJcUmWNPqY2pfee5O655ybTI2kNPWAe58Zu6gLu4Oi4QT4BgWA==", - "dependencies": [ - "@graphql-typed-document-node/core", - "cross-inspect@1.0.0", - "dset", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/utils@10.8.6_graphql@16.13.1": { - "integrity": "sha512-Alc9Vyg0oOsGhRapfL3xvqh1zV8nKoFUdtLhXX7Ki4nClaIJXckrA86j+uxEuG3ic6j4jlM1nvcWXRn/71AVLQ==", - "dependencies": [ - "@graphql-typed-document-node/core", - "@whatwg-node/promise-helpers", - "cross-inspect@1.0.1", - "dset", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/utils@11.0.0_graphql@16.13.1": { - "integrity": "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA==", - "dependencies": [ - "@graphql-typed-document-node/core", - "@whatwg-node/promise-helpers", - "cross-inspect@1.0.1", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/utils@9.2.1_graphql@16.13.1": { - "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==", - "dependencies": [ - "@graphql-typed-document-node/core", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-tools/wrap@10.1.4_graphql@16.13.1": { - "integrity": "sha512-7pyNKqXProRjlSdqOtrbnFRMQAVamCmEREilOXtZujxY6kYit3tvWWSjUrcIOheltTffoRh7EQSjpy2JDCzasg==", - "dependencies": [ - "@graphql-tools/delegate", - "@graphql-tools/schema@10.0.31_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@whatwg-node/promise-helpers", - "graphql", - "tslib@2.8.1" - ] - }, - "@graphql-typed-document-node/core@3.2.0_graphql@16.13.1": { - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "dependencies": [ - "graphql" - ] - }, - "@graphql-yoga/logger@2.0.1": { - "integrity": "sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "@graphql-yoga/subscription@5.0.5": { - "integrity": "sha512-oCMWOqFs6QV96/NZRt/ZhTQvzjkGB4YohBOpKM4jH/lDT4qb7Lex/aGCxpi/JD9njw3zBBtMqxbaC22+tFHVvw==", - "dependencies": [ - "@graphql-yoga/typed-event-target", - "@repeaterjs/repeater", - "@whatwg-node/events", - "tslib@2.8.1" - ] - }, - "@graphql-yoga/typed-event-target@3.0.2": { - "integrity": "sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA==", - "dependencies": [ - "@repeaterjs/repeater", - "tslib@2.8.1" - ] - }, - "@inquirer/external-editor@1.0.3": { - "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", - "dependencies": [ - "chardet", - "iconv-lite@0.7.2" - ] - }, - "@ioredis/commands@1.5.1": { - "integrity": "sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==" - }, - "@jridgewell/gen-mapping@0.3.13": { - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dependencies": [ - "@jridgewell/sourcemap-codec", - "@jridgewell/trace-mapping" - ] - }, - "@jridgewell/resolve-uri@3.1.2": { - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" - }, - "@jridgewell/sourcemap-codec@1.5.5": { - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" - }, - "@jridgewell/trace-mapping@0.3.31": { - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dependencies": [ - "@jridgewell/resolve-uri", - "@jridgewell/sourcemap-codec" - ] - }, - "@kamilkisiela/fast-url-parser@1.1.4": { - "integrity": "sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==" - }, - "@mapbox/node-pre-gyp@1.0.11": { - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dependencies": [ - "detect-libc", - "https-proxy-agent@5.0.1", - "make-dir", - "node-fetch@2.7.0", - "nopt", - "npmlog", - "rimraf", - "semver@7.7.4", - "tar" - ], - "bin": true - }, - "@nodelib/fs.scandir@2.1.5": { - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": [ - "@nodelib/fs.stat", - "run-parallel" - ] - }, - "@nodelib/fs.stat@2.0.5": { - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk@1.2.8": { - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": [ - "@nodelib/fs.scandir", - "fastq" - ] - }, - "@protobufjs/aspromise@1.1.2": { - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "@protobufjs/base64@1.1.2": { - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen@2.0.4": { - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter@1.1.0": { - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "@protobufjs/fetch@1.1.0": { - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": [ - "@protobufjs/aspromise", - "@protobufjs/inquire" - ] - }, - "@protobufjs/float@1.0.2": { - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "@protobufjs/inquire@1.1.0": { - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "@protobufjs/path@1.1.2": { - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "@protobufjs/pool@1.1.0": { - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "@protobufjs/utf8@1.1.0": { - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "@repeaterjs/repeater@3.0.6": { - "integrity": "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==" - }, - "@rescript/core@1.6.1_rescript@12.2.0": { - "integrity": "sha512-vyb5k90ck+65Fgui+5vCja/mUfzKaK3kOPT4Z6aAJdHLH1eljEi1zKhXroCiCtpNLSWp8k4ulh1bdB5WS0hvqA==", - "dependencies": [ - "rescript" - ] - }, - "@rescript/darwin-arm64@12.2.0": { - "integrity": "sha512-xc3K/J7Ujl1vPiFY2009mRf3kWRlUe/VZyJWprseKxlcEtUQv89ter7r6pY+YFbtYvA/fcaEncL9CVGEdattAg==", - "os": ["darwin"], - "cpu": ["arm64"] - }, - "@rescript/darwin-x64@12.2.0": { - "integrity": "sha512-qqcTvnlSeoKkywLjG7cXfYvKZ1e4Gz2kUKcD6SiqDgCqm8TF+spwlFAiM6sloRUOFsc0bpC/0R0B3yr01FCB1A==", - "os": ["darwin"], - "cpu": ["x64"] - }, - "@rescript/linux-arm64@12.2.0": { - "integrity": "sha512-ODmpG3ji+Nj/8d5yvXkeHlfKkmbw1Q4t1iIjVuNwtmFpz7TiEa7n/sQqoYdE+WzbDX3DoJfmJNbp3Ob7qCUoOg==", - "os": ["linux"], - "cpu": ["arm64"] - }, - "@rescript/linux-x64@12.2.0": { - "integrity": "sha512-2W9Y9/g19Y4F/subl8yV3T8QBG2oRaP+HciNRcBjptyEdw9LmCKH8+rhWO6sp3E+nZLwoE2IAkwH0WKV3wqlxQ==", - "os": ["linux"], - "cpu": ["x64"] - }, - "@rescript/runtime@12.2.0": { - "integrity": "sha512-NwfljDRq1rjFPHUaca1nzFz13xsa9ZGkBkLvMhvVgavJT5+A4rMcLu8XAaVTi/oAhO/tlHf9ZDoOTF1AfyAk9Q==" - }, - "@rescript/win32-x64@12.2.0": { - "integrity": "sha512-fhf8CBj3p1lkIXPeNko3mVTKQfXXm4BoxJtR1xAXxUn43wDpd8Lox4w8/EPBbbW6C/YFQW6H7rtpY+2AKuNaDA==", - "os": ["win32"], - "cpu": ["x64"] - }, - "@so-ric/colorspace@1.1.6": { - "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==", - "dependencies": [ - "color", - "text-hex" - ] - }, - "@types/bcrypt@5.0.2": { - "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", - "dependencies": [ - "@types/node" - ] - }, - "@types/better-sqlite3@7.6.13": { - "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", - "dependencies": [ - "@types/node" - ] - }, - "@types/body-parser@1.19.6": { - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dependencies": [ - "@types/connect", - "@types/node" - ] - }, - "@types/connect@3.4.38": { - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": [ - "@types/node" - ] - }, - "@types/cors@2.8.19": { - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", - "dependencies": [ - "@types/node" - ] - }, - "@types/express-serve-static-core@4.19.8": { - "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", - "dependencies": [ - "@types/node", - "@types/qs", - "@types/range-parser", - "@types/send" - ] - }, - "@types/express@4.17.25": { - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", - "dependencies": [ - "@types/body-parser", - "@types/express-serve-static-core", - "@types/qs", - "@types/serve-static" - ] - }, - "@types/http-errors@2.0.5": { - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==" - }, - "@types/js-yaml@4.0.9": { - "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==" - }, - "@types/jsonwebtoken@9.0.10": { - "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", - "dependencies": [ - "@types/ms", - "@types/node" - ] - }, - "@types/long@4.0.2": { - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "@types/mime@1.3.5": { - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "@types/ms@2.1.0": { - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" - }, - "@types/node-fetch@2.6.13": { - "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", - "dependencies": [ - "@types/node", - "form-data" - ] - }, - "@types/node@25.3.3": { - "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", - "dependencies": [ - "undici-types" - ] - }, - "@types/pg@8.18.0": { - "integrity": "sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==", - "dependencies": [ - "@types/node", - "pg-protocol", - "pg-types" - ] - }, - "@types/qs@6.14.0": { - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==" - }, - "@types/range-parser@1.2.7": { - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "@types/send@0.17.6": { - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", - "dependencies": [ - "@types/mime", - "@types/node" - ] - }, - "@types/serve-static@1.15.10": { - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", - "dependencies": [ - "@types/http-errors", - "@types/node", - "@types/send" - ] - }, - "@types/triple-beam@1.3.5": { - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "@types/uuid@9.0.8": { - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==" - }, - "@types/ws@8.18.1": { - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dependencies": [ - "@types/node" - ] - }, - "@whatwg-node/disposablestack@0.0.5": { - "integrity": "sha512-9lXugdknoIequO4OYvIjhygvfSEgnO8oASLqLelnDhkRjgBZhc39shC3QSlZuyDO9bgYSIVa2cHAiN+St3ty4w==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "@whatwg-node/disposablestack@0.0.6": { - "integrity": "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==", - "dependencies": [ - "@whatwg-node/promise-helpers", - "tslib@2.8.1" - ] - }, - "@whatwg-node/events@0.1.2": { - "integrity": "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "@whatwg-node/fetch@0.10.13": { - "integrity": "sha512-b4PhJ+zYj4357zwk4TTuF2nEe0vVtOrwdsrNo5hL+u1ojXNhh1FgJ6pg1jzDlwlT4oBdzfSwaBwMCtFCsIWg8Q==", - "dependencies": [ - "@whatwg-node/node-fetch@0.8.5", - "urlpattern-polyfill" - ] - }, - "@whatwg-node/fetch@0.9.23": { - "integrity": "sha512-7xlqWel9JsmxahJnYVUj/LLxWcnA93DR4c9xlw3U814jWTiYalryiH1qToik1hOxweKKRLi4haXHM5ycRksPBA==", - "dependencies": [ - "@whatwg-node/node-fetch@0.6.0", - "urlpattern-polyfill" - ] - }, - "@whatwg-node/node-fetch@0.6.0": { - "integrity": "sha512-tcZAhrpx6oVlkEsRngeTEEE7I5/QdLjeEz4IlekabGaESP7+Dkm/6a9KcF1KdCBB7mO9PXtBkwCuTCt8+UPg8Q==", - "dependencies": [ - "@kamilkisiela/fast-url-parser", - "busboy", - "fast-querystring", - "tslib@2.8.1" - ] - }, - "@whatwg-node/node-fetch@0.8.5": { - "integrity": "sha512-4xzCl/zphPqlp9tASLVeUhB5+WJHbuWGYpfoC2q1qh5dw0AqZBW7L27V5roxYWijPxj4sspRAAoOH3d2ztaHUQ==", - "dependencies": [ - "@fastify/busboy", - "@whatwg-node/disposablestack@0.0.6", - "@whatwg-node/promise-helpers", - "tslib@2.8.1" - ] - }, - "@whatwg-node/promise-helpers@1.3.2": { - "integrity": "sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "@whatwg-node/server@0.9.71": { - "integrity": "sha512-ueFCcIPaMgtuYDS9u0qlUoEvj6GiSsKrwnOLPp9SshqjtcRaR1IEHRjoReq3sXNydsF5i0ZnmuYgXq9dV53t0g==", - "dependencies": [ - "@whatwg-node/disposablestack@0.0.6", - "@whatwg-node/fetch@0.10.13", - "@whatwg-node/promise-helpers", - "tslib@2.8.1" - ] - }, - "abbrev@1.1.1": { - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts@1.3.8": { - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": [ - "mime-types", - "negotiator" - ] - }, - "agent-base@6.0.2": { - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": [ - "debug@4.4.3" - ] - }, - "agent-base@7.1.4": { - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==" - }, - "aggregate-error@3.1.0": { - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": [ - "clean-stack", - "indent-string" - ] - }, - "ansi-escapes@4.3.2": { - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dependencies": [ - "type-fest" - ] - }, - "ansi-regex@5.0.1": { - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles@4.3.0": { - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": [ - "color-convert@2.0.1" - ] - }, - "aproba@2.1.0": { - "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==" - }, - "are-we-there-yet@2.0.0": { - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dependencies": [ - "delegates", - "readable-stream" - ], - "deprecated": true - }, - "argparse@2.0.1": { - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "array-flatten@1.1.1": { - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "array-union@2.1.0": { - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" - }, - "astral-regex@2.0.0": { - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - }, - "async-retry@1.3.3": { - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "dependencies": [ - "retry" - ] - }, - "async@3.2.6": { - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" - }, - "asynckit@0.4.0": { - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "auto-bind@4.0.0": { - "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==" - }, - "available-typed-arrays@1.0.7": { - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": [ - "possible-typed-array-names" - ] - }, - "balanced-match@1.0.2": { - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js@1.5.1": { - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "baseline-browser-mapping@2.10.0": { - "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", - "bin": true - }, - "bcrypt@5.1.1": { - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", - "dependencies": [ - "@mapbox/node-pre-gyp", - "node-addon-api" - ], - "scripts": true - }, - "better-sqlite3@9.6.0": { - "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==", - "dependencies": [ - "bindings", - "prebuild-install" - ], - "scripts": true - }, - "bindings@1.5.0": { - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": [ - "file-uri-to-path" - ] - }, - "bl@4.1.0": { - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": [ - "buffer", - "inherits", - "readable-stream" - ] - }, - "body-parser@1.20.4": { - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", - "dependencies": [ - "bytes", - "content-type", - "debug@2.6.9", - "depd", - "destroy", - "http-errors", - "iconv-lite@0.4.24", - "on-finished", - "qs", - "raw-body", - "type-is", - "unpipe" - ] - }, - "brace-expansion@1.1.12": { - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dependencies": [ - "balanced-match", - "concat-map" - ] - }, - "brace-expansion@2.0.2": { - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dependencies": [ - "balanced-match" - ] - }, - "braces@3.0.3": { - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": [ - "fill-range" - ] - }, - "browserslist@4.28.1": { - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dependencies": [ - "baseline-browser-mapping", - "caniuse-lite", - "electron-to-chromium", - "node-releases", - "update-browserslist-db" - ], - "bin": true - }, - "buffer-equal-constant-time@1.0.1": { - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "buffer@5.7.1": { - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dependencies": [ - "base64-js", - "ieee754" - ] - }, - "bun-types@1.3.10": { - "integrity": "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg==", - "dependencies": [ - "@types/node" - ] - }, - "busboy@1.6.0": { - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": [ - "streamsearch" - ] - }, - "bytes@3.1.2": { - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "call-bind-apply-helpers@1.0.2": { - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dependencies": [ - "es-errors", - "function-bind" - ] - }, - "call-bind@1.0.8": { - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "dependencies": [ - "call-bind-apply-helpers", - "es-define-property", - "get-intrinsic", - "set-function-length" - ] - }, - "call-bound@1.0.4": { - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dependencies": [ - "call-bind-apply-helpers", - "get-intrinsic" - ] - }, - "callsites@3.1.0": { - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camel-case@4.1.2": { - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": [ - "pascal-case", - "tslib@2.8.1" - ] - }, - "caniuse-lite@1.0.30001776": { - "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==" - }, - "capital-case@1.0.4": { - "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", - "dependencies": [ - "no-case", - "tslib@2.8.1", - "upper-case-first" - ] - }, - "chalk@4.1.2": { - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": [ - "ansi-styles", - "supports-color" - ] - }, - "change-case-all@1.0.15": { - "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==", - "dependencies": [ - "change-case", - "is-lower-case", - "is-upper-case", - "lower-case", - "lower-case-first", - "sponge-case", - "swap-case", - "title-case", - "upper-case", - "upper-case-first" - ] - }, - "change-case@4.1.2": { - "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", - "dependencies": [ - "camel-case", - "capital-case", - "constant-case", - "dot-case", - "header-case", - "no-case", - "param-case", - "pascal-case", - "path-case", - "sentence-case", - "snake-case", - "tslib@2.8.1" - ] - }, - "chardet@2.1.1": { - "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==" - }, - "chownr@1.1.4": { - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "chownr@2.0.0": { - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "clean-stack@2.2.0": { - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cli-cursor@3.1.0": { - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dependencies": [ - "restore-cursor" - ] - }, - "cli-spinners@2.9.2": { - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==" - }, - "cli-table3@0.6.3": { - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", - "dependencies": [ - "string-width" - ], - "optionalDependencies": [ - "@colors/colors@1.5.0" - ] - }, - "cli-truncate@2.1.0": { - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dependencies": [ - "slice-ansi@3.0.0", - "string-width" - ] - }, - "cli-width@3.0.0": { - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" - }, - "cliui@8.0.1": { - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": [ - "string-width", - "strip-ansi", - "wrap-ansi@7.0.0" - ] - }, - "clone@1.0.4": { - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" - }, - "cluster-key-slot@1.1.2": { - "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==" - }, - "color-convert@2.0.1": { - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": [ - "color-name@1.1.4" - ] - }, - "color-convert@3.1.3": { - "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", - "dependencies": [ - "color-name@2.1.0" - ] - }, - "color-name@1.1.4": { - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "color-name@2.1.0": { - "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==" - }, - "color-string@2.1.4": { - "integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==", - "dependencies": [ - "color-name@2.1.0" - ] - }, - "color-support@1.1.3": { - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": true - }, - "color@5.0.3": { - "integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==", - "dependencies": [ - "color-convert@3.1.3", - "color-string" - ] - }, - "colorette@2.0.20": { - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "combined-stream@1.0.8": { - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": [ - "delayed-stream" - ] - }, - "common-tags@1.8.2": { - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" - }, - "concat-map@0.0.1": { - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "console-control-strings@1.1.0": { - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" - }, - "constant-case@3.0.4": { - "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", - "dependencies": [ - "no-case", - "tslib@2.8.1", - "upper-case" - ] - }, - "content-disposition@0.5.4": { - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": [ - "safe-buffer" - ] - }, - "content-type@1.0.5": { - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "convert-source-map@2.0.0": { - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "cookie-signature@1.0.7": { - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" - }, - "cookie@0.7.2": { - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==" - }, - "cors@2.8.6": { - "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "dependencies": [ - "object-assign", - "vary" - ] - }, - "cosmiconfig@8.3.6_typescript@5.9.3": { - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dependencies": [ - "import-fresh", - "js-yaml", - "parse-json", - "path-type", - "typescript" - ], - "optionalPeers": [ - "typescript" - ] - }, - "cross-fetch@3.2.0": { - "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", - "dependencies": [ - "node-fetch@2.7.0" - ] - }, - "cross-inspect@1.0.0": { - "integrity": "sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "cross-inspect@1.0.1": { - "integrity": "sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "data-uri-to-buffer@4.0.1": { - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" - }, - "dataloader@2.2.3": { - "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==" - }, - "date-fns@3.6.0": { - "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==" - }, - "debounce@1.2.1": { - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" - }, - "debug@2.6.9": { - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": [ - "ms@2.0.0" - ] - }, - "debug@4.4.3": { - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dependencies": [ - "ms@2.1.3" - ] - }, - "decompress-response@6.0.0": { - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": [ - "mimic-response" - ] - }, - "deep-extend@0.6.0": { - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "defaults@1.0.4": { - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dependencies": [ - "clone" - ] - }, - "define-data-property@1.1.4": { - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": [ - "es-define-property", - "es-errors", - "gopd" - ] - }, - "define-lazy-prop@2.0.0": { - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" - }, - "delayed-stream@1.0.0": { - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "delegates@1.0.0": { - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" - }, - "denque@2.1.0": { - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" - }, - "depd@2.0.0": { - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "dependency-graph@0.11.0": { - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==" - }, - "dependency-graph@1.0.0": { - "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==" - }, - "destroy@1.2.0": { - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "detect-indent@6.1.0": { - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==" - }, - "detect-libc@2.1.2": { - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==" - }, - "dir-glob@3.0.1": { - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": [ - "path-type" - ] - }, - "dot-case@3.0.4": { - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": [ - "no-case", - "tslib@2.8.1" - ] - }, - "dotenv@16.6.1": { - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==" - }, - "dset@3.1.4": { - "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==" - }, - "dunder-proto@1.0.1": { - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dependencies": [ - "call-bind-apply-helpers", - "es-errors", - "gopd" - ] - }, - "ecdsa-sig-formatter@1.0.11": { - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": [ - "safe-buffer" - ] - }, - "ee-first@1.1.1": { - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "electron-to-chromium@1.5.307": { - "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==" - }, - "emoji-regex@8.0.0": { - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "enabled@2.0.0": { - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "encodeurl@2.0.0": { - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - }, - "end-of-stream@1.4.5": { - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dependencies": [ - "once" - ] - }, - "error-ex@1.3.4": { - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dependencies": [ - "is-arrayish" - ] - }, - "es-define-property@1.0.1": { - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" - }, - "es-errors@1.3.0": { - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "es-object-atoms@1.1.1": { - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dependencies": [ - "es-errors" - ] - }, - "es-set-tostringtag@2.1.0": { - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dependencies": [ - "es-errors", - "get-intrinsic", - "has-tostringtag", - "hasown" - ] - }, - "escalade@3.2.0": { - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" - }, - "escape-html@1.0.3": { - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp@1.0.5": { - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" - }, - "etag@1.8.1": { - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "expand-template@2.0.3": { - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" - }, - "express@4.22.1": { - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", - "dependencies": [ - "accepts", - "array-flatten", - "body-parser", - "content-disposition", - "content-type", - "cookie", - "cookie-signature", - "debug@2.6.9", - "depd", - "encodeurl", - "escape-html", - "etag", - "finalhandler", - "fresh", - "http-errors", - "merge-descriptors", - "methods", - "on-finished", - "parseurl", - "path-to-regexp", - "proxy-addr", - "qs", - "range-parser", - "safe-buffer", - "send", - "serve-static", - "setprototypeof", - "statuses", - "type-is", - "utils-merge", - "vary" - ] - }, - "fast-decode-uri-component@1.0.1": { - "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" - }, - "fast-glob@3.3.3": { - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dependencies": [ - "@nodelib/fs.stat", - "@nodelib/fs.walk", - "glob-parent", - "merge2", - "micromatch" - ] - }, - "fast-querystring@1.1.2": { - "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", - "dependencies": [ - "fast-decode-uri-component" - ] - }, - "fastq@1.20.1": { - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dependencies": [ - "reusify" - ] - }, - "fecha@4.2.3": { - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "fetch-blob@3.2.0": { - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dependencies": [ - "node-domexception", - "web-streams-polyfill" - ] - }, - "figures@3.2.0": { - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dependencies": [ - "escape-string-regexp" - ] - }, - "file-uri-to-path@1.0.0": { - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range@7.1.1": { - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": [ - "to-regex-range" - ] - }, - "finalhandler@1.3.2": { - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "dependencies": [ - "debug@2.6.9", - "encodeurl", - "escape-html", - "on-finished", - "parseurl", - "statuses", - "unpipe" - ] - }, - "fn.name@1.1.0": { - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "for-each@0.3.5": { - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dependencies": [ - "is-callable" - ] - }, - "form-data@4.0.5": { - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "dependencies": [ - "asynckit", - "combined-stream", - "es-set-tostringtag", - "hasown", - "mime-types" - ] - }, - "formdata-polyfill@4.0.10": { - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": [ - "fetch-blob" - ] - }, - "forwarded@0.2.0": { - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh@0.5.2": { - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "fs-constants@1.0.0": { - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs-minipass@2.1.0": { - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": [ - "minipass@3.3.6" - ] - }, - "fs.realpath@1.0.0": { - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "function-bind@1.1.2": { - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "gauge@3.0.2": { - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dependencies": [ - "aproba", - "color-support", - "console-control-strings", - "has-unicode", - "object-assign", - "signal-exit", - "string-width", - "strip-ansi", - "wide-align" - ], - "deprecated": true - }, - "gensync@1.0.0-beta.2": { - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "get-caller-file@2.0.5": { - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-intrinsic@1.3.0": { - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dependencies": [ - "call-bind-apply-helpers", - "es-define-property", - "es-errors", - "es-object-atoms", - "function-bind", - "get-proto", - "gopd", - "has-symbols", - "hasown", - "math-intrinsics" - ] - }, - "get-proto@1.0.1": { - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dependencies": [ - "dunder-proto", - "es-object-atoms" - ] - }, - "github-from-package@0.0.0": { - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, - "glob-parent@5.1.2": { - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": [ - "is-glob" - ] - }, - "glob@7.2.3": { - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": [ - "fs.realpath", - "inflight", - "inherits", - "minimatch@3.1.5", - "once", - "path-is-absolute" - ], - "deprecated": true - }, - "globby@11.1.0": { - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": [ - "array-union", - "dir-glob", - "fast-glob", - "ignore", - "merge2", - "slash" - ] - }, - "gopd@1.2.0": { - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" - }, - "graphql-config@5.1.5_graphql@16.13.1_typescript@5.9.3": { - "integrity": "sha512-mG2LL1HccpU8qg5ajLROgdsBzx/o2M6kgI3uAmoaXiSH9PCUbtIyLomLqUtCFaAeG2YCFsl0M5cfQ9rKmDoMVA==", - "dependencies": [ - "@graphql-tools/graphql-file-loader", - "@graphql-tools/json-file-loader", - "@graphql-tools/load@8.1.8_graphql@16.13.1", - "@graphql-tools/merge@9.1.7_graphql@16.13.1", - "@graphql-tools/url-loader@8.0.33_graphql@16.13.1_ws@8.19.0", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "cosmiconfig", - "graphql", - "jiti@2.6.1", - "minimatch@9.0.9", - "string-env-interpolation", - "tslib@2.8.1" - ] - }, - "graphql-request@6.1.0_graphql@16.13.1": { - "integrity": "sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw==", - "dependencies": [ - "@graphql-typed-document-node/core", - "cross-fetch", - "graphql" - ] - }, - "graphql-scalars@1.25.0_graphql@16.13.1": { - "integrity": "sha512-b0xyXZeRFkne4Eq7NAnL400gStGqG/Sx9VqX0A05nHyEbv57UJnWKsjNnrpVqv5e/8N1MUxkt0wwcRXbiyKcFg==", - "dependencies": [ - "graphql", - "tslib@2.8.1" - ] - }, - "graphql-subscriptions@2.0.0_graphql@16.13.1": { - "integrity": "sha512-s6k2b8mmt9gF9pEfkxsaO1lTxaySfKoEJzEfmwguBbQ//Oq23hIXCfR1hm4kdh5hnR20RdwB+s3BCb+0duHSZA==", - "dependencies": [ - "graphql", - "iterall" - ] - }, - "graphql-tag@2.12.6_graphql@16.13.1": { - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", - "dependencies": [ - "graphql", - "tslib@2.8.1" - ] - }, - "graphql-ws@5.16.2_graphql@16.13.1": { - "integrity": "sha512-E1uccsZxt/96jH/OwmLPuXMACILs76pKF2i3W861LpKBCYtGIyPQGtWLuBLkND4ox1KHns70e83PS4te50nvPQ==", - "dependencies": [ - "graphql" - ] - }, - "graphql-ws@6.0.7_graphql@16.13.1_ws@8.19.0": { - "integrity": "sha512-yoLRW+KRlDmnnROdAu7sX77VNLC0bsFoZyGQJLy1cF+X/SkLg/fWkRGrEEYQK8o2cafJ2wmEaMqMEZB3U3DYDg==", - "dependencies": [ - "graphql", - "ws" - ], - "optionalPeers": [ - "ws" - ] - }, - "graphql-yoga@5.7.0_graphql@16.13.1": { - "integrity": "sha512-QyGVvFAvGhMrzjJvhjsxsyoE+e4lNrj5f5qOsRYJuWIjyw7tHfbBvybZIwzNOGY0aB5sgA8BlVvu5hxjdKJ5tQ==", - "dependencies": [ - "@envelop/core", - "@graphql-tools/executor", - "@graphql-tools/schema@10.0.31_graphql@16.13.1", - "@graphql-tools/utils@10.11.0_graphql@16.13.1", - "@graphql-yoga/logger", - "@graphql-yoga/subscription", - "@whatwg-node/fetch@0.9.23", - "@whatwg-node/server", - "dset", - "graphql", - "lru-cache@10.4.3", - "tslib@2.8.1" - ] - }, - "graphql@16.13.1": { - "integrity": "sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==" - }, - "has-flag@4.0.0": { - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-property-descriptors@1.0.2": { - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": [ - "es-define-property" - ] - }, - "has-symbols@1.1.0": { - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" - }, - "has-tostringtag@1.0.2": { - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": [ - "has-symbols" - ] - }, - "has-unicode@2.0.1": { - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, - "hasown@2.0.2": { - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": [ - "function-bind" - ] - }, - "header-case@2.0.4": { - "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", - "dependencies": [ - "capital-case", - "tslib@2.8.1" - ] - }, - "http-errors@2.0.1": { - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dependencies": [ - "depd", - "inherits", - "setprototypeof", - "statuses", - "toidentifier" - ] - }, - "http-proxy-agent@7.0.2": { - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dependencies": [ - "agent-base@7.1.4", - "debug@4.4.3" - ] - }, - "https-proxy-agent@5.0.1": { - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": [ - "agent-base@6.0.2", - "debug@4.4.3" - ] - }, - "https-proxy-agent@7.0.6": { - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dependencies": [ - "agent-base@7.1.4", - "debug@4.4.3" - ] - }, - "iconv-lite@0.4.24": { - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": [ - "safer-buffer" - ] - }, - "iconv-lite@0.7.2": { - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "dependencies": [ - "safer-buffer" - ] - }, - "ieee754@1.2.1": { - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore@5.3.2": { - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==" - }, - "immutable@5.1.5": { - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==" - }, - "import-fresh@3.3.1": { - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dependencies": [ - "parent-module", - "resolve-from@4.0.0" - ] - }, - "import-from@4.0.0": { - "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==" - }, - "indent-string@4.0.0": { - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "inflight@1.0.6": { - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": [ - "once", - "wrappy" - ], - "deprecated": true - }, - "inherits@2.0.4": { - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini@1.3.8": { - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "inquirer@8.2.7": { - "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", - "dependencies": [ - "@inquirer/external-editor", - "ansi-escapes", - "chalk", - "cli-cursor", - "cli-width", - "figures", - "lodash", - "mute-stream", - "ora", - "run-async", - "rxjs", - "string-width", - "strip-ansi", - "through", - "wrap-ansi@6.2.0" - ] - }, - "invariant@2.2.4": { - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": [ - "loose-envify" - ] - }, - "ioredis@5.10.0": { - "integrity": "sha512-HVBe9OFuqs+Z6n64q09PQvP1/R4Bm+30PAyyD4wIEqssh3v9L21QjCVk4kRLucMBcDokJTcLjsGeVRlq/nH6DA==", - "dependencies": [ - "@ioredis/commands", - "cluster-key-slot", - "debug@4.4.3", - "denque", - "lodash.defaults", - "lodash.isarguments", - "redis-errors", - "redis-parser", - "standard-as-callback" - ] - }, - "ipaddr.js@1.9.1": { - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-absolute@1.0.0": { - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dependencies": [ - "is-relative", - "is-windows" - ] - }, - "is-arrayish@0.2.1": { - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "is-callable@1.2.7": { - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" - }, - "is-docker@2.2.1": { - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": true - }, - "is-extglob@2.1.1": { - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-fullwidth-code-point@3.0.0": { - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob@4.0.3": { - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": [ - "is-extglob" - ] - }, - "is-interactive@1.0.0": { - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" - }, - "is-lower-case@2.0.2": { - "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "is-number@7.0.0": { - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-relative@1.0.0": { - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dependencies": [ - "is-unc-path" - ] - }, - "is-stream@2.0.1": { - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-typed-array@1.1.15": { - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", - "dependencies": [ - "which-typed-array" - ] - }, - "is-unc-path@1.0.0": { - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dependencies": [ - "unc-path-regex" - ] - }, - "is-unicode-supported@0.1.0": { - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" - }, - "is-upper-case@2.0.2": { - "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "is-windows@1.0.2": { - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl@2.2.0": { - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": [ - "is-docker" - ] - }, - "isarray@2.0.5": { - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "isomorphic-ws@5.0.0_ws@8.19.0": { - "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", - "dependencies": [ - "ws" - ] - }, - "iterall@1.3.0": { - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==" - }, - "jiti@1.21.7": { - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "bin": true - }, - "jiti@2.6.1": { - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "bin": true - }, - "jose@5.10.0": { - "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==" - }, - "js-levenshtein@1.1.6": { - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" - }, - "js-tokens@4.0.0": { - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml@4.1.1": { - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dependencies": [ - "argparse" - ], - "bin": true - }, - "jsesc@3.1.0": { - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "bin": true - }, - "json-parse-even-better-errors@2.3.1": { - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json-to-pretty-yaml@1.2.2": { - "integrity": "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==", - "dependencies": [ - "remedial", - "remove-trailing-spaces" - ] - }, - "json5@2.2.3": { - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": true - }, - "jsonwebtoken@9.0.3": { - "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", - "dependencies": [ - "jws", - "lodash.includes", - "lodash.isboolean", - "lodash.isinteger", - "lodash.isnumber", - "lodash.isplainobject", - "lodash.isstring", - "lodash.once", - "ms@2.1.3", - "semver@7.7.4" - ] - }, - "jwa@2.0.1": { - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", - "dependencies": [ - "buffer-equal-constant-time", - "ecdsa-sig-formatter", - "safe-buffer" - ] - }, - "jws@4.0.1": { - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", - "dependencies": [ - "jwa", - "safe-buffer" - ] - }, - "kuler@2.0.0": { - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "lines-and-columns@1.2.4": { - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "listr2@4.0.5": { - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", - "dependencies": [ - "cli-truncate", - "colorette", - "log-update", - "p-map", - "rfdc", - "rxjs", - "through", - "wrap-ansi@7.0.0" - ] - }, - "lodash.defaults@4.2.0": { - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" - }, - "lodash.includes@4.3.0": { - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "lodash.isarguments@3.1.0": { - "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" - }, - "lodash.isboolean@3.0.3": { - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "lodash.isinteger@4.0.4": { - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "lodash.isnumber@3.0.3": { - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "lodash.isplainobject@4.0.6": { - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "lodash.isstring@4.0.1": { - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "lodash.once@4.1.1": { - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "lodash.sortby@4.7.0": { - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "lodash@4.17.23": { - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==" - }, - "log-symbols@4.1.0": { - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dependencies": [ - "chalk", - "is-unicode-supported" - ] - }, - "log-update@4.0.0": { - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dependencies": [ - "ansi-escapes", - "cli-cursor", - "slice-ansi@4.0.0", - "wrap-ansi@6.2.0" - ] - }, - "logform@2.7.0": { - "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", - "dependencies": [ - "@colors/colors@1.6.0", - "@types/triple-beam", - "fecha", - "ms@2.1.3", - "safe-stable-stringify", - "triple-beam" - ] - }, - "loglevel@1.9.2": { - "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==" - }, - "long@4.0.0": { - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "loose-envify@1.4.0": { - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": [ - "js-tokens" - ], - "bin": true - }, - "lower-case-first@2.0.2": { - "integrity": "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "lower-case@2.0.2": { - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "lru-cache@10.4.3": { - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" - }, - "lru-cache@5.1.1": { - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": [ - "yallist@3.1.1" - ] - }, - "lru-cache@7.18.3": { - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" - }, - "make-dir@3.1.0": { - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": [ - "semver@6.3.1" - ] - }, - "map-cache@0.2.2": { - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" - }, - "math-intrinsics@1.1.0": { - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" - }, - "media-typer@0.3.0": { - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "merge-descriptors@1.0.3": { - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" - }, - "merge2@1.4.1": { - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "meros@1.3.2": { - "integrity": "sha512-Q3mobPbvEx7XbwhnC1J1r60+5H6EZyNccdzSz0eGexJRwouUtTZxPVRGdqKtxlpD84ScK4+tIGldkqDtCKdI0A==" - }, - "methods@1.1.2": { - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "micromatch@4.0.8": { - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": [ - "braces", - "picomatch" - ] - }, - "mime-db@1.52.0": { - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types@2.1.35": { - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": [ - "mime-db" - ] - }, - "mime@1.6.0": { - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": true - }, - "mimic-fn@2.1.0": { - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "mimic-response@3.1.0": { - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - }, - "minimatch@3.1.5": { - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dependencies": [ - "brace-expansion@1.1.12" - ] - }, - "minimatch@9.0.9": { - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dependencies": [ - "brace-expansion@2.0.2" - ] - }, - "minimist@1.2.8": { - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "minipass@3.3.6": { - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": [ - "yallist@4.0.0" - ] - }, - "minipass@5.0.0": { - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" - }, - "minizlib@2.1.2": { - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": [ - "minipass@3.3.6", - "yallist@4.0.0" - ] - }, - "mkdirp-classic@0.5.3": { - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "mkdirp@1.0.4": { - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": true - }, - "ms@2.0.0": { - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "ms@2.1.3": { - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "mute-stream@0.0.8": { - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, - "napi-build-utils@2.0.0": { - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" - }, - "negotiator@0.6.3": { - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "no-case@3.0.4": { - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": [ - "lower-case", - "tslib@2.8.1" - ] - }, - "node-abi@3.87.0": { - "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", - "dependencies": [ - "semver@7.7.4" - ] - }, - "node-abort-controller@3.1.1": { - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" - }, - "node-addon-api@5.1.0": { - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" - }, - "node-domexception@1.0.0": { - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": true - }, - "node-fetch@2.7.0": { - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": [ - "whatwg-url" - ] - }, - "node-fetch@3.3.2": { - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dependencies": [ - "data-uri-to-buffer", - "fetch-blob", - "formdata-polyfill" - ] - }, - "node-releases@2.0.36": { - "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==" - }, - "nopt@5.0.0": { - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": [ - "abbrev" - ], - "bin": true - }, - "normalize-path@2.1.1": { - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dependencies": [ - "remove-trailing-separator" - ] - }, - "npmlog@5.0.1": { - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dependencies": [ - "are-we-there-yet", - "console-control-strings", - "gauge", - "set-blocking" - ], - "deprecated": true - }, - "object-assign@4.1.1": { - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-inspect@1.13.2": { - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" - }, - "object-inspect@1.13.4": { - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - }, - "on-finished@2.4.1": { - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": [ - "ee-first" - ] - }, - "once@1.4.0": { - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": [ - "wrappy" - ] - }, - "one-time@1.0.0": { - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": [ - "fn.name" - ] - }, - "onetime@5.1.2": { - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": [ - "mimic-fn" - ] - }, - "open@8.4.2": { - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": [ - "define-lazy-prop", - "is-docker", - "is-wsl" - ] - }, - "ora@5.4.1": { - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dependencies": [ - "bl", - "chalk", - "cli-cursor", - "cli-spinners", - "is-interactive", - "is-unicode-supported", - "log-symbols", - "strip-ansi", - "wcwidth" - ] - }, - "p-limit@3.1.0": { - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": [ - "yocto-queue" - ] - }, - "p-map@4.0.0": { - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": [ - "aggregate-error" - ] - }, - "param-case@3.0.4": { - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": [ - "dot-case", - "tslib@2.8.1" - ] - }, - "parent-module@1.0.1": { - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": [ - "callsites" - ] - }, - "parse-filepath@1.0.2": { - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dependencies": [ - "is-absolute", - "map-cache", - "path-root" - ] - }, - "parse-json@5.2.0": { - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": [ - "@babel/code-frame", - "error-ex", - "json-parse-even-better-errors", - "lines-and-columns" - ] - }, - "parseurl@1.3.3": { - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "pascal-case@3.1.2": { - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": [ - "no-case", - "tslib@2.8.1" - ] - }, - "path-case@3.0.4": { - "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", - "dependencies": [ - "dot-case", - "tslib@2.8.1" - ] - }, - "path-is-absolute@1.0.1": { - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-root-regex@0.1.2": { - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==" - }, - "path-root@0.1.1": { - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dependencies": [ - "path-root-regex" - ] - }, - "path-to-regexp@0.1.12": { - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" - }, - "path-type@4.0.0": { - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pg-cloudflare@1.3.0": { - "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==" - }, - "pg-connection-string@2.12.0": { - "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==" - }, - "pg-int8@1.0.1": { - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" - }, - "pg-pool@3.13.0_pg@8.20.0": { - "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", - "dependencies": [ - "pg" - ] - }, - "pg-protocol@1.13.0": { - "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==" - }, - "pg-types@2.2.0": { - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "dependencies": [ - "pg-int8", - "postgres-array", - "postgres-bytea", - "postgres-date", - "postgres-interval" - ] - }, - "pg@8.20.0": { - "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", - "dependencies": [ - "pg-connection-string", - "pg-pool", - "pg-protocol", - "pg-types", - "pgpass" - ], - "optionalDependencies": [ - "pg-cloudflare" - ] - }, - "pgpass@1.0.5": { - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "dependencies": [ - "split2" - ] - }, - "picocolors@1.1.1": { - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "picomatch@2.3.1": { - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "possible-typed-array-names@1.1.0": { - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==" - }, - "postgres-array@2.0.0": { - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" - }, - "postgres-bytea@1.0.1": { - "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==" - }, - "postgres-date@1.0.7": { - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" - }, - "postgres-interval@1.2.0": { - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "dependencies": [ - "xtend" - ] - }, - "prebuild-install@7.1.3": { - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "dependencies": [ - "detect-libc", - "expand-template", - "github-from-package", - "minimist", - "mkdirp-classic", - "napi-build-utils", - "node-abi", - "pump", - "rc", - "simple-get", - "tar-fs", - "tunnel-agent" - ], - "deprecated": true, - "bin": true - }, - "proxy-addr@2.0.7": { - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": [ - "forwarded", - "ipaddr.js" - ] - }, - "pump@3.0.4": { - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "dependencies": [ - "end-of-stream", - "once" - ] - }, - "qs@6.14.2": { - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", - "dependencies": [ - "side-channel" - ] - }, - "queue-microtask@1.2.3": { - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "range-parser@1.2.1": { - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body@2.5.3": { - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "dependencies": [ - "bytes", - "http-errors", - "iconv-lite@0.4.24", - "unpipe" - ] - }, - "rc@1.2.8": { - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": [ - "deep-extend", - "ini", - "minimist", - "strip-json-comments" - ], - "bin": true - }, - "readable-stream@3.6.2": { - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": [ - "inherits", - "string_decoder", - "util-deprecate" - ] - }, - "redis-errors@1.2.0": { - "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==" - }, - "redis-parser@3.0.0": { - "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", - "dependencies": [ - "redis-errors" - ] - }, - "remedial@1.0.8": { - "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==" - }, - "remove-trailing-separator@1.1.0": { - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" - }, - "remove-trailing-spaces@1.0.9": { - "integrity": "sha512-xzG7w5IRijvIkHIjDk65URsJJ7k4J95wmcArY5PRcmjldIOl7oTvG8+X2Ag690R7SfwiOcHrWZKVc1Pp5WIOzA==" - }, - "require-directory@2.1.1": { - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" - }, - "rescript@12.2.0": { - "integrity": "sha512-1Jf2cmNhyx5Mj2vwZ4XXPcXvNSjGj9D1jPBUcoqIOqRpLPo1ch2Ta/7eWh23xAHWHK5ow7BCDyYFjvZSjyjLzg==", - "dependencies": [ - "@rescript/runtime" - ], - "optionalDependencies": [ - "@rescript/darwin-arm64", - "@rescript/darwin-x64", - "@rescript/linux-arm64", - "@rescript/linux-x64", - "@rescript/win32-x64" - ], - "bin": true - }, - "resolve-from@4.0.0": { - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "resolve-from@5.0.0": { - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "restore-cursor@3.1.0": { - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dependencies": [ - "onetime", - "signal-exit" - ] - }, - "retry@0.13.1": { - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" - }, - "reusify@1.1.0": { - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==" - }, - "rfdc@1.4.1": { - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" - }, - "rimraf@3.0.2": { - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": [ - "glob" - ], - "deprecated": true, - "bin": true - }, - "run-async@2.4.1": { - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" - }, - "run-parallel@1.2.0": { - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dependencies": [ - "queue-microtask" - ] - }, - "rxjs@7.8.2": { - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "safe-buffer@5.2.1": { - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-stable-stringify@2.5.0": { - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==" - }, - "safer-buffer@2.1.2": { - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scuid@1.1.0": { - "integrity": "sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==" - }, - "semver@6.3.1": { - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": true - }, - "semver@7.7.4": { - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "bin": true - }, - "send@0.19.2": { - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", - "dependencies": [ - "debug@2.6.9", - "depd", - "destroy", - "encodeurl", - "escape-html", - "etag", - "fresh", - "http-errors", - "mime", - "ms@2.1.3", - "on-finished", - "range-parser", - "statuses" - ] - }, - "sentence-case@3.0.4": { - "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", - "dependencies": [ - "no-case", - "tslib@2.8.1", - "upper-case-first" - ] - }, - "serve-static@1.16.3": { - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", - "dependencies": [ - "encodeurl", - "escape-html", - "parseurl", - "send" - ] - }, - "set-blocking@2.0.0": { - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" - }, - "set-function-length@1.2.2": { - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": [ - "define-data-property", - "es-errors", - "function-bind", - "get-intrinsic", - "gopd", - "has-property-descriptors" - ] - }, - "setprototypeof@1.2.0": { - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "sha.js@2.4.12": { - "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", - "dependencies": [ - "inherits", - "safe-buffer", - "to-buffer" - ], - "bin": true - }, - "shell-quote@1.8.3": { - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==" - }, - "side-channel-list@1.0.0": { - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dependencies": [ - "es-errors", - "object-inspect@1.13.4" - ] - }, - "side-channel-map@1.0.1": { - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dependencies": [ - "call-bound", - "es-errors", - "get-intrinsic", - "object-inspect@1.13.4" - ] - }, - "side-channel-weakmap@1.0.2": { - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dependencies": [ - "call-bound", - "es-errors", - "get-intrinsic", - "object-inspect@1.13.4", - "side-channel-map" - ] - }, - "side-channel@1.1.0": { - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dependencies": [ - "es-errors", - "object-inspect@1.13.4", - "side-channel-list", - "side-channel-map", - "side-channel-weakmap" - ] - }, - "signal-exit@3.0.7": { - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "simple-concat@1.0.1": { - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "simple-get@4.0.1": { - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dependencies": [ - "decompress-response", - "once", - "simple-concat" - ] - }, - "slash@3.0.0": { - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "slice-ansi@3.0.0": { - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dependencies": [ - "ansi-styles", - "astral-regex", - "is-fullwidth-code-point" - ] - }, - "slice-ansi@4.0.0": { - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dependencies": [ - "ansi-styles", - "astral-regex", - "is-fullwidth-code-point" - ] - }, - "snake-case@3.0.4": { - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dependencies": [ - "dot-case", - "tslib@2.8.1" - ] - }, - "split2@4.2.0": { - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" - }, - "sponge-case@1.0.1": { - "integrity": "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "stack-trace@0.0.10": { - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" - }, - "standard-as-callback@2.1.0": { - "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" - }, - "statuses@2.0.2": { - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - }, - "std-env@3.7.0": { - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" - }, - "streamsearch@1.1.0": { - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" - }, - "string-env-interpolation@1.0.1": { - "integrity": "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==" - }, - "string-width@4.2.3": { - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": [ - "emoji-regex", - "is-fullwidth-code-point", - "strip-ansi" - ] - }, - "string_decoder@1.3.0": { - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": [ - "safe-buffer" - ] - }, - "strip-ansi@6.0.1": { - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": [ - "ansi-regex" - ] - }, - "strip-json-comments@2.0.1": { - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" - }, - "supports-color@7.2.0": { - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": [ - "has-flag" - ] - }, - "swap-case@2.0.2": { - "integrity": "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "sync-fetch@0.6.0": { - "integrity": "sha512-IELLEvzHuCfc1uTsshPK58ViSdNqXxlml1U+fmwJIKLYKOr/rAtBrorE2RYm5IHaMpDNlmC0fr1LAvdXvyheEQ==", - "dependencies": [ - "node-fetch@3.3.2", - "timeout-signal", - "whatwg-mimetype@4.0.0" - ] - }, - "sync-fetch@0.6.0-2": { - "integrity": "sha512-c7AfkZ9udatCuAy9RSfiGPpeOKKUAUK5e1cXadLOGUjasdxqYqAK0jTNkM/FSEyJ3a5Ra27j/tw/PS0qLmaF/A==", - "dependencies": [ - "node-fetch@3.3.2", - "timeout-signal", - "whatwg-mimetype@4.0.0" - ] - }, - "tar-fs@2.1.4": { - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "dependencies": [ - "chownr@1.1.4", - "mkdirp-classic", - "pump", - "tar-stream" - ] - }, - "tar-stream@2.2.0": { - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": [ - "bl", - "end-of-stream", - "fs-constants", - "inherits", - "readable-stream" - ] - }, - "tar@6.2.1": { - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dependencies": [ - "chownr@2.0.0", - "fs-minipass", - "minipass@5.0.0", - "minizlib", - "mkdirp", - "yallist@4.0.0" - ], - "deprecated": true - }, - "text-hex@1.0.0": { - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "through@2.3.8": { - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "timeout-signal@2.0.0": { - "integrity": "sha512-YBGpG4bWsHoPvofT6y/5iqulfXIiIErl5B0LdtHT1mGXDFTAhhRrbUpTvBgYbovr+3cKblya2WAOcpoy90XguA==" - }, - "title-case@3.0.3": { - "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "to-buffer@1.2.2": { - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", - "dependencies": [ - "isarray", - "safe-buffer", - "typed-array-buffer" - ] - }, - "to-regex-range@5.0.1": { - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": [ - "is-number" - ] - }, - "toidentifier@1.0.1": { - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "tr46@0.0.3": { - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "triple-beam@1.4.1": { - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" - }, - "ts-log@2.2.7": { - "integrity": "sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg==" - }, - "tslib@2.6.2": { - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "tslib@2.6.3": { - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "tslib@2.8.1": { - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, - "tunnel-agent@0.6.0": { - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": [ - "safe-buffer" - ] - }, - "type-fest@0.21.3": { - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - }, - "type-is@1.6.18": { - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": [ - "media-typer", - "mime-types" - ] - }, - "typed-array-buffer@1.0.3": { - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dependencies": [ - "call-bound", - "es-errors", - "is-typed-array" - ] - }, - "typescript@5.9.3": { - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "bin": true - }, - "unc-path-regex@0.1.2": { - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==" - }, - "undici-types@7.18.2": { - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==" - }, - "unixify@1.0.0": { - "integrity": "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==", - "dependencies": [ - "normalize-path" - ] - }, - "unpipe@1.0.0": { - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "update-browserslist-db@1.2.3_browserslist@4.28.1": { - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dependencies": [ - "browserslist", - "escalade", - "picocolors" - ], - "bin": true - }, - "upper-case-first@2.0.2": { - "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "upper-case@2.0.2": { - "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", - "dependencies": [ - "tslib@2.8.1" - ] - }, - "urlpattern-polyfill@10.1.0": { - "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==" - }, - "util-deprecate@1.0.2": { - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "utils-merge@1.0.1": { - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, - "uuid@9.0.1": { - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "bin": true - }, - "value-or-promise@1.0.12": { - "integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==" - }, - "vary@1.1.2": { - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "wcwidth@1.0.1": { - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dependencies": [ - "defaults" - ] - }, - "web-streams-polyfill@3.3.3": { - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" - }, - "webidl-conversions@3.0.1": { - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-mimetype@3.0.0": { - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==" - }, - "whatwg-mimetype@4.0.0": { - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" - }, - "whatwg-url@5.0.0": { - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": [ - "tr46", - "webidl-conversions" - ] - }, - "which-typed-array@1.1.20": { - "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", - "dependencies": [ - "available-typed-arrays", - "call-bind", - "call-bound", - "for-each", - "get-proto", - "gopd", - "has-tostringtag" - ] - }, - "wide-align@1.1.5": { - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dependencies": [ - "string-width" - ] - }, - "winston-transport@4.9.0": { - "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", - "dependencies": [ - "logform", - "readable-stream", - "triple-beam" - ] - }, - "winston@3.19.0": { - "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", - "dependencies": [ - "@colors/colors@1.6.0", - "@dabh/diagnostics", - "async", - "is-stream", - "logform", - "one-time", - "readable-stream", - "safe-stable-stringify", - "stack-trace", - "triple-beam", - "winston-transport" - ] - }, - "wrap-ansi@6.2.0": { - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dependencies": [ - "ansi-styles", - "string-width", - "strip-ansi" - ] - }, - "wrap-ansi@7.0.0": { - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": [ - "ansi-styles", - "string-width", - "strip-ansi" - ] - }, - "wrappy@1.0.2": { - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "ws@8.19.0": { - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==" - }, - "xtend@4.0.2": { - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n@5.0.8": { - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist@3.1.1": { - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yallist@4.0.0": { - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml-ast-parser@0.0.43": { - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==" - }, - "yaml@2.8.2": { - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "bin": true - }, - "yargs-parser@21.1.1": { - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" - }, - "yargs@17.7.2": { - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": [ - "cliui", - "escalade", - "get-caller-file", - "require-directory", - "string-width", - "y18n", - "yargs-parser" - ] - }, - "yocto-queue@0.1.0": { - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" - } - }, - "workspace": { - "dependencies": [ - "npm:@rescript/core@^1.6.1", - "npm:@rescript/runtime@12.2.0", - "npm:jsonwebtoken@^9.0.2", - "npm:rescript@12" - ], - "packageJson": { - "dependencies": [ - "npm:@apollo/server@^4.10.0", - "npm:@apollo/subgraph@^2.7.0", - "npm:@graphql-codegen/cli@5", - "npm:@graphql-codegen/typescript-resolvers@^4.0.4", - "npm:@graphql-codegen/typescript@^4.0.4", - "npm:@graphql-inspector/cli@^5.0.2", - "npm:@graphql-tools/load-files@7", - "npm:@graphql-tools/schema@^10.0.3", - "npm:@types/bcrypt@^5.0.2", - "npm:@types/better-sqlite3@^7.6.8", - "npm:@types/cors@^2.8.17", - "npm:@types/express@^4.17.21", - "npm:@types/jsonwebtoken@^9.0.5", - "npm:@types/pg@^8.10.9", - "npm:@types/uuid@^9.0.7", - "npm:@types/ws@^8.5.10", - "npm:bcrypt@^5.1.1", - "npm:better-sqlite3@^9.2.2", - "npm:bun-types@latest", - "npm:cors@^2.8.5", - "npm:dataloader@^2.2.2", - "npm:date-fns@^3.3.0", - "npm:express@^4.18.2", - "npm:graphql-scalars@^1.22.4", - "npm:graphql-subscriptions@2", - "npm:graphql-ws@^5.15.0", - "npm:graphql@^16.8.1", - "npm:ioredis@^5.3.2", - "npm:jsonwebtoken@^9.0.2", - "npm:pg@^8.11.3", - "npm:typescript@^5.3.3", - "npm:uuid@^9.0.1", - "npm:winston@^3.11.0", - "npm:ws@^8.16.0" - ] - } - } -} diff --git a/praxis/SymbolicEngine/graphql/graphql-config.yml b/praxis/SymbolicEngine/graphql/graphql-config.yml index c52f218..83a8a9a 100644 --- a/praxis/SymbolicEngine/graphql/graphql-config.yml +++ b/praxis/SymbolicEngine/graphql/graphql-config.yml @@ -12,5 +12,3 @@ extensions: generates: src/generated/types.ts: plugins: - - typescript - - typescript-resolvers diff --git a/praxis/SymbolicEngine/graphql/lib/ocaml/Jwt.ast b/praxis/SymbolicEngine/graphql/lib/ocaml/Jwt.ast index 73e2d04..cade062 100644 Binary files a/praxis/SymbolicEngine/graphql/lib/ocaml/Jwt.ast and b/praxis/SymbolicEngine/graphql/lib/ocaml/Jwt.ast differ diff --git a/praxis/SymbolicEngine/graphql/lib/ocaml/Jwt.res b/praxis/SymbolicEngine/graphql/lib/ocaml/Jwt.res deleted file mode 100644 index ddc34a8..0000000 --- a/praxis/SymbolicEngine/graphql/lib/ocaml/Jwt.res +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * JWT Authentication for Praxis GraphQL - * Fully ported to ReScript v12 - */ - -module Types = { - type authUser = { - id: string, - username: string, - roles: array, - permissions: array, - } -} - -module Jwt = { - @module("jsonwebtoken") - external verify: (string, string) => JSON.t = "verify" - - @module("jsonwebtoken") - external sign: (JSON.t, string, {"expiresIn": string}) => string = "sign" -} - -module Node = { - module Http = { - type incomingMessage = {headers: {"authorization": option}} - } -} - -let jwtSecret = switch %raw(`process.env.JWT_SECRET`) { -| s if %raw(`typeof s === 'string'`) => (s :> string) -| _ => "wp-praxis-secret-change-in-production" -} - -let jwtExpiresIn = switch %raw(`process.env.JWT_EXPIRES_IN`) { -| s if %raw(`typeof s === 'string'`) => (s :> string) -| _ => "24h" -} - -let extractToken = (req: Node.Http.incomingMessage): option => { - switch req.headers["authorization"] { - | None => None - | Some(authHeader) => - if String.startsWith(authHeader, "Bearer ") { - Some(String.substring(authHeader, ~start=7, ~end=String.length(authHeader))) - } else { - Some(authHeader) - } - } -} - -let verifyToken = async (token: string): option => { - try { - let decoded = Jwt.verify(token, jwtSecret) - let dict = JSON.Decode.object(decoded)->Option.getExn - - Some({ - id: switch (Dict.get(dict, "id"), Dict.get(dict, "sub")) { - | (Some(id), _) => JSON.Decode.string(id)->Option.getOr("") - | (_, Some(sub)) => JSON.Decode.string(sub)->Option.getOr("") - | _ => "" - }, - username: Dict.get(dict, "username") - ->Option.flatMap(JSON.Decode.string) - ->Option.getOr(""), - roles: Dict.get(dict, "roles") - ->Option.flatMap(JSON.Decode.array) - ->Option.getOr([]) - ->Array.map(v => JSON.Decode.string(v)->Option.getOr("")), - permissions: Dict.get(dict, "permissions") - ->Option.flatMap(JSON.Decode.array) - ->Option.getOr([]) - ->Array.map(v => JSON.Decode.string(v)->Option.getOr("")), - }) - } catch { - | _ => None - } -} - -let generateToken = (user: Types.authUser): string => { - let payload = JSON.Encode.object( - Dict.fromArray([ - ("sub", JSON.Encode.string(user.id)), - ("username", JSON.Encode.string(user.username)), - ("roles", JSON.Encode.array(user.roles->Array.map(JSON.Encode.string))), - ("permissions", JSON.Encode.array(user.permissions->Array.map(JSON.Encode.string))), - ]), - ) - - Jwt.sign(payload, jwtSecret, {"expiresIn": jwtExpiresIn}) -} diff --git a/praxis/SymbolicEngine/graphql/lib/ocaml/Server.res b/praxis/SymbolicEngine/graphql/lib/ocaml/Server.res deleted file mode 100644 index f2c64e6..0000000 --- a/praxis/SymbolicEngine/graphql/lib/ocaml/Server.res +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * WP Praxis GraphQL API Server - * Fully ported to ReScript v12 - */ - -module Apollo = { - type server - type options = { - schema: JSON.t, - plugins: array, - introspection: bool, - } - @module("@apollo/server") @new - external make: options => server = "ApolloServer" - @send external start: server => promise = "start" - @send external stop: server => promise = "stop" -} - -module Express = { - type t - type request - type response - @module("express") external make: unit => t = "default" - @send external use: (t, 'middleware) => unit = "use" - @send external get: (t, string, (request, response) => unit) => unit = "get" - @module("@apollo/server/express4") - external expressMiddleware: (Apollo.server, 'options) => 'middleware = "expressMiddleware" -} - -module Http = { - type server - @module("http") external createServer: Express.t => server = "createServer" - @send external listen: (server, {"port": int, "host": string}, unit => unit) => unit = "listen" - @send external close: server => unit = "close" -} - -// Logic implementations -let startServer = async () => { - Console.log("🚀 Starting WP Praxis GraphQL Server...") - - let app = Express.make() - let httpServer = Http.createServer(app) - - let server = Apollo.make({ - schema: %raw(`{}`), // Placeholder for actual schema - plugins: [], - introspection: true, - }) - - await Apollo.start(server) - - Express.get(app, "/health", (_req, res) => { - let payload = {"status": "ok", "timestamp": Date.now()} - let _ = %raw(`res.json(payload)`) - }) - - let port = 4000 - let host = "localhost" - - Http.listen(httpServer, {"port": port, "host": host}, () => { - Console.log(`🚀 GraphQL API Server ready at http://${host}:${Int.toString(port)}/graphql`) - }) -} - -let _ = startServer() diff --git a/praxis/SymbolicEngine/graphql/lib/rescript.lock b/praxis/SymbolicEngine/graphql/lib/rescript.lock deleted file mode 100644 index 0a3dc3a..0000000 --- a/praxis/SymbolicEngine/graphql/lib/rescript.lock +++ /dev/null @@ -1 +0,0 @@ -126878 \ No newline at end of file diff --git a/praxis/SymbolicEngine/graphql/package.json b/praxis/SymbolicEngine/graphql/package.json index f58d602..939bc18 100644 --- a/praxis/SymbolicEngine/graphql/package.json +++ b/praxis/SymbolicEngine/graphql/package.json @@ -40,19 +40,8 @@ }, "devDependencies": { "@graphql-codegen/cli": "^5.0.0", - "@graphql-codegen/typescript": "^4.0.4", - "@graphql-codegen/typescript-resolvers": "^4.0.4", "@graphql-inspector/cli": "^5.0.2", - "@types/bcrypt": "^5.0.2", - "@types/jsonwebtoken": "^9.0.5", - "@types/pg": "^8.10.9", - "@types/ws": "^8.5.10", - "@types/uuid": "^9.0.7", - "@types/express": "^4.17.21", - "@types/cors": "^2.8.17", - "@types/better-sqlite3": "^7.6.8", "bun-types": "latest", - "typescript": "^5.3.3" }, "keywords": [ "wp-praxis", diff --git a/praxis/SymbolicEngine/graphql/rescript.json b/praxis/SymbolicEngine/graphql/rescript.json deleted file mode 100644 index f6b9088..0000000 --- a/praxis/SymbolicEngine/graphql/rescript.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "praxis-graphql", - "version": "0.1.0", - "sources": [ - { - "dir": "src", - "subdirs": true - } - ], - "package-specs": [ - { - "module": "esmodule", - "in-source": true - } - ], - "suffix": ".res.js", - "dependencies": [ - "@rescript/core" - ], - "compiler-flags": ["-open RescriptCore"], - "uncurried": true -} diff --git a/praxis/SymbolicEngine/graphql/src/Server.res b/praxis/SymbolicEngine/graphql/src/Server.res deleted file mode 100644 index f2c64e6..0000000 --- a/praxis/SymbolicEngine/graphql/src/Server.res +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * WP Praxis GraphQL API Server - * Fully ported to ReScript v12 - */ - -module Apollo = { - type server - type options = { - schema: JSON.t, - plugins: array, - introspection: bool, - } - @module("@apollo/server") @new - external make: options => server = "ApolloServer" - @send external start: server => promise = "start" - @send external stop: server => promise = "stop" -} - -module Express = { - type t - type request - type response - @module("express") external make: unit => t = "default" - @send external use: (t, 'middleware) => unit = "use" - @send external get: (t, string, (request, response) => unit) => unit = "get" - @module("@apollo/server/express4") - external expressMiddleware: (Apollo.server, 'options) => 'middleware = "expressMiddleware" -} - -module Http = { - type server - @module("http") external createServer: Express.t => server = "createServer" - @send external listen: (server, {"port": int, "host": string}, unit => unit) => unit = "listen" - @send external close: server => unit = "close" -} - -// Logic implementations -let startServer = async () => { - Console.log("🚀 Starting WP Praxis GraphQL Server...") - - let app = Express.make() - let httpServer = Http.createServer(app) - - let server = Apollo.make({ - schema: %raw(`{}`), // Placeholder for actual schema - plugins: [], - introspection: true, - }) - - await Apollo.start(server) - - Express.get(app, "/health", (_req, res) => { - let payload = {"status": "ok", "timestamp": Date.now()} - let _ = %raw(`res.json(payload)`) - }) - - let port = 4000 - let host = "localhost" - - Http.listen(httpServer, {"port": port, "host": host}, () => { - Console.log(`🚀 GraphQL API Server ready at http://${host}:${Int.toString(port)}/graphql`) - }) -} - -let _ = startServer() diff --git a/praxis/SymbolicEngine/graphql/src/Server.res.js b/praxis/SymbolicEngine/graphql/src/Server.res.js index 29bdb17..b3e92db 100644 --- a/praxis/SymbolicEngine/graphql/src/Server.res.js +++ b/praxis/SymbolicEngine/graphql/src/Server.res.js @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE import * as Http from "http"; import Express from "express"; diff --git a/praxis/SymbolicEngine/graphql/src/auth/Jwt.res b/praxis/SymbolicEngine/graphql/src/auth/Jwt.res deleted file mode 100644 index ddc34a8..0000000 --- a/praxis/SymbolicEngine/graphql/src/auth/Jwt.res +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * JWT Authentication for Praxis GraphQL - * Fully ported to ReScript v12 - */ - -module Types = { - type authUser = { - id: string, - username: string, - roles: array, - permissions: array, - } -} - -module Jwt = { - @module("jsonwebtoken") - external verify: (string, string) => JSON.t = "verify" - - @module("jsonwebtoken") - external sign: (JSON.t, string, {"expiresIn": string}) => string = "sign" -} - -module Node = { - module Http = { - type incomingMessage = {headers: {"authorization": option}} - } -} - -let jwtSecret = switch %raw(`process.env.JWT_SECRET`) { -| s if %raw(`typeof s === 'string'`) => (s :> string) -| _ => "wp-praxis-secret-change-in-production" -} - -let jwtExpiresIn = switch %raw(`process.env.JWT_EXPIRES_IN`) { -| s if %raw(`typeof s === 'string'`) => (s :> string) -| _ => "24h" -} - -let extractToken = (req: Node.Http.incomingMessage): option => { - switch req.headers["authorization"] { - | None => None - | Some(authHeader) => - if String.startsWith(authHeader, "Bearer ") { - Some(String.substring(authHeader, ~start=7, ~end=String.length(authHeader))) - } else { - Some(authHeader) - } - } -} - -let verifyToken = async (token: string): option => { - try { - let decoded = Jwt.verify(token, jwtSecret) - let dict = JSON.Decode.object(decoded)->Option.getExn - - Some({ - id: switch (Dict.get(dict, "id"), Dict.get(dict, "sub")) { - | (Some(id), _) => JSON.Decode.string(id)->Option.getOr("") - | (_, Some(sub)) => JSON.Decode.string(sub)->Option.getOr("") - | _ => "" - }, - username: Dict.get(dict, "username") - ->Option.flatMap(JSON.Decode.string) - ->Option.getOr(""), - roles: Dict.get(dict, "roles") - ->Option.flatMap(JSON.Decode.array) - ->Option.getOr([]) - ->Array.map(v => JSON.Decode.string(v)->Option.getOr("")), - permissions: Dict.get(dict, "permissions") - ->Option.flatMap(JSON.Decode.array) - ->Option.getOr([]) - ->Array.map(v => JSON.Decode.string(v)->Option.getOr("")), - }) - } catch { - | _ => None - } -} - -let generateToken = (user: Types.authUser): string => { - let payload = JSON.Encode.object( - Dict.fromArray([ - ("sub", JSON.Encode.string(user.id)), - ("username", JSON.Encode.string(user.username)), - ("roles", JSON.Encode.array(user.roles->Array.map(JSON.Encode.string))), - ("permissions", JSON.Encode.array(user.permissions->Array.map(JSON.Encode.string))), - ]), - ) - - Jwt.sign(payload, jwtSecret, {"expiresIn": jwtExpiresIn}) -} diff --git a/praxis/SymbolicEngine/graphql/src/auth/Jwt.res.js b/praxis/SymbolicEngine/graphql/src/auth/Jwt.res.js index a929c4f..0d78543 100644 --- a/praxis/SymbolicEngine/graphql/src/auth/Jwt.res.js +++ b/praxis/SymbolicEngine/graphql/src/auth/Jwt.res.js @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// Generated by ReScript, PLEASE EDIT WITH CARE +// Generated by , PLEASE EDIT WITH CARE -import * as Core__JSON from "@rescript/core/src/Core__JSON.res.js"; -import * as Core__Option from "@rescript/core/src/Core__Option.res.js"; +import * as Core__JSON from "@/core/src/Core__JSON.res.js"; +import * as Core__Option from "@/core/src/Core__Option.res.js"; import * as Jsonwebtoken from "jsonwebtoken"; let Types = {}; diff --git a/praxis/SymbolicEngine/graphql/src/auth/jwt.ts b/praxis/SymbolicEngine/graphql/src/auth/jwt.ts deleted file mode 100644 index 16d698d..0000000 --- a/praxis/SymbolicEngine/graphql/src/auth/jwt.ts +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * JWT Authentication - * - * Handles JWT token creation, verification, and extraction - */ - -import jwt from 'jsonwebtoken'; -import type { IncomingMessage } from 'http'; -import type { AuthUser } from '../types.js'; - -const JWT_SECRET = process.env.JWT_SECRET || 'wp-praxis-secret-change-in-production'; -const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '24h'; - -export function extractToken(req: IncomingMessage): string | null { - const authHeader = req.headers.authorization; - - if (!authHeader) { - return null; - } - - // Support "Bearer " format - if (authHeader.startsWith('Bearer ')) { - return authHeader.substring(7); - } - - return authHeader; -} - -export async function verifyToken(token: string): Promise { - try { - const decoded = jwt.verify(token, JWT_SECRET) as any; - - return { - id: decoded.id || decoded.sub, - username: decoded.username, - roles: decoded.roles || [], - permissions: decoded.permissions || [], - }; - } catch (error) { - return null; - } -} - -export function generateToken(user: AuthUser): string { - return jwt.sign( - { - sub: user.id, - username: user.username, - roles: user.roles, - permissions: user.permissions, - }, - JWT_SECRET, - { expiresIn: JWT_EXPIRES_IN } - ); -} diff --git a/praxis/SymbolicEngine/graphql/src/auth/permissions.ts b/praxis/SymbolicEngine/graphql/src/auth/permissions.ts deleted file mode 100644 index cd7c5e0..0000000 --- a/praxis/SymbolicEngine/graphql/src/auth/permissions.ts +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Permission Checking - * - * Authorization helpers for GraphQL resolvers - */ - -import { AuthenticationError, AuthorizationError, type GraphQLContext } from '../types.js'; - -export function requireAuth(context: GraphQLContext): asserts context is GraphQLContext & { user: NonNullable } { - if (!context.user) { - throw new AuthenticationError('You must be logged in to perform this action'); - } -} - -export function requireRole(context: GraphQLContext, role: string): void { - requireAuth(context); - - if (!context.user.roles.includes(role) && !context.user.roles.includes('admin')) { - throw new AuthorizationError(`You must have the ${role} role to perform this action`); - } -} - -export function requirePermission(context: GraphQLContext, permission: string): void { - requireAuth(context); - - if (!context.user.permissions.includes(permission) && !context.user.roles.includes('admin')) { - throw new AuthorizationError(`You must have the ${permission} permission to perform this action`); - } -} - -export function hasPermission(context: GraphQLContext, permission: string): boolean { - if (!context.user) { - return false; - } - - return context.user.permissions.includes(permission) || context.user.roles.includes('admin'); -} - -export function isAdmin(context: GraphQLContext): boolean { - return context.user?.roles.includes('admin') ?? false; -} diff --git a/praxis/SymbolicEngine/graphql/src/context.ts b/praxis/SymbolicEngine/graphql/src/context.ts deleted file mode 100644 index 1b98617..0000000 --- a/praxis/SymbolicEngine/graphql/src/context.ts +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * GraphQL Context Builder - * - * Creates the context object for each GraphQL request - */ - -import type { IncomingMessage } from 'http'; -import type { PubSub } from 'graphql-subscriptions'; -import type { Logger } from 'winston'; -import DataLoader from 'dataloader'; - -import type { GraphQLContext } from './types.js'; -import { extractToken, verifyToken } from './auth/jwt.js'; -import { createDataLoaders } from './loaders/index.js'; - -interface CreateContextOptions { - req: IncomingMessage; - dataSources: any; - pubsub: PubSub; - logger: Logger; -} - -export async function createContext({ - req, - dataSources, - pubsub, - logger, -}: CreateContextOptions): Promise { - // Extract and verify authentication token - const token = extractToken(req); - let user = null; - - if (token) { - try { - user = await verifyToken(token); - } catch (error) { - logger.warn('Invalid authentication token:', error); - // Continue without user - some operations might not require auth - } - } - - // Create DataLoaders for this request - const loaders = createDataLoaders(dataSources); - - return { - user, - token, - dataSources, - loaders, - pubsub, - logger, - request: req, - }; -} diff --git a/praxis/SymbolicEngine/graphql/src/datasources/ecto-datasource.ts b/praxis/SymbolicEngine/graphql/src/datasources/ecto-datasource.ts deleted file mode 100644 index 1962477..0000000 --- a/praxis/SymbolicEngine/graphql/src/datasources/ecto-datasource.ts +++ /dev/null @@ -1,617 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Ecto/PostgreSQL Data Source - * - * Connects to the PostgreSQL database used by the Elixir Ecto schema - */ - -import pg from 'pg'; -import type { Logger } from 'winston'; -import type { - EctoDataSource, - SymbolModel, - WorkflowModel, - ExecutionModel, - BaselineModel, - AuditModel, - SymbolFilters, - WorkflowFilters, - ExecutionFilters, - BaselineFilters, - AuditFilters, -} from '../types.js'; - -const { Pool } = pg; - -export class EctoDataSourceImpl implements EctoDataSource { - private pool: pg.Pool; - private logger: Logger; - - constructor(logger: Logger) { - this.logger = logger; - this.pool = new Pool({ - host: process.env.DB_HOST || 'localhost', - port: parseInt(process.env.DB_PORT || '5432', 10), - database: process.env.DB_NAME || 'wp_praxis_dev', - user: process.env.DB_USER || 'postgres', - password: process.env.DB_PASSWORD || 'postgres', - max: 20, - idleTimeoutMillis: 30000, - connectionTimeoutMillis: 2000, - }); - - this.pool.on('error', (err) => { - this.logger.error('PostgreSQL pool error:', err); - }); - } - - async close(): Promise { - await this.pool.end(); - } - - // ============================================================================ - // Symbol Operations - // ============================================================================ - - async getSymbol(id: number): Promise { - const result = await this.pool.query( - 'SELECT * FROM symbols WHERE id = $1', - [id] - ); - return result.rows[0] || null; - } - - async getSymbolByName(name: string): Promise { - const result = await this.pool.query( - 'SELECT * FROM symbols WHERE name = $1', - [name] - ); - return result.rows[0] || null; - } - - async getSymbols(filters: SymbolFilters = {}): Promise { - const conditions: string[] = []; - const values: any[] = []; - let paramCount = 1; - - if (filters.type) { - conditions.push(`type = $${paramCount++}`); - values.push(filters.type); - } - - if (filters.context) { - conditions.push(`context = $${paramCount++}`); - values.push(filters.context); - } - - if (filters.status) { - conditions.push(`status = $${paramCount++}`); - values.push(filters.status); - } - - const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''; - const limit = filters.limit || 100; - const offset = filters.offset || 0; - - const query = ` - SELECT * FROM symbols - ${whereClause} - ORDER BY priority DESC, name ASC - LIMIT $${paramCount++} OFFSET $${paramCount++} - `; - - values.push(limit, offset); - - const result = await this.pool.query(query, values); - return result.rows; - } - - async createSymbol(input: any): Promise { - const result = await this.pool.query( - `INSERT INTO symbols - (name, type, context, dispatch_target, parameters, description, priority, timeout, retry_count, status) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) - RETURNING *`, - [ - input.name, - input.type, - input.context, - input.dispatchTarget, - JSON.stringify(input.parameters || {}), - input.description || null, - input.priority || 5, - input.timeout || 300, - input.retryCount || 0, - 'active', - ] - ); - return result.rows[0]; - } - - async updateSymbol(id: number, input: any): Promise { - const updates: string[] = []; - const values: any[] = []; - let paramCount = 1; - - if (input.name !== undefined) { - updates.push(`name = $${paramCount++}`); - values.push(input.name); - } - if (input.type !== undefined) { - updates.push(`type = $${paramCount++}`); - values.push(input.type); - } - if (input.context !== undefined) { - updates.push(`context = $${paramCount++}`); - values.push(input.context); - } - if (input.status !== undefined) { - updates.push(`status = $${paramCount++}`); - values.push(input.status); - } - if (input.dispatchTarget !== undefined) { - updates.push(`dispatch_target = $${paramCount++}`); - values.push(input.dispatchTarget); - } - if (input.parameters !== undefined) { - updates.push(`parameters = $${paramCount++}`); - values.push(JSON.stringify(input.parameters)); - } - if (input.description !== undefined) { - updates.push(`description = $${paramCount++}`); - values.push(input.description); - } - if (input.priority !== undefined) { - updates.push(`priority = $${paramCount++}`); - values.push(input.priority); - } - if (input.timeout !== undefined) { - updates.push(`timeout = $${paramCount++}`); - values.push(input.timeout); - } - if (input.retryCount !== undefined) { - updates.push(`retry_count = $${paramCount++}`); - values.push(input.retryCount); - } - - updates.push(`updated_at = NOW()`); - values.push(id); - - const query = ` - UPDATE symbols - SET ${updates.join(', ')} - WHERE id = $${paramCount} - RETURNING * - `; - - const result = await this.pool.query(query, values); - return result.rows[0]; - } - - async deleteSymbol(id: number): Promise { - const result = await this.pool.query('DELETE FROM symbols WHERE id = $1', [id]); - return (result.rowCount ?? 0) > 0; - } - - // ============================================================================ - // Workflow Operations - // ============================================================================ - - async getWorkflow(id: number): Promise { - const result = await this.pool.query( - 'SELECT * FROM workflows WHERE id = $1', - [id] - ); - return result.rows[0] || null; - } - - async getWorkflows(filters: WorkflowFilters = {}): Promise { - const conditions: string[] = []; - const values: any[] = []; - let paramCount = 1; - - if (filters.status) { - conditions.push(`status = $${paramCount++}`); - values.push(filters.status); - } - - const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''; - const limit = filters.limit || 100; - const offset = filters.offset || 0; - - const query = ` - SELECT * FROM workflows - ${whereClause} - ORDER BY inserted_at DESC - LIMIT $${paramCount++} OFFSET $${paramCount++} - `; - - values.push(limit, offset); - - const result = await this.pool.query(query, values); - return result.rows; - } - - async createWorkflow(input: any): Promise { - const result = await this.pool.query( - `INSERT INTO workflows (name, description, manifest_path, metadata, status) - VALUES ($1, $2, $3, $4, $5) - RETURNING *`, - [ - input.name, - input.description || null, - input.manifestPath, - JSON.stringify(input.metadata || {}), - 'pending', - ] - ); - return result.rows[0]; - } - - async updateWorkflow(id: number, updates: any): Promise { - const setClauses: string[] = []; - const values: any[] = []; - let paramCount = 1; - - Object.entries(updates).forEach(([key, value]) => { - setClauses.push(`${key} = $${paramCount++}`); - values.push(value); - }); - - setClauses.push(`updated_at = NOW()`); - values.push(id); - - const query = ` - UPDATE workflows - SET ${setClauses.join(', ')} - WHERE id = $${paramCount} - RETURNING * - `; - - const result = await this.pool.query(query, values); - return result.rows[0]; - } - - async deleteWorkflow(id: number): Promise { - const result = await this.pool.query('DELETE FROM workflows WHERE id = $1', [id]); - return (result.rowCount ?? 0) > 0; - } - - // ============================================================================ - // Execution Operations - // ============================================================================ - - async getExecution(id: number): Promise { - const result = await this.pool.query( - 'SELECT * FROM executions WHERE id = $1', - [id] - ); - return result.rows[0] || null; - } - - async getExecutions(filters: ExecutionFilters = {}): Promise { - const conditions: string[] = []; - const values: any[] = []; - let paramCount = 1; - - if (filters.workflowId) { - conditions.push(`workflow_id = $${paramCount++}`); - values.push(filters.workflowId); - } - - if (filters.symbolId) { - conditions.push(`symbol_id = $${paramCount++}`); - values.push(filters.symbolId); - } - - if (filters.status) { - conditions.push(`status = $${paramCount++}`); - values.push(filters.status); - } - - const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''; - const limit = filters.limit || 100; - const offset = filters.offset || 0; - - const query = ` - SELECT * FROM executions - ${whereClause} - ORDER BY inserted_at DESC - LIMIT $${paramCount++} OFFSET $${paramCount++} - `; - - values.push(limit, offset); - - const result = await this.pool.query(query, values); - return result.rows; - } - - async getExecutionsByWorkflow(workflowId: number): Promise { - const result = await this.pool.query( - 'SELECT * FROM executions WHERE workflow_id = $1 ORDER BY inserted_at ASC', - [workflowId] - ); - return result.rows; - } - - async getExecutionsBySymbol(symbolId: number): Promise { - const result = await this.pool.query( - 'SELECT * FROM executions WHERE symbol_id = $1 ORDER BY inserted_at DESC LIMIT 100', - [symbolId] - ); - return result.rows; - } - - async createExecution(input: any): Promise { - const result = await this.pool.query( - `INSERT INTO executions (workflow_id, symbol_id, status, metadata) - VALUES ($1, $2, $3, $4) - RETURNING *`, - [input.workflowId, input.symbolId, 'pending', JSON.stringify(input.metadata || {})] - ); - return result.rows[0]; - } - - async updateExecution(id: number, updates: any): Promise { - const setClauses: string[] = []; - const values: any[] = []; - let paramCount = 1; - - Object.entries(updates).forEach(([key, value]) => { - setClauses.push(`${key} = $${paramCount++}`); - values.push(value); - }); - - setClauses.push(`updated_at = NOW()`); - values.push(id); - - const query = ` - UPDATE executions - SET ${setClauses.join(', ')} - WHERE id = $${paramCount} - RETURNING * - `; - - const result = await this.pool.query(query, values); - return result.rows[0]; - } - - // ============================================================================ - // Baseline Operations - // ============================================================================ - - async getBaseline(id: number): Promise { - const result = await this.pool.query( - 'SELECT * FROM baselines WHERE id = $1', - [id] - ); - return result.rows[0] || null; - } - - async getBaselines(filters: BaselineFilters = {}): Promise { - const conditions: string[] = []; - const values: any[] = []; - let paramCount = 1; - - if (filters.active !== undefined) { - conditions.push(`is_active = $${paramCount++}`); - values.push(filters.active); - } - - if (filters.baselineType) { - conditions.push(`baseline_type = $${paramCount++}`); - values.push(filters.baselineType); - } - - if (filters.scope) { - conditions.push(`scope = $${paramCount++}`); - values.push(filters.scope); - } - - const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''; - const limit = filters.limit || 100; - const offset = filters.offset || 0; - - const query = ` - SELECT * FROM baselines - ${whereClause} - ORDER BY inserted_at DESC - LIMIT $${paramCount++} OFFSET $${paramCount++} - `; - - values.push(limit, offset); - - const result = await this.pool.query(query, values); - return result.rows; - } - - async createBaseline(input: any): Promise { - const result = await this.pool.query( - `INSERT INTO baselines - (name, description, symbolic_state, version, baseline_type, scope, created_by, metadata) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8) - RETURNING *`, - [ - input.name, - input.description || null, - JSON.stringify(input.symbolicState), - input.version || '1.0.0', - input.baselineType || 'system', - input.scope || 'global', - input.createdBy || null, - JSON.stringify(input.metadata || {}), - ] - ); - return result.rows[0]; - } - - async updateBaseline(id: number, updates: any): Promise { - const setClauses: string[] = []; - const values: any[] = []; - let paramCount = 1; - - Object.entries(updates).forEach(([key, value]) => { - setClauses.push(`${key} = $${paramCount++}`); - values.push(value); - }); - - setClauses.push(`updated_at = NOW()`); - values.push(id); - - const query = ` - UPDATE baselines - SET ${setClauses.join(', ')} - WHERE id = $${paramCount} - RETURNING * - `; - - const result = await this.pool.query(query, values); - return result.rows[0]; - } - - async deleteBaseline(id: number): Promise { - const result = await this.pool.query('DELETE FROM baselines WHERE id = $1', [id]); - return (result.rowCount ?? 0) > 0; - } - - // ============================================================================ - // Audit Operations - // ============================================================================ - - async getAudit(id: number): Promise { - const result = await this.pool.query( - 'SELECT * FROM audits WHERE id = $1', - [id] - ); - return result.rows[0] || null; - } - - async getAudits(filters: AuditFilters = {}): Promise { - const conditions: string[] = []; - const values: any[] = []; - let paramCount = 1; - - if (filters.baselineId) { - conditions.push(`baseline_id = $${paramCount++}`); - values.push(filters.baselineId); - } - - if (filters.severity) { - conditions.push(`severity = $${paramCount++}`); - values.push(filters.severity); - } - - if (filters.status) { - conditions.push(`status = $${paramCount++}`); - values.push(filters.status); - } - - const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''; - const limit = filters.limit || 100; - const offset = filters.offset || 0; - - const query = ` - SELECT * FROM audits - ${whereClause} - ORDER BY inserted_at DESC - LIMIT $${paramCount++} OFFSET $${paramCount++} - `; - - values.push(limit, offset); - - const result = await this.pool.query(query, values); - return result.rows; - } - - async createAudit(input: any): Promise { - const result = await this.pool.query( - `INSERT INTO audits (baseline_id, workflow_id, audit_type, metadata) - VALUES ($1, $2, $3, $4) - RETURNING *`, - [ - input.baselineId, - input.workflowId || null, - input.auditType || 'manual', - JSON.stringify(input.metadata || {}), - ] - ); - return result.rows[0]; - } - - async updateAudit(id: number, updates: any): Promise { - const setClauses: string[] = []; - const values: any[] = []; - let paramCount = 1; - - Object.entries(updates).forEach(([key, value]) => { - setClauses.push(`${key} = $${paramCount++}`); - values.push(value); - }); - - setClauses.push(`updated_at = NOW()`); - values.push(id); - - const query = ` - UPDATE audits - SET ${setClauses.join(', ')} - WHERE id = $${paramCount} - RETURNING * - `; - - const result = await this.pool.query(query, values); - return result.rows[0]; - } - - // ============================================================================ - // Statistics - // ============================================================================ - - async getSymbolStats(): Promise { - const [typeStats, contextStats, statusStats, total] = await Promise.all([ - this.pool.query('SELECT type, COUNT(*) as count FROM symbols GROUP BY type'), - this.pool.query('SELECT context, COUNT(*) as count FROM symbols GROUP BY context'), - this.pool.query('SELECT status, COUNT(*) as count FROM symbols GROUP BY status'), - this.pool.query('SELECT COUNT(*) as total FROM symbols'), - ]); - - return { - total: parseInt(total.rows[0]?.total || '0', 10), - byType: typeStats.rows, - byContext: contextStats.rows, - byStatus: statusStats.rows, - }; - } - - async getWorkflowStats(): Promise { - const stats = await this.pool.query(` - SELECT - COUNT(*) as total, - COUNT(*) FILTER (WHERE status = 'pending') as pending, - COUNT(*) FILTER (WHERE status = 'running') as running, - COUNT(*) FILTER (WHERE status = 'completed') as completed, - COUNT(*) FILTER (WHERE status = 'failed') as failed, - AVG(duration) FILTER (WHERE duration IS NOT NULL) as average_duration, - (COUNT(*) FILTER (WHERE status = 'completed')::float / NULLIF(COUNT(*), 0)) as success_rate - FROM workflows - `); - - return stats.rows[0]; - } - - async getExecutionStats(): Promise { - const stats = await this.pool.query(` - SELECT - COUNT(*) as total, - COUNT(*) FILTER (WHERE status = 'pending') as pending, - COUNT(*) FILTER (WHERE status = 'running') as running, - COUNT(*) FILTER (WHERE status = 'completed') as completed, - COUNT(*) FILTER (WHERE status = 'failed') as failed, - AVG(duration) FILTER (WHERE duration IS NOT NULL) as average_duration, - (COUNT(*) FILTER (WHERE status = 'completed')::float / NULLIF(COUNT(*), 0)) as success_rate - FROM executions - `); - - return stats.rows[0]; - } -} diff --git a/praxis/SymbolicEngine/graphql/src/datasources/index.ts b/praxis/SymbolicEngine/graphql/src/datasources/index.ts deleted file mode 100644 index 41067e1..0000000 --- a/praxis/SymbolicEngine/graphql/src/datasources/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Data Sources Index - * - * Creates and exports all data sources - */ - -import type { Logger } from 'winston'; -import { EctoDataSourceImpl } from './ecto-datasource.js'; -import { SwarmDataSourceImpl } from './swarm-datasource.js'; -import { PowerShellDataSourceImpl } from './powershell-datasource.js'; -import { InjectorDataSourceImpl } from './injector-datasource.js'; - -export async function createDataSources(logger: Logger) { - return { - ecto: new EctoDataSourceImpl(logger), - swarm: new SwarmDataSourceImpl(logger), - powershell: new PowerShellDataSourceImpl(logger), - injector: new InjectorDataSourceImpl(logger), - }; -} - -export { EctoDataSourceImpl, SwarmDataSourceImpl, PowerShellDataSourceImpl, InjectorDataSourceImpl }; diff --git a/praxis/SymbolicEngine/graphql/src/datasources/injector-datasource.ts b/praxis/SymbolicEngine/graphql/src/datasources/injector-datasource.ts deleted file mode 100644 index e44aa64..0000000 --- a/praxis/SymbolicEngine/graphql/src/datasources/injector-datasource.ts +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Injector Data Source - * - * Executes Rust injector binary - */ - -import { spawn } from 'child_process'; -import type { Logger } from 'winston'; -import type { InjectorDataSource } from '../types.js'; - -export class InjectorDataSourceImpl implements InjectorDataSource { - private logger: Logger; - private binaryPath: string; - - constructor(logger: Logger) { - this.logger = logger; - this.binaryPath = process.env.INJECTOR_BINARY_PATH || '../../wp_injector/target/release/wp_injector'; - } - - async getInjectorStatus(): Promise { - try { - const result = await this.execInjector(['--version']); - return { - available: true, - version: result.output, - }; - } catch (error) { - this.logger.error('Injector not available:', error); - return { - available: false, - error: String(error), - }; - } - } - - async executeInjection(symbolId: number, params: Record): Promise { - const args = [ - 'inject', - '--symbol-id', - String(symbolId), - '--params', - JSON.stringify(params), - ]; - - return this.execInjector(args); - } - - private execInjector(args: string[]): Promise { - return new Promise((resolve, reject) => { - const child = spawn(this.binaryPath, args); - - let stdout = ''; - let stderr = ''; - - child.stdout.on('data', (data) => { - stdout += data.toString(); - }); - - child.stderr.on('data', (data) => { - stderr += data.toString(); - }); - - child.on('close', (code) => { - if (code === 0) { - try { - const output = JSON.parse(stdout); - resolve(output); - } catch { - resolve({ output: stdout }); - } - } else { - reject(new Error(`Injector exited with code ${code}: ${stderr}`)); - } - }); - - child.on('error', (error) => { - reject(error); - }); - }); - } -} diff --git a/praxis/SymbolicEngine/graphql/src/datasources/powershell-datasource.ts b/praxis/SymbolicEngine/graphql/src/datasources/powershell-datasource.ts deleted file mode 100644 index 4dcea85..0000000 --- a/praxis/SymbolicEngine/graphql/src/datasources/powershell-datasource.ts +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * PowerShell Data Source - * - * Executes PowerShell symbolic engine scripts - */ - -import { spawn } from 'child_process'; -import { promisify } from 'util'; -import { exec } from 'child_process'; -import type { Logger } from 'winston'; -import type { PowerShellDataSource } from '../types.js'; - -const execAsync = promisify(exec); - -export class PowerShellDataSourceImpl implements PowerShellDataSource { - private logger: Logger; - private pwshBinary: string; - private scriptPath: string; - - constructor(logger: Logger) { - this.logger = logger; - this.pwshBinary = process.env.PWSH_BINARY || 'pwsh'; - this.scriptPath = process.env.SYMBOLIC_ENGINE_PATH || '../core'; - } - - async executeScript(script: string, params: Record = {}): Promise { - try { - const paramString = Object.entries(params) - .map(([key, value]) => `-${key} "${value}"`) - .join(' '); - - const command = `${this.pwshBinary} -File "${script}" ${paramString}`; - - this.logger.debug('Executing PowerShell script:', { command }); - - const { stdout, stderr } = await execAsync(command, { - timeout: 60000, // 60 second timeout - }); - - if (stderr) { - this.logger.warn('PowerShell stderr:', stderr); - } - - // Try to parse JSON output - try { - return JSON.parse(stdout); - } catch { - return { output: stdout }; - } - } catch (error) { - this.logger.error('PowerShell execution error:', error); - throw error; - } - } - - async runSymbolicAudit(baselineId: number, workflowId?: number): Promise { - const script = `${this.scriptPath}/Run-SymbolicAudit.ps1`; - const params: Record = { BaselineId: baselineId }; - - if (workflowId) { - params.WorkflowId = workflowId; - } - - return this.executeScript(script, params); - } - - async setBaseline(baselineId: number): Promise { - const script = `${this.scriptPath}/Set-NormativeBaseline.ps1`; - const params = { BaselineId: baselineId }; - - try { - await this.executeScript(script, params); - return true; - } catch (error) { - this.logger.error('Failed to set baseline:', error); - return false; - } - } - - async visualizeDiff(baseline1: number, baseline2: number): Promise { - const script = `${this.scriptPath}/Visualize-SymbolicDiff.ps1`; - const params = { - Baseline1: baseline1, - Baseline2: baseline2, - }; - - return this.executeScript(script, params); - } -} diff --git a/praxis/SymbolicEngine/graphql/src/datasources/swarm-datasource.ts b/praxis/SymbolicEngine/graphql/src/datasources/swarm-datasource.ts deleted file mode 100644 index 41ab0d2..0000000 --- a/praxis/SymbolicEngine/graphql/src/datasources/swarm-datasource.ts +++ /dev/null @@ -1,184 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Swarm Data Source - * - * Connects to the swarm coordinator for node and task information - */ - -import Database from 'better-sqlite3'; -import type { Logger } from 'winston'; -import type { - SwarmDataSource, - NodeModel, - TaskModel, - NodeFilters, - TaskFilters, -} from '../types.js'; - -export class SwarmDataSourceImpl implements SwarmDataSource { - private db: Database.Database; - private logger: Logger; - - constructor(logger: Logger) { - this.logger = logger; - const dbPath = process.env.SWARM_DB_PATH || '../swarm/swarm-state.db'; - this.db = new Database(dbPath, { readonly: true }); - } - - async getNode(id: string): Promise { - try { - const stmt = this.db.prepare('SELECT * FROM nodes WHERE id = ?'); - const row = stmt.get(id) as any; - return row ? this.parseNode(row) : null; - } catch (error) { - this.logger.error('Error fetching node:', error); - return null; - } - } - - async getNodes(filters: NodeFilters = {}): Promise { - const conditions: string[] = []; - const values: any[] = []; - - if (filters.status) { - conditions.push('status = ?'); - values.push(filters.status); - } - - const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''; - const limit = filters.limit || 100; - const offset = filters.offset || 0; - - const query = ` - SELECT * FROM nodes - ${whereClause} - ORDER BY connectedAt DESC - LIMIT ? OFFSET ? - `; - - try { - const stmt = this.db.prepare(query); - const rows = stmt.all(...values, limit, offset) as any[]; - return rows.map((row) => this.parseNode(row)); - } catch (error) { - this.logger.error('Error fetching nodes:', error); - return []; - } - } - - async getTask(id: string): Promise { - try { - const stmt = this.db.prepare('SELECT * FROM tasks WHERE id = ?'); - const row = stmt.get(id) as any; - return row ? this.parseTask(row) : null; - } catch (error) { - this.logger.error('Error fetching task:', error); - return null; - } - } - - async getTasks(filters: TaskFilters = {}): Promise { - const conditions: string[] = []; - const values: any[] = []; - - if (filters.nodeId) { - conditions.push('assignedTo = ?'); - values.push(filters.nodeId); - } - - if (filters.status) { - conditions.push('status = ?'); - values.push(filters.status); - } - - const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : ''; - const limit = filters.limit || 100; - const offset = filters.offset || 0; - - const query = ` - SELECT * FROM tasks - ${whereClause} - ORDER BY priority DESC, createdAt DESC - LIMIT ? OFFSET ? - `; - - try { - const stmt = this.db.prepare(query); - const rows = stmt.all(...values, limit, offset) as any[]; - return rows.map((row) => this.parseTask(row)); - } catch (error) { - this.logger.error('Error fetching tasks:', error); - return []; - } - } - - async getNodeStats(): Promise { - try { - const total = this.db.prepare('SELECT COUNT(*) as count FROM nodes').get() as any; - const online = this.db.prepare("SELECT COUNT(*) as count FROM nodes WHERE status IN ('idle', 'busy')").get() as any; - const offline = this.db.prepare("SELECT COUNT(*) as count FROM nodes WHERE status = 'offline'").get() as any; - - const capacityStmt = this.db.prepare(` - SELECT SUM(json_extract(capabilities, '$.maxConcurrentTasks')) as totalCapacity - FROM nodes - WHERE status IN ('idle', 'busy') - `); - const capacity = capacityStmt.get() as any; - - const activeTasksStmt = this.db.prepare(` - SELECT SUM(json_extract(health, '$.activeTasks')) as activeTasks - FROM nodes - WHERE status IN ('idle', 'busy') - `); - const activeTasks = activeTasksStmt.get() as any; - - const totalCapacity = parseInt(capacity?.totalCapacity || '0', 10); - const activeTaskCount = parseInt(activeTasks?.activeTasks || '0', 10); - - return { - total: total.count, - online: online.count, - offline: offline.count, - totalCapacity, - utilizationRate: totalCapacity > 0 ? activeTaskCount / totalCapacity : 0, - }; - } catch (error) { - this.logger.error('Error fetching node stats:', error); - return { - total: 0, - online: 0, - offline: 0, - totalCapacity: 0, - utilizationRate: 0, - }; - } - } - - private parseNode(row: any): NodeModel { - return { - id: row.id, - name: row.name, - status: row.status, - capabilities: JSON.parse(row.capabilities), - health: JSON.parse(row.health), - lastHeartbeat: row.lastHeartbeat, - connectedAt: row.connectedAt, - metadata: row.metadata ? JSON.parse(row.metadata) : undefined, - }; - } - - private parseTask(row: any): TaskModel { - return { - id: row.id, - executionId: row.executionId, - symbol: JSON.parse(row.symbol), - priority: row.priority, - dependencies: JSON.parse(row.dependencies || '[]'), - status: row.status, - assignedTo: row.assignedTo || undefined, - createdAt: row.createdAt, - assignedAt: row.assignedAt || undefined, - }; - } -} diff --git a/praxis/SymbolicEngine/graphql/src/loaders/index.ts b/praxis/SymbolicEngine/graphql/src/loaders/index.ts deleted file mode 100644 index 8d768e8..0000000 --- a/praxis/SymbolicEngine/graphql/src/loaders/index.ts +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * DataLoader Configuration - * - * Creates DataLoaders for batching and caching database queries - */ - -import DataLoader from 'dataloader'; -import type { - SymbolModel, - WorkflowModel, - ExecutionModel, - BaselineModel, - AuditModel, - NodeModel, - TaskModel, -} from '../types.js'; - -export function createDataLoaders(dataSources: any) { - return { - // Symbol loader - batch load symbols by ID - symbolLoader: new DataLoader( - async (ids) => { - const symbols = await Promise.all( - ids.map((id) => dataSources.ecto.getSymbol(id)) - ); - return symbols; - }, - { - cache: true, - batchScheduleFn: (callback) => setTimeout(callback, 10), - } - ), - - // Workflow loader - batch load workflows by ID - workflowLoader: new DataLoader( - async (ids) => { - const workflows = await Promise.all( - ids.map((id) => dataSources.ecto.getWorkflow(id)) - ); - return workflows; - }, - { - cache: true, - batchScheduleFn: (callback) => setTimeout(callback, 10), - } - ), - - // Execution loader - batch load executions by ID - executionLoader: new DataLoader( - async (ids) => { - const executions = await Promise.all( - ids.map((id) => dataSources.ecto.getExecution(id)) - ); - return executions; - }, - { - cache: true, - batchScheduleFn: (callback) => setTimeout(callback, 10), - } - ), - - // Baseline loader - batch load baselines by ID - baselineLoader: new DataLoader( - async (ids) => { - const baselines = await Promise.all( - ids.map((id) => dataSources.ecto.getBaseline(id)) - ); - return baselines; - }, - { - cache: true, - batchScheduleFn: (callback) => setTimeout(callback, 10), - } - ), - - // Audit loader - batch load audits by ID - auditLoader: new DataLoader( - async (ids) => { - const audits = await Promise.all( - ids.map((id) => dataSources.ecto.getAudit(id)) - ); - return audits; - }, - { - cache: true, - batchScheduleFn: (callback) => setTimeout(callback, 10), - } - ), - - // Node loader - batch load nodes by ID - nodeLoader: new DataLoader( - async (ids) => { - const nodes = await Promise.all( - ids.map((id) => dataSources.swarm.getNode(id)) - ); - return nodes; - }, - { - cache: true, - batchScheduleFn: (callback) => setTimeout(callback, 10), - } - ), - - // Task loader - batch load tasks by ID - taskLoader: new DataLoader( - async (ids) => { - const tasks = await Promise.all( - ids.map((id) => dataSources.swarm.getTask(id)) - ); - return tasks; - }, - { - cache: true, - batchScheduleFn: (callback) => setTimeout(callback, 10), - } - ), - }; -} diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/audit-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/audit-resolvers.ts deleted file mode 100644 index 66522e2..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/audit-resolvers.ts +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Audit Resolvers - * - * GraphQL resolvers for Audit queries and mutations - */ - -import type { GraphQLContext } from '../types.js'; -import { requirePermission } from '../auth/permissions.js'; -import { SUBSCRIPTION_TOPICS } from '../types.js'; - -export const auditResolvers = { - Query: { - audit: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - const id = parseInt(args.id, 10); - return context.loaders.auditLoader.load(id); - }, - - audits: async (_parent: any, args: any, context: GraphQLContext) => { - return context.dataSources.ecto.getAudits({ - baselineId: args.baselineId ? parseInt(args.baselineId, 10) : undefined, - severity: args.severity?.toLowerCase(), - status: args.status?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - - auditsConnection: async (_parent: any, args: any, context: GraphQLContext) => { - const limit = args.first || args.last || 20; - const offset = args.after ? parseInt(Buffer.from(args.after, 'base64').toString(), 10) : 0; - - const audits = await context.dataSources.ecto.getAudits({ - baselineId: args.baselineId ? parseInt(args.baselineId, 10) : undefined, - severity: args.severity?.toLowerCase(), - status: args.status?.toLowerCase(), - limit: limit + 1, - offset, - }); - - const hasNextPage = audits.length > limit; - const edges = audits.slice(0, limit).map((node, index) => ({ - node, - cursor: Buffer.from(String(offset + index)).toString('base64'), - })); - - return { - edges, - pageInfo: { - hasNextPage, - hasPreviousPage: offset > 0, - startCursor: edges[0]?.cursor, - endCursor: edges[edges.length - 1]?.cursor, - total: edges.length, - }, - }; - }, - }, - - Mutation: { - runAudit: async (_parent: any, args: { input: any }, context: GraphQLContext) => { - requirePermission(context, 'audits:run'); - - const baselineId = parseInt(args.input.baselineId, 10); - const workflowId = args.input.workflowId ? parseInt(args.input.workflowId, 10) : undefined; - - // Create audit record - const audit = await context.dataSources.ecto.createAudit({ - baselineId, - workflowId, - auditType: args.input.auditType || 'manual', - metadata: args.input.metadata || {}, - }); - - // Update audit to running - await context.dataSources.ecto.updateAudit(audit.id, { - status: 'running', - started_at: new Date(), - }); - - // Execute PowerShell audit script asynchronously - context.dataSources.powershell - .runSymbolicAudit(baselineId, workflowId) - .then(async (result) => { - // Update audit with results - await context.dataSources.ecto.updateAudit(audit.id, { - status: 'completed', - completed_at: new Date(), - deviations: result.deviations || [], - deviation_count: result.deviations?.length || 0, - severity: result.severity || 'info', - passed_checks: result.passedChecks || 0, - failed_checks: result.failedChecks || 0, - recommendations: result.recommendations || [], - }); - - const completedAudit = await context.dataSources.ecto.getAudit(audit.id); - context.pubsub.publish(SUBSCRIPTION_TOPICS.AUDIT_COMPLETED, { auditCompleted: completedAudit }); - - if (result.severity === 'error' || result.severity === 'critical') { - context.pubsub.publish(SUBSCRIPTION_TOPICS.AUDIT_DEVIATION_DETECTED, { - auditDeviationDetected: completedAudit, - }); - } - }) - .catch(async (error) => { - context.logger.error('Audit execution failed:', error); - await context.dataSources.ecto.updateAudit(audit.id, { - status: 'failed', - completed_at: new Date(), - metadata: { error: String(error) }, - }); - }); - - return audit; - }, - - cancelAudit: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'audits:cancel'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.updateAudit(id, { - status: 'cancelled', - completed_at: new Date(), - }); - }, - }, - - Audit: { - id: (audit: any) => String(audit.id), - auditType: (audit: any) => audit.audit_type?.toUpperCase(), - status: (audit: any) => audit.status?.toUpperCase(), - severity: (audit: any) => audit.severity?.toUpperCase(), - deviationCount: (audit: any) => audit.deviation_count, - passedChecks: (audit: any) => audit.passed_checks, - failedChecks: (audit: any) => audit.failed_checks, - createdAt: (audit: any) => audit.inserted_at, - updatedAt: (audit: any) => audit.updated_at, - startedAt: (audit: any) => audit.started_at, - completedAt: (audit: any) => audit.completed_at, - - baseline: async (audit: any, _args: any, context: GraphQLContext) => { - return context.loaders.baselineLoader.load(audit.baseline_id); - }, - - workflow: async (audit: any, _args: any, context: GraphQLContext) => { - if (audit.workflow_id) { - return context.loaders.workflowLoader.load(audit.workflow_id); - } - return null; - }, - - deviations: (audit: any) => { - return audit.deviations.map((d: any) => ({ - path: d.path, - expected: d.expected, - actual: d.actual, - severity: d.severity?.toUpperCase(), - message: d.message, - })); - }, - - recommendations: (audit: any) => audit.recommendations, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/baseline-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/baseline-resolvers.ts deleted file mode 100644 index aa203d8..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/baseline-resolvers.ts +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Baseline Resolvers - * - * GraphQL resolvers for Baseline queries and mutations - */ - -import type { GraphQLContext } from '../types.js'; -import { requirePermission } from '../auth/permissions.js'; - -export const baselineResolvers = { - Query: { - baseline: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - const id = parseInt(args.id, 10); - return context.loaders.baselineLoader.load(id); - }, - - baselines: async (_parent: any, args: any, context: GraphQLContext) => { - return context.dataSources.ecto.getBaselines({ - active: args.active, - baselineType: args.baselineType?.toLowerCase(), - scope: args.scope?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - }, - - Mutation: { - createBaseline: async (_parent: any, args: { input: any }, context: GraphQLContext) => { - requirePermission(context, 'baselines:write'); - return context.dataSources.ecto.createBaseline(args.input); - }, - - activateBaseline: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'baselines:activate'); - const id = parseInt(args.id, 10); - - // Deactivate all other baselines first - const baselines = await context.dataSources.ecto.getBaselines({ active: true }); - await Promise.all( - baselines.map((b) => context.dataSources.ecto.updateBaseline(b.id, { is_active: false })) - ); - - // Activate the target baseline - const baseline = await context.dataSources.ecto.updateBaseline(id, { is_active: true }); - - // Call PowerShell script to set baseline - await context.dataSources.powershell.setBaseline(id); - - return baseline; - }, - - deactivateBaseline: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'baselines:activate'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.updateBaseline(id, { is_active: false }); - }, - - deleteBaseline: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'baselines:delete'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.deleteBaseline(id); - }, - }, - - Baseline: { - id: (baseline: any) => String(baseline.id), - symbolicState: (baseline: any) => baseline.symbolic_state, - isActive: (baseline: any) => baseline.is_active, - baselineType: (baseline: any) => baseline.baseline_type?.toUpperCase(), - scope: (baseline: any) => baseline.scope?.toUpperCase(), - createdBy: (baseline: any) => baseline.created_by, - createdAt: (baseline: any) => baseline.inserted_at, - updatedAt: (baseline: any) => baseline.updated_at, - - audits: async (baseline: any, args: any, context: GraphQLContext) => { - return context.dataSources.ecto.getAudits({ - baselineId: baseline.id, - limit: args.limit, - offset: args.offset, - }); - }, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/execution-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/execution-resolvers.ts deleted file mode 100644 index 99fc4cf..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/execution-resolvers.ts +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Execution Resolvers - * - * GraphQL resolvers for Execution queries and mutations - */ - -import type { GraphQLContext } from '../types.js'; -import { requirePermission } from '../auth/permissions.js'; -import { SUBSCRIPTION_TOPICS } from '../types.js'; - -export const executionResolvers = { - Query: { - execution: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - const id = parseInt(args.id, 10); - return context.loaders.executionLoader.load(id); - }, - - executions: async (_parent: any, args: any, context: GraphQLContext) => { - return context.dataSources.ecto.getExecutions({ - workflowId: args.workflowId ? parseInt(args.workflowId, 10) : undefined, - symbolId: args.symbolId ? parseInt(args.symbolId, 10) : undefined, - status: args.status?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - - executionsConnection: async (_parent: any, args: any, context: GraphQLContext) => { - const limit = args.first || args.last || 20; - const offset = args.after ? parseInt(Buffer.from(args.after, 'base64').toString(), 10) : 0; - - const executions = await context.dataSources.ecto.getExecutions({ - workflowId: args.workflowId ? parseInt(args.workflowId, 10) : undefined, - symbolId: args.symbolId ? parseInt(args.symbolId, 10) : undefined, - status: args.status?.toLowerCase(), - limit: limit + 1, - offset, - }); - - const hasNextPage = executions.length > limit; - const edges = executions.slice(0, limit).map((node, index) => ({ - node, - cursor: Buffer.from(String(offset + index)).toString('base64'), - })); - - return { - edges, - pageInfo: { - hasNextPage, - hasPreviousPage: offset > 0, - startCursor: edges[0]?.cursor, - endCursor: edges[edges.length - 1]?.cursor, - total: edges.length, - }, - }; - }, - }, - - Mutation: { - retryExecution: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'executions:retry'); - const id = parseInt(args.id, 10); - - const execution = await context.dataSources.ecto.updateExecution(id, { - status: 'retrying', - retry_attempt: context.dataSources.ecto.getExecution(id).then((e) => (e?.retry_attempt || 0) + 1), - }); - - context.pubsub.publish(SUBSCRIPTION_TOPICS.EXECUTION_UPDATED, { executionUpdated: execution }); - - return execution; - }, - - cancelExecution: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'executions:cancel'); - const id = parseInt(args.id, 10); - - const execution = await context.dataSources.ecto.updateExecution(id, { - status: 'cancelled', - completed_at: new Date(), - }); - - context.pubsub.publish(SUBSCRIPTION_TOPICS.EXECUTION_UPDATED, { executionUpdated: execution }); - - return execution; - }, - - rollbackExecution: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'executions:rollback'); - const id = parseInt(args.id, 10); - - const execution = await context.dataSources.ecto.updateExecution(id, { - status: 'rolled_back', - completed_at: new Date(), - }); - - context.pubsub.publish(SUBSCRIPTION_TOPICS.EXECUTION_UPDATED, { executionUpdated: execution }); - - return execution; - }, - }, - - Execution: { - id: (execution: any) => String(execution.id), - status: (execution: any) => execution.status?.toUpperCase(), - attempts: (execution: any) => execution.retry_attempt, - exitCode: (execution: any) => execution.exit_code, - rollbackState: (execution: any) => execution.rollback_state, - createdAt: (execution: any) => execution.inserted_at, - updatedAt: (execution: any) => execution.updated_at, - startedAt: (execution: any) => execution.started_at, - completedAt: (execution: any) => execution.completed_at, - - workflow: async (execution: any, _args: any, context: GraphQLContext) => { - return context.loaders.workflowLoader.load(execution.workflow_id); - }, - - symbol: async (execution: any, _args: any, context: GraphQLContext) => { - return context.loaders.symbolLoader.load(execution.symbol_id); - }, - - node: async (execution: any, _args: any, context: GraphQLContext) => { - // Get node from execution metadata if available - const nodeId = execution.metadata?.nodeId; - if (nodeId) { - return context.loaders.nodeLoader.load(nodeId); - } - return null; - }, - - result: (execution: any) => { - if (execution.status === 'completed' || execution.status === 'failed') { - return { - success: execution.status === 'completed', - output: execution.output, - error: execution.error_log, - stackTrace: execution.metadata?.stackTrace, - duration: execution.duration || 0, - timestamp: execution.completed_at || execution.updated_at, - metadata: execution.metadata, - }; - } - return null; - }, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/index.ts b/praxis/SymbolicEngine/graphql/src/resolvers/index.ts deleted file mode 100644 index b1025b1..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Resolvers Index - * - * Combines all GraphQL resolvers into a single export - */ - -import { GraphQLDateTime, GraphQLJSON, GraphQLJSONObject } from 'graphql-scalars'; -import { symbolResolvers } from './symbol-resolvers.js'; -import { workflowResolvers } from './workflow-resolvers.js'; -import { executionResolvers } from './execution-resolvers.js'; -import { baselineResolvers } from './baseline-resolvers.js'; -import { auditResolvers } from './audit-resolvers.js'; -import { nodeResolvers } from './node-resolvers.js'; -import { statsResolvers } from './stats-resolvers.js'; -import { subscriptionResolvers } from './subscription-resolvers.js'; - -export const resolvers = { - // Scalar types - DateTime: GraphQLDateTime, - JSON: GraphQLJSON, - JSONObject: GraphQLJSONObject, - - // Query resolvers - Query: { - ...symbolResolvers.Query, - ...workflowResolvers.Query, - ...executionResolvers.Query, - ...baselineResolvers.Query, - ...auditResolvers.Query, - ...nodeResolvers.Query, - ...statsResolvers.Query, - }, - - // Mutation resolvers - Mutation: { - ...symbolResolvers.Mutation, - ...workflowResolvers.Mutation, - ...executionResolvers.Mutation, - ...baselineResolvers.Mutation, - ...auditResolvers.Mutation, - ...nodeResolvers.Mutation, - }, - - // Subscription resolvers - Subscription: { - ...subscriptionResolvers.Subscription, - }, - - // Type resolvers - Symbol: symbolResolvers.Symbol, - Workflow: workflowResolvers.Workflow, - Execution: executionResolvers.Execution, - Baseline: baselineResolvers.Baseline, - Audit: auditResolvers.Audit, - Node: nodeResolvers.Node, - Task: nodeResolvers.Task, - SystemStats: statsResolvers.SystemStats, - SymbolStats: statsResolvers.SymbolStats, - WorkflowStats: statsResolvers.WorkflowStats, - ExecutionStats: statsResolvers.ExecutionStats, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/node-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/node-resolvers.ts deleted file mode 100644 index e4edb28..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/node-resolvers.ts +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Node and Task Resolvers - * - * GraphQL resolvers for swarm Nodes and Tasks - */ - -import type { GraphQLContext } from '../types.js'; -import { requireRole } from '../auth/permissions.js'; - -export const nodeResolvers = { - Query: { - node: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - return context.loaders.nodeLoader.load(args.id); - }, - - nodes: async (_parent: any, args: any, context: GraphQLContext) => { - return context.dataSources.swarm.getNodes({ - status: args.status?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - - task: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - return context.loaders.taskLoader.load(args.id); - }, - - tasks: async (_parent: any, args: any, context: GraphQLContext) => { - return context.dataSources.swarm.getTasks({ - nodeId: args.nodeId, - status: args.status?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - }, - - Mutation: { - removeNode: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requireRole(context, 'admin'); - // This would require adding a method to swarm data source - // For now, this is a placeholder - context.logger.warn('removeNode mutation not fully implemented'); - return true; - }, - }, - - Node: { - status: (node: any) => node.status?.toUpperCase(), - lastHeartbeat: (node: any) => new Date(node.lastHeartbeat), - connectedAt: (node: any) => new Date(node.connectedAt), - - tasks: async (node: any, args: any, context: GraphQLContext) => { - return context.dataSources.swarm.getTasks({ - nodeId: node.id, - status: args.status?.toLowerCase(), - limit: args.limit, - }); - }, - }, - - Task: { - status: (task: any) => task.status?.toUpperCase(), - createdAt: (task: any) => new Date(task.createdAt), - assignedAt: (task: any) => (task.assignedAt ? new Date(task.assignedAt) : null), - - execution: async (task: any, _args: any, context: GraphQLContext) => { - const execId = parseInt(task.executionId, 10); - return context.loaders.executionLoader.load(execId); - }, - - symbol: (task: any) => task.symbol, - - node: async (task: any, _args: any, context: GraphQLContext) => { - if (task.assignedTo) { - return context.loaders.nodeLoader.load(task.assignedTo); - } - return null; - }, - - dependencies: async (task: any, _args: any, context: GraphQLContext) => { - if (task.dependencies && task.dependencies.length > 0) { - return Promise.all(task.dependencies.map((id: string) => context.loaders.taskLoader.load(id))); - } - return []; - }, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/stats-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/stats-resolvers.ts deleted file mode 100644 index 51898ea..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/stats-resolvers.ts +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Statistics Resolvers - * - * GraphQL resolvers for system statistics - */ - -import type { GraphQLContext } from '../types.js'; -import { readFileSync } from 'fs'; -import { join, dirname } from 'path'; -import { fileURLToPath } from 'url'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); - -export const statsResolvers = { - Query: { - stats: async (_parent: any, _args: any, context: GraphQLContext) => { - const [symbolStats, workflowStats, executionStats, nodeStats] = await Promise.all([ - context.dataSources.ecto.getSymbolStats(), - context.dataSources.ecto.getWorkflowStats(), - context.dataSources.ecto.getExecutionStats(), - context.dataSources.swarm.getNodeStats(), - ]); - - // Get version from package.json - let version = '0.1.0'; - try { - const pkg = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8')); - version = pkg.version; - } catch { - // Ignore if package.json not found - } - - return { - symbols: symbolStats, - workflows: workflowStats, - executions: executionStats, - nodes: nodeStats, - uptime: Math.floor(process.uptime()), - version, - }; - }, - }, - - SystemStats: { - // All fields are returned by the query resolver - }, - - SymbolStats: { - byType: (stats: any) => - stats.byType.map((item: any) => ({ - type: item.type?.toUpperCase(), - count: parseInt(item.count, 10), - })), - - byContext: (stats: any) => - stats.byContext.map((item: any) => ({ - context: item.context?.toUpperCase(), - count: parseInt(item.count, 10), - })), - - byStatus: (stats: any) => - stats.byStatus.map((item: any) => ({ - status: item.status?.toUpperCase(), - count: parseInt(item.count, 10), - })), - }, - - WorkflowStats: { - total: (stats: any) => parseInt(stats.total, 10), - pending: (stats: any) => parseInt(stats.pending, 10), - running: (stats: any) => parseInt(stats.running, 10), - completed: (stats: any) => parseInt(stats.completed, 10), - failed: (stats: any) => parseInt(stats.failed, 10), - averageDuration: (stats: any) => parseFloat(stats.average_duration) || null, - successRate: (stats: any) => parseFloat(stats.success_rate) || 0, - }, - - ExecutionStats: { - total: (stats: any) => parseInt(stats.total, 10), - pending: (stats: any) => parseInt(stats.pending, 10), - running: (stats: any) => parseInt(stats.running, 10), - completed: (stats: any) => parseInt(stats.completed, 10), - failed: (stats: any) => parseInt(stats.failed, 10), - averageDuration: (stats: any) => parseFloat(stats.average_duration) || null, - successRate: (stats: any) => parseFloat(stats.success_rate) || 0, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/subscription-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/subscription-resolvers.ts deleted file mode 100644 index 693dfdb..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/subscription-resolvers.ts +++ /dev/null @@ -1,169 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Subscription Resolvers - * - * GraphQL subscription resolvers for real-time updates - */ - -import { withFilter } from 'graphql-subscriptions'; -import type { GraphQLContext } from '../types.js'; -import { SUBSCRIPTION_TOPICS } from '../types.js'; - -export const subscriptionResolvers = { - Subscription: { - workflowUpdated: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.WORKFLOW_UPDATED]); - }, - (payload: any, args: { id?: string }) => { - // If ID filter provided, only send updates for that workflow - if (args.id) { - return String(payload.workflowUpdated.id) === args.id; - } - return true; - } - ), - }, - - workflowStatusChanged: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.WORKFLOW_STATUS_CHANGED]); - }, - (payload: any, args: { id?: string }) => { - if (args.id) { - return String(payload.workflowStatusChanged.id) === args.id; - } - return true; - } - ), - }, - - executionUpdated: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.EXECUTION_UPDATED]); - }, - (payload: any, args: { workflowId?: string }) => { - if (args.workflowId) { - return String(payload.executionUpdated.workflow_id) === args.workflowId; - } - return true; - } - ), - }, - - executionStatusChanged: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.EXECUTION_STATUS_CHANGED]); - }, - (payload: any, args: { workflowId?: string; status?: string }) => { - const execution = payload.executionStatusChanged; - - if (args.workflowId && String(execution.workflow_id) !== args.workflowId) { - return false; - } - - if (args.status && execution.status?.toUpperCase() !== args.status) { - return false; - } - - return true; - } - ), - }, - - auditCompleted: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.AUDIT_COMPLETED]); - }, - (payload: any, args: { baselineId?: string }) => { - if (args.baselineId) { - return String(payload.auditCompleted.baseline_id) === args.baselineId; - } - return true; - } - ), - }, - - auditDeviationDetected: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.AUDIT_DEVIATION_DETECTED]); - }, - (payload: any, args: { severity?: string }) => { - if (args.severity) { - return payload.auditDeviationDetected.severity?.toUpperCase() === args.severity; - } - return true; - } - ), - }, - - nodeStatusChanged: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.NODE_STATUS_CHANGED]); - }, - (payload: any, args: { id?: string }) => { - if (args.id) { - return payload.nodeStatusChanged.id === args.id; - } - return true; - } - ), - }, - - nodeHealthUpdated: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.NODE_HEALTH_UPDATED]); - }, - (payload: any, args: { id?: string }) => { - if (args.id) { - return payload.nodeHealthUpdated.id === args.id; - } - return true; - } - ), - }, - - taskAssigned: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.TASK_ASSIGNED]); - }, - (payload: any, args: { nodeId?: string }) => { - if (args.nodeId) { - return payload.taskAssigned.assignedTo === args.nodeId; - } - return true; - } - ), - }, - - taskUpdated: { - subscribe: withFilter( - (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.TASK_UPDATED]); - }, - (payload: any, args: { nodeId?: string }) => { - if (args.nodeId) { - return payload.taskUpdated.assignedTo === args.nodeId; - } - return true; - } - ), - }, - - statsUpdated: { - subscribe: (_parent: any, _args: any, context: GraphQLContext) => { - return context.pubsub.asyncIterator([SUBSCRIPTION_TOPICS.STATS_UPDATED]); - }, - }, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/symbol-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/symbol-resolvers.ts deleted file mode 100644 index 64c58a1..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/symbol-resolvers.ts +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Symbol Resolvers - * - * GraphQL resolvers for Symbol queries and mutations - */ - -import type { GraphQLContext, NotFoundError } from '../types.js'; -import { requirePermission } from '../auth/permissions.js'; - -export const symbolResolvers = { - Query: { - symbol: async (_parent: any, args: { id?: string; name?: string }, context: GraphQLContext) => { - if (args.id) { - return context.loaders.symbolLoader.load(parseInt(args.id, 10)); - } else if (args.name) { - return context.dataSources.ecto.getSymbolByName(args.name); - } - return null; - }, - - symbols: async (_parent: any, args: any, context: GraphQLContext) => { - return context.dataSources.ecto.getSymbols({ - type: args.type?.toLowerCase(), - context: args.context?.toLowerCase(), - status: args.status?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - - symbolsConnection: async (_parent: any, args: any, context: GraphQLContext) => { - // Relay-style pagination - const limit = args.first || args.last || 20; - const offset = args.after ? parseInt(Buffer.from(args.after, 'base64').toString(), 10) : 0; - - const symbols = await context.dataSources.ecto.getSymbols({ - type: args.type?.toLowerCase(), - context: args.context?.toLowerCase(), - status: args.status?.toLowerCase(), - limit: limit + 1, // Fetch one extra to determine hasNextPage - offset, - }); - - const hasNextPage = symbols.length > limit; - const edges = symbols.slice(0, limit).map((node, index) => ({ - node, - cursor: Buffer.from(String(offset + index)).toString('base64'), - })); - - return { - edges, - pageInfo: { - hasNextPage, - hasPreviousPage: offset > 0, - startCursor: edges[0]?.cursor, - endCursor: edges[edges.length - 1]?.cursor, - total: edges.length, - }, - }; - }, - }, - - Mutation: { - createSymbol: async (_parent: any, args: { input: any }, context: GraphQLContext) => { - requirePermission(context, 'symbols:write'); - return context.dataSources.ecto.createSymbol(args.input); - }, - - updateSymbol: async (_parent: any, args: { id: string; input: any }, context: GraphQLContext) => { - requirePermission(context, 'symbols:write'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.updateSymbol(id, args.input); - }, - - deleteSymbol: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'symbols:delete'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.deleteSymbol(id); - }, - - activateSymbol: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'symbols:write'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.updateSymbol(id, { status: 'active' }); - }, - - deactivateSymbol: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'symbols:write'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.updateSymbol(id, { status: 'inactive' }); - }, - }, - - Symbol: { - id: (symbol: any) => String(symbol.id), - dispatchTarget: (symbol: any) => symbol.dispatch_target?.toUpperCase().replace(/_/g, '_'), - status: (symbol: any) => symbol.status?.toUpperCase(), - type: (symbol: any) => symbol.type?.toUpperCase(), - context: (symbol: any) => symbol.context?.toUpperCase(), - retryCount: (symbol: any) => symbol.retry_count, - createdAt: (symbol: any) => symbol.inserted_at, - updatedAt: (symbol: any) => symbol.updated_at, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/resolvers/workflow-resolvers.ts b/praxis/SymbolicEngine/graphql/src/resolvers/workflow-resolvers.ts deleted file mode 100644 index fc74887..0000000 --- a/praxis/SymbolicEngine/graphql/src/resolvers/workflow-resolvers.ts +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Workflow Resolvers - * - * GraphQL resolvers for Workflow queries and mutations - */ - -import type { GraphQLContext } from '../types.js'; -import { requirePermission } from '../auth/permissions.js'; -import { SUBSCRIPTION_TOPICS } from '../types.js'; - -export const workflowResolvers = { - Query: { - workflow: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - const id = parseInt(args.id, 10); - return context.loaders.workflowLoader.load(id); - }, - - workflows: async (_parent: any, args: any, context: GraphQLContext) => { - return context.dataSources.ecto.getWorkflows({ - status: args.status?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - - workflowsConnection: async (_parent: any, args: any, context: GraphQLContext) => { - const limit = args.first || args.last || 20; - const offset = args.after ? parseInt(Buffer.from(args.after, 'base64').toString(), 10) : 0; - - const workflows = await context.dataSources.ecto.getWorkflows({ - status: args.status?.toLowerCase(), - limit: limit + 1, - offset, - }); - - const hasNextPage = workflows.length > limit; - const edges = workflows.slice(0, limit).map((node, index) => ({ - node, - cursor: Buffer.from(String(offset + index)).toString('base64'), - })); - - return { - edges, - pageInfo: { - hasNextPage, - hasPreviousPage: offset > 0, - startCursor: edges[0]?.cursor, - endCursor: edges[edges.length - 1]?.cursor, - total: edges.length, - }, - }; - }, - }, - - Mutation: { - createWorkflow: async (_parent: any, args: { input: any }, context: GraphQLContext) => { - requirePermission(context, 'workflows:write'); - return context.dataSources.ecto.createWorkflow(args.input); - }, - - executeWorkflow: async (_parent: any, args: { input: any }, context: GraphQLContext) => { - requirePermission(context, 'workflows:execute'); - const workflowId = parseInt(args.input.workflowId, 10); - - // Update workflow status to running - const workflow = await context.dataSources.ecto.updateWorkflow(workflowId, { - status: 'running', - started_at: new Date(), - }); - - // Publish to subscription - context.pubsub.publish(SUBSCRIPTION_TOPICS.WORKFLOW_UPDATED, { workflowUpdated: workflow }); - context.pubsub.publish(SUBSCRIPTION_TOPICS.WORKFLOW_STATUS_CHANGED, { workflowStatusChanged: workflow }); - - return workflow; - }, - - cancelWorkflow: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'workflows:execute'); - const id = parseInt(args.id, 10); - - const workflow = await context.dataSources.ecto.updateWorkflow(id, { - status: 'cancelled', - completed_at: new Date(), - }); - - context.pubsub.publish(SUBSCRIPTION_TOPICS.WORKFLOW_UPDATED, { workflowUpdated: workflow }); - context.pubsub.publish(SUBSCRIPTION_TOPICS.WORKFLOW_STATUS_CHANGED, { workflowStatusChanged: workflow }); - - return workflow; - }, - - pauseWorkflow: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'workflows:execute'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.updateWorkflow(id, { status: 'paused' }); - }, - - resumeWorkflow: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'workflows:execute'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.updateWorkflow(id, { status: 'running' }); - }, - - deleteWorkflow: async (_parent: any, args: { id: string }, context: GraphQLContext) => { - requirePermission(context, 'workflows:delete'); - const id = parseInt(args.id, 10); - return context.dataSources.ecto.deleteWorkflow(id); - }, - }, - - Workflow: { - id: (workflow: any) => String(workflow.id), - status: (workflow: any) => workflow.status?.toUpperCase(), - manifestPath: (workflow: any) => workflow.manifest_path, - executionLog: (workflow: any) => workflow.execution_log, - createdAt: (workflow: any) => workflow.inserted_at, - updatedAt: (workflow: any) => workflow.updated_at, - startedAt: (workflow: any) => workflow.started_at, - completedAt: (workflow: any) => workflow.completed_at, - - symbols: async (workflow: any, _args: any, context: GraphQLContext) => { - // Get all executions for this workflow and extract unique symbols - const executions = await context.dataSources.ecto.getExecutionsByWorkflow(workflow.id); - const symbolIds = [...new Set(executions.map((e) => e.symbol_id))]; - return Promise.all(symbolIds.map((id) => context.loaders.symbolLoader.load(id))); - }, - - executions: async (workflow: any, args: any, context: GraphQLContext) => { - return context.dataSources.ecto.getExecutions({ - workflowId: workflow.id, - status: args.status?.toLowerCase(), - limit: args.limit, - offset: args.offset, - }); - }, - }, -}; diff --git a/praxis/SymbolicEngine/graphql/src/server.ts b/praxis/SymbolicEngine/graphql/src/server.ts deleted file mode 100644 index 20ec89b..0000000 --- a/praxis/SymbolicEngine/graphql/src/server.ts +++ /dev/null @@ -1,215 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis GraphQL API Server - * - * Apollo Server implementation with subscriptions, authentication, and DataLoader - */ - -import { ApolloServer } from '@apollo/server'; -import { expressMiddleware } from '@apollo/server/express4'; -import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'; -import { makeExecutableSchema } from '@graphql-tools/schema'; -import { WebSocketServer } from 'ws'; -import { useServer } from 'graphql-ws/lib/use/ws'; -import { PubSub } from 'graphql-subscriptions'; -import express from 'express'; -import { createServer } from 'http'; -import cors from 'cors'; -import { readFileSync } from 'fs'; -import { join, dirname } from 'path'; -import { fileURLToPath } from 'url'; - -import { createContext } from './context.js'; -import { resolvers } from './resolvers/index.js'; -import { createLogger } from './utils/logger.js'; -import { formatError } from './utils/error-formatter.js'; -import { createDataSources } from './datasources/index.js'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); - -// ============================================================================ -// Configuration -// ============================================================================ - -const PORT = parseInt(process.env.GRAPHQL_PORT || '4000', 10); -const HOST = process.env.GRAPHQL_HOST || 'localhost'; -const NODE_ENV = process.env.NODE_ENV || 'development'; - -const config = { - port: PORT, - host: HOST, - corsOrigins: process.env.CORS_ORIGINS?.split(',') || ['http://localhost:3000'], - enablePlayground: process.env.ENABLE_PLAYGROUND !== 'false', - enableIntrospection: process.env.ENABLE_INTROSPECTION !== 'false', - logLevel: (process.env.LOG_LEVEL as any) || 'info', -}; - -// ============================================================================ -// Schema Loading -// ============================================================================ - -const typeDefs = readFileSync(join(__dirname, '../schema.graphql'), 'utf-8'); - -const schema = makeExecutableSchema({ - typeDefs, - resolvers, -}); - -// ============================================================================ -// Server Setup -// ============================================================================ - -async function startServer() { - const logger = createLogger(config.logLevel); - const pubsub = new PubSub(); - - // Create Express app - const app = express(); - const httpServer = createServer(app); - - // Create WebSocket server for subscriptions - const wsServer = new WebSocketServer({ - server: httpServer, - path: '/graphql', - }); - - // Create data sources (shared across requests) - const dataSources = await createDataSources(logger); - - // Setup WebSocket subscription server - const serverCleanup = useServer( - { - schema, - context: async (ctx) => { - // WebSocket context (for subscriptions) - return createContext({ - req: ctx.extra.request, - dataSources, - pubsub, - logger, - }); - }, - }, - wsServer - ); - - // Create Apollo Server - const server = new ApolloServer({ - schema, - plugins: [ - // Proper shutdown for HTTP server - ApolloServerPluginDrainHttpServer({ httpServer }), - - // Proper shutdown for WebSocket server - { - async serverWillStart() { - return { - async drainServer() { - await serverCleanup.dispose(); - }, - }; - }, - }, - - // Custom logging plugin - { - async requestDidStart() { - return { - async didEncounterErrors(requestContext) { - logger.error('GraphQL Errors:', { - errors: requestContext.errors, - operation: requestContext.operationName, - }); - }, - }; - }, - }, - ], - formatError, - introspection: config.enableIntrospection, - }); - - await server.start(); - - // Apply middleware - app.use( - '/graphql', - cors({ - origin: config.corsOrigins, - credentials: true, - }), - express.json(), - expressMiddleware(server, { - context: async ({ req }) => { - return createContext({ - req, - dataSources, - pubsub, - logger, - }); - }, - }) - ); - - // Health check endpoint - app.get('/health', (req, res) => { - res.json({ - status: 'ok', - uptime: process.uptime(), - timestamp: new Date().toISOString(), - }); - }); - - // Metrics endpoint (basic) - app.get('/metrics', async (req, res) => { - try { - const stats = { - uptime: process.uptime(), - memory: process.memoryUsage(), - connections: { - http: (httpServer as any).connections || 0, - ws: wsServer.clients.size, - }, - }; - res.json(stats); - } catch (error) { - logger.error('Metrics endpoint error:', error); - res.status(500).json({ error: 'Internal server error' }); - } - }); - - // Start HTTP server - await new Promise((resolve) => { - httpServer.listen({ port: config.port, host: config.host }, resolve); - }); - - logger.info(`🚀 GraphQL API Server ready at http://${config.host}:${config.port}/graphql`); - logger.info(`🔌 WebSocket subscriptions ready at ws://${config.host}:${config.port}/graphql`); - - if (config.enablePlayground) { - logger.info(`🎮 GraphQL Playground available at http://${config.host}:${config.port}/graphql`); - } - - // Graceful shutdown - const shutdown = async () => { - logger.info('Shutting down GraphQL server...'); - await server.stop(); - httpServer.close(); - await dataSources.ecto.close?.(); - logger.info('Server shutdown complete'); - process.exit(0); - }; - - process.on('SIGTERM', shutdown); - process.on('SIGINT', shutdown); -} - -// ============================================================================ -// Start Server -// ============================================================================ - -startServer().catch((error) => { - console.error('Failed to start server:', error); - process.exit(1); -}); diff --git a/praxis/SymbolicEngine/graphql/src/types.ts b/praxis/SymbolicEngine/graphql/src/types.ts deleted file mode 100644 index c9697a1..0000000 --- a/praxis/SymbolicEngine/graphql/src/types.ts +++ /dev/null @@ -1,356 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis GraphQL API - Type Definitions - * - * Core TypeScript types for the GraphQL server - */ - -import type { IncomingMessage } from 'http'; -import type { PubSub } from 'graphql-subscriptions'; -import type DataLoader from 'dataloader'; -import type { Logger } from 'winston'; - -// ============================================================================ -// Database Models (matching Ecto schema) -// ============================================================================ - -export interface SymbolModel { - id: number; - name: string; - type: string; - context: string; - status: string; - dispatch_target: string; - parameters: Record; - description: string | null; - priority: number; - timeout: number; - retry_count: number; - inserted_at: Date; - updated_at: Date; -} - -export interface WorkflowModel { - id: number; - name: string; - description: string | null; - manifest_path: string; - status: string; - execution_log: Array>; - metadata: Record; - started_at: Date | null; - completed_at: Date | null; - duration: number | null; - inserted_at: Date; - updated_at: Date; -} - -export interface ExecutionModel { - id: number; - workflow_id: number; - symbol_id: number; - status: string; - started_at: Date | null; - completed_at: Date | null; - duration: number | null; - output: Record; - error_log: string | null; - rollback_state: Record; - retry_attempt: number; - exit_code: number | null; - metadata: Record; - inserted_at: Date; - updated_at: Date; -} - -export interface BaselineModel { - id: number; - name: string; - description: string | null; - symbolic_state: Record; - version: string; - is_active: boolean; - created_by: string | null; - metadata: Record; - baseline_type: string; - scope: string; - inserted_at: Date; - updated_at: Date; -} - -export interface AuditModel { - id: number; - baseline_id: number; - workflow_id: number | null; - audit_type: string; - status: string; - deviations: Array>; - severity: string; - deviation_count: number; - passed_checks: number; - failed_checks: number; - recommendations: Array>; - started_at: Date | null; - completed_at: Date | null; - duration: number | null; - metadata: Record; - inserted_at: Date; - updated_at: Date; -} - -// ============================================================================ -// Swarm Models (from TypeScript swarm) -// ============================================================================ - -export interface NodeModel { - id: string; - name: string; - status: string; - capabilities: { - rust: boolean; - php: boolean; - powershell: boolean; - maxConcurrentTasks: number; - }; - health: { - cpuUsage: number; - memoryUsage: number; - activeTasks: number; - completedTasks: number; - failedTasks: number; - uptime: number; - }; - lastHeartbeat: number; - connectedAt: number; - metadata?: Record; -} - -export interface TaskModel { - id: string; - executionId: string; - symbol: any; - priority: number; - dependencies: string[]; - status: string; - assignedTo?: string; - createdAt: number; - assignedAt?: number; -} - -// ============================================================================ -// GraphQL Context -// ============================================================================ - -export interface AuthUser { - id: string; - username: string; - roles: string[]; - permissions: string[]; -} - -export interface GraphQLContext { - // Authentication - user: AuthUser | null; - token: string | null; - - // Data sources - dataSources: { - ecto: EctoDataSource; - swarm: SwarmDataSource; - powershell: PowerShellDataSource; - injector: InjectorDataSource; - }; - - // DataLoaders - loaders: { - symbolLoader: DataLoader; - workflowLoader: DataLoader; - executionLoader: DataLoader; - baselineLoader: DataLoader; - auditLoader: DataLoader; - nodeLoader: DataLoader; - taskLoader: DataLoader; - }; - - // Subscriptions - pubsub: PubSub; - - // Utilities - logger: Logger; - request: IncomingMessage; -} - -// ============================================================================ -// Data Source Interfaces -// ============================================================================ - -export interface EctoDataSource { - // Symbol operations - getSymbol(id: number): Promise; - getSymbolByName(name: string): Promise; - getSymbols(filters?: SymbolFilters): Promise; - createSymbol(input: any): Promise; - updateSymbol(id: number, input: any): Promise; - deleteSymbol(id: number): Promise; - - // Workflow operations - getWorkflow(id: number): Promise; - getWorkflows(filters?: WorkflowFilters): Promise; - createWorkflow(input: any): Promise; - updateWorkflow(id: number, updates: any): Promise; - deleteWorkflow(id: number): Promise; - - // Execution operations - getExecution(id: number): Promise; - getExecutions(filters?: ExecutionFilters): Promise; - getExecutionsByWorkflow(workflowId: number): Promise; - getExecutionsBySymbol(symbolId: number): Promise; - createExecution(input: any): Promise; - updateExecution(id: number, updates: any): Promise; - - // Baseline operations - getBaseline(id: number): Promise; - getBaselines(filters?: BaselineFilters): Promise; - createBaseline(input: any): Promise; - updateBaseline(id: number, updates: any): Promise; - deleteBaseline(id: number): Promise; - - // Audit operations - getAudit(id: number): Promise; - getAudits(filters?: AuditFilters): Promise; - createAudit(input: any): Promise; - updateAudit(id: number, updates: any): Promise; - - // Statistics - getSymbolStats(): Promise; - getWorkflowStats(): Promise; - getExecutionStats(): Promise; -} - -export interface SwarmDataSource { - getNode(id: string): Promise; - getNodes(filters?: NodeFilters): Promise; - getTask(id: string): Promise; - getTasks(filters?: TaskFilters): Promise; - getNodeStats(): Promise; -} - -export interface PowerShellDataSource { - executeScript(script: string, params?: Record): Promise; - runSymbolicAudit(baselineId: number, workflowId?: number): Promise; - setBaseline(baselineId: number): Promise; - visualizeDiff(baseline1: number, baseline2: number): Promise; -} - -export interface InjectorDataSource { - getInjectorStatus(): Promise; - executeInjection(symbolId: number, params: Record): Promise; -} - -// ============================================================================ -// Filter Types -// ============================================================================ - -export interface SymbolFilters { - type?: string; - context?: string; - status?: string; - limit?: number; - offset?: number; -} - -export interface WorkflowFilters { - status?: string; - limit?: number; - offset?: number; -} - -export interface ExecutionFilters { - workflowId?: number; - symbolId?: number; - status?: string; - limit?: number; - offset?: number; -} - -export interface BaselineFilters { - active?: boolean; - baselineType?: string; - scope?: string; - limit?: number; - offset?: number; -} - -export interface AuditFilters { - baselineId?: number; - severity?: string; - status?: string; - limit?: number; - offset?: number; -} - -export interface NodeFilters { - status?: string; - limit?: number; - offset?: number; -} - -export interface TaskFilters { - nodeId?: string; - status?: string; - limit?: number; - offset?: number; -} - -// ============================================================================ -// Subscription Events -// ============================================================================ - -export const SUBSCRIPTION_TOPICS = { - WORKFLOW_UPDATED: 'WORKFLOW_UPDATED', - WORKFLOW_STATUS_CHANGED: 'WORKFLOW_STATUS_CHANGED', - EXECUTION_UPDATED: 'EXECUTION_UPDATED', - EXECUTION_STATUS_CHANGED: 'EXECUTION_STATUS_CHANGED', - AUDIT_COMPLETED: 'AUDIT_COMPLETED', - AUDIT_DEVIATION_DETECTED: 'AUDIT_DEVIATION_DETECTED', - NODE_STATUS_CHANGED: 'NODE_STATUS_CHANGED', - NODE_HEALTH_UPDATED: 'NODE_HEALTH_UPDATED', - TASK_ASSIGNED: 'TASK_ASSIGNED', - TASK_UPDATED: 'TASK_UPDATED', - STATS_UPDATED: 'STATS_UPDATED', -} as const; - -export type SubscriptionTopic = typeof SUBSCRIPTION_TOPICS[keyof typeof SUBSCRIPTION_TOPICS]; - -// ============================================================================ -// Error Types -// ============================================================================ - -export class AuthenticationError extends Error { - constructor(message: string = 'Not authenticated') { - super(message); - this.name = 'AuthenticationError'; - } -} - -export class AuthorizationError extends Error { - constructor(message: string = 'Not authorized') { - super(message); - this.name = 'AuthorizationError'; - } -} - -export class ValidationError extends Error { - constructor(message: string) { - super(message); - this.name = 'ValidationError'; - } -} - -export class NotFoundError extends Error { - constructor(resource: string, id: string | number) { - super(`${resource} with id ${id} not found`); - this.name = 'NotFoundError'; - } -} diff --git a/praxis/SymbolicEngine/graphql/src/utils/error-formatter.ts b/praxis/SymbolicEngine/graphql/src/utils/error-formatter.ts deleted file mode 100644 index 2708e78..0000000 --- a/praxis/SymbolicEngine/graphql/src/utils/error-formatter.ts +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * GraphQL Error Formatter - * - * Formats errors for GraphQL responses - */ - -import { GraphQLError, GraphQLFormattedError } from 'graphql'; -import { AuthenticationError, AuthorizationError, ValidationError } from '../types.js'; - -export function formatError(formattedError: GraphQLFormattedError, error: unknown): GraphQLFormattedError { - const originalError = error instanceof GraphQLError ? error.originalError : error; - - // Authentication errors - if (originalError instanceof AuthenticationError) { - return { - ...formattedError, - extensions: { - code: 'UNAUTHENTICATED', - http: { status: 401 }, - }, - }; - } - - // Authorization errors - if (originalError instanceof AuthorizationError) { - return { - ...formattedError, - extensions: { - code: 'FORBIDDEN', - http: { status: 403 }, - }, - }; - } - - // Validation errors - if (originalError instanceof ValidationError) { - return { - ...formattedError, - extensions: { - code: 'BAD_USER_INPUT', - http: { status: 400 }, - }, - }; - } - - // Don't expose internal errors in production - if (process.env.NODE_ENV === 'production') { - return { - message: 'Internal server error', - extensions: { - code: 'INTERNAL_SERVER_ERROR', - http: { status: 500 }, - }, - }; - } - - return formattedError; -} diff --git a/praxis/SymbolicEngine/graphql/src/utils/logger.ts b/praxis/SymbolicEngine/graphql/src/utils/logger.ts deleted file mode 100644 index 095f5c4..0000000 --- a/praxis/SymbolicEngine/graphql/src/utils/logger.ts +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Logger Configuration - * - * Winston logger setup for GraphQL server - */ - -import winston from 'winston'; - -export function createLogger(level: string = 'info'): winston.Logger { - const logger = winston.createLogger({ - level, - format: winston.format.combine( - winston.format.timestamp(), - winston.format.errors({ stack: true }), - winston.format.json() - ), - transports: [ - // Console output - new winston.transports.Console({ - format: winston.format.combine( - winston.format.colorize(), - winston.format.simple() - ), - }), - ], - }); - - // Add file transport in production - if (process.env.NODE_ENV === 'production') { - logger.add( - new winston.transports.File({ - filename: 'logs/graphql-error.log', - level: 'error', - }) - ); - logger.add( - new winston.transports.File({ - filename: 'logs/graphql-combined.log', - }) - ); - } - - return logger; -} diff --git a/praxis/SymbolicEngine/graphql/tests/integration.test.ts b/praxis/SymbolicEngine/graphql/tests/integration.test.ts deleted file mode 100644 index e327060..0000000 --- a/praxis/SymbolicEngine/graphql/tests/integration.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Integration Tests - * - * End-to-end tests for GraphQL API - */ - -import { describe, test, expect, beforeAll, afterAll } from 'bun:test'; - -// Note: These are placeholder tests. In a real environment, you would: -// 1. Start the GraphQL server -// 2. Set up test database -// 3. Create test data -// 4. Run queries/mutations -// 5. Clean up - -describe('GraphQL API Integration Tests', () => { - beforeAll(async () => { - // TODO: Start server and initialize test database - }); - - afterAll(async () => { - // TODO: Clean up and stop server - }); - - test('placeholder: should query symbols', async () => { - // TODO: Implement actual integration test - expect(true).toBe(true); - }); - - test('placeholder: should create and execute workflow', async () => { - // TODO: Implement actual integration test - expect(true).toBe(true); - }); - - test('placeholder: should subscribe to workflow updates', async () => { - // TODO: Implement actual integration test - expect(true).toBe(true); - }); -}); diff --git a/praxis/SymbolicEngine/graphql/tests/schema.test.ts b/praxis/SymbolicEngine/graphql/tests/schema.test.ts deleted file mode 100644 index cf9b7d9..0000000 --- a/praxis/SymbolicEngine/graphql/tests/schema.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Schema Validation Tests - * - * Tests for GraphQL schema validation - */ - -import { describe, test, expect } from 'bun:test'; -import { readFileSync } from 'fs'; -import { join, dirname } from 'path'; -import { fileURLToPath } from 'url'; -import { buildSchema, GraphQLSchema } from 'graphql'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); - -describe('GraphQL Schema', () => { - let schema: GraphQLSchema; - - test('should load and parse schema file', () => { - const schemaPath = join(__dirname, '../schema.graphql'); - const typeDefs = readFileSync(schemaPath, 'utf-8'); - - expect(() => { - schema = buildSchema(typeDefs); - }).not.toThrow(); - - expect(schema).toBeDefined(); - }); - - test('should have Query type', () => { - const schemaPath = join(__dirname, '../schema.graphql'); - const typeDefs = readFileSync(schemaPath, 'utf-8'); - schema = buildSchema(typeDefs); - - const queryType = schema.getQueryType(); - expect(queryType).toBeDefined(); - expect(queryType?.name).toBe('Query'); - }); - - test('should have Mutation type', () => { - const schemaPath = join(__dirname, '../schema.graphql'); - const typeDefs = readFileSync(schemaPath, 'utf-8'); - schema = buildSchema(typeDefs); - - const mutationType = schema.getMutationType(); - expect(mutationType).toBeDefined(); - expect(mutationType?.name).toBe('Mutation'); - }); - - test('should have Subscription type', () => { - const schemaPath = join(__dirname, '../schema.graphql'); - const typeDefs = readFileSync(schemaPath, 'utf-8'); - schema = buildSchema(typeDefs); - - const subscriptionType = schema.getSubscriptionType(); - expect(subscriptionType).toBeDefined(); - expect(subscriptionType?.name).toBe('Subscription'); - }); - - test('should have Symbol type with required fields', () => { - const schemaPath = join(__dirname, '../schema.graphql'); - const typeDefs = readFileSync(schemaPath, 'utf-8'); - schema = buildSchema(typeDefs); - - const symbolType = schema.getType('Symbol'); - expect(symbolType).toBeDefined(); - - const fields = (symbolType as any).getFields(); - expect(fields.id).toBeDefined(); - expect(fields.name).toBeDefined(); - expect(fields.type).toBeDefined(); - expect(fields.context).toBeDefined(); - expect(fields.status).toBeDefined(); - }); - - test('should have Workflow type with required fields', () => { - const schemaPath = join(__dirname, '../schema.graphql'); - const typeDefs = readFileSync(schemaPath, 'utf-8'); - schema = buildSchema(typeDefs); - - const workflowType = schema.getType('Workflow'); - expect(workflowType).toBeDefined(); - - const fields = (workflowType as any).getFields(); - expect(fields.id).toBeDefined(); - expect(fields.name).toBeDefined(); - expect(fields.status).toBeDefined(); - expect(fields.executions).toBeDefined(); - }); -}); diff --git a/praxis/SymbolicEngine/graphql/tsconfig.json b/praxis/SymbolicEngine/graphql/tsconfig.json deleted file mode 100644 index 70d690f..0000000 --- a/praxis/SymbolicEngine/graphql/tsconfig.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "ESNext", - "lib": ["ES2022"], - "moduleResolution": "bundler", - "types": ["bun-types"], - - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "allowSyntheticDefaultImports": true, - - "outDir": "./dist", - "rootDir": "./src", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedIndexedAccess": true, - - "baseUrl": ".", - "paths": { - "@/*": ["./src/*"], - "@resolvers/*": ["./src/resolvers/*"], - "@datasources/*": ["./src/datasources/*"], - "@auth/*": ["./src/auth/*"], - "@utils/*": ["./src/utils/*"] - } - }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules", - "dist", - "tests" - ] -} diff --git a/praxis/SymbolicEngine/swarm/README.md b/praxis/SymbolicEngine/swarm/README.md index 9b87ac3..afcb0e9 100644 --- a/praxis/SymbolicEngine/swarm/README.md +++ b/praxis/SymbolicEngine/swarm/README.md @@ -6,7 +6,7 @@ Copyright (c) Jonathan D.A. Jewell **Distributed Symbolic Execution System for WordPress Workflows** -A high-performance TypeScript-based swarm coordination system that distributes symbolic execution tasks across multiple worker nodes with real-time monitoring, state synchronization, and fault tolerance. +A high-performance -based swarm coordination system that distributes symbolic execution tasks across multiple worker nodes with real-time monitoring, state synchronization, and fault tolerance. ## Overview @@ -405,9 +405,9 @@ timeout = 30000 ## Programmatic Usage -You can use the swarm system programmatically in your TypeScript code: +You can use the swarm system programmatically in your code: -```typescript +``` import { createDispatcher, createWorker } from '@wp-praxis/swarm'; import { StateManager } from '@wp-praxis/swarm/state-manager'; import { Logger } from '@wp-praxis/swarm/logger'; @@ -448,7 +448,7 @@ swarm/ ├── bin/ │ └── swarm-cli.ts # CLI interface ├── src/ -│ ├── types.ts # TypeScript type definitions +│ ├── types.ts # type definitions │ ├── logger.ts # Logging system │ ├── state-manager.ts # SQLite state management │ ├── executor.ts # Symbol execution @@ -457,7 +457,7 @@ swarm/ │ ├── dispatch.ts # Main dispatcher │ └── websocket-server.ts # WebSocket server ├── package.json # Dependencies -├── tsconfig.json # TypeScript config +├── onfig.json # config ├── swarm-config.toml # Default configuration └── README.md # This file ``` @@ -465,7 +465,7 @@ swarm/ ### Building ```bash -# TypeScript type checking +# type checking bun run lint # Build project diff --git a/praxis/SymbolicEngine/swarm/bin/swarm-cli.ts b/praxis/SymbolicEngine/swarm/bin/swarm-cli.ts deleted file mode 100644 index 4890e19..0000000 --- a/praxis/SymbolicEngine/swarm/bin/swarm-cli.ts +++ /dev/null @@ -1,419 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -#!/usr/bin/env bun - -/** - * WP Praxis Swarm - CLI Interface - * - * Command-line interface for swarm coordination with commands: - * - start: Start dispatcher or worker - * - stop: Stop running components - * - status: Show swarm status - * - deploy: Deploy a workflow - * - scale: Scale worker nodes - * - config: Manage configuration - */ - -import { existsSync, readFileSync, writeFileSync } from 'fs'; -import { resolve, join } from 'path'; -import { parse as parseTOML } from 'toml'; -import type { SwarmConfig, WorkerConfig } from '../src/types'; -import { createDispatcher } from '../src/dispatch'; -import { createWorker } from '../src/worker'; -import { StateManager } from '../src/state-manager'; -import { Logger } from '../src/logger'; - -// ============================================================================ -// Configuration -// ============================================================================ - -const DEFAULT_CONFIG_PATH = './swarm-config.toml'; -const DEFAULT_STATE_DB = './swarm-state.db'; -const DEFAULT_LOG_FILE = './swarm.log'; - -/** - * Load configuration from file - */ -function loadConfig(configPath: string): SwarmConfig { - if (!existsSync(configPath)) { - console.error(`Configuration file not found: ${configPath}`); - process.exit(1); - } - - try { - const content = readFileSync(configPath, 'utf-8'); - const config = parseTOML(content) as any; - - return { - dispatcher: { - coordinatorEndpoint: config.dispatcher?.coordinator_endpoint ?? 'ws://localhost:8080', - stateDbPath: config.dispatcher?.state_db_path ?? DEFAULT_STATE_DB, - enableWebSocket: config.dispatcher?.enable_websocket ?? true, - websocketPort: config.dispatcher?.websocket_port ?? 8080, - }, - coordinator: { - maxWorkers: config.coordinator?.max_workers ?? 100, - heartbeatInterval: config.coordinator?.heartbeat_interval ?? 5000, - heartbeatTimeout: config.coordinator?.heartbeat_timeout ?? 15000, - taskRetryLimit: config.coordinator?.task_retry_limit ?? 3, - enableLoadBalancing: config.coordinator?.enable_load_balancing ?? true, - priorityQueueEnabled: config.coordinator?.priority_queue_enabled ?? true, - }, - worker: { - nodeName: config.worker?.node_name ?? 'worker-node', - dispatcherUrl: config.worker?.dispatcher_url ?? 'ws://localhost:8080', - heartbeatInterval: config.worker?.heartbeat_interval ?? 5000, - maxConcurrentTasks: config.worker?.max_concurrent_tasks ?? 4, - capabilities: { - rust: config.worker?.capabilities?.rust ?? false, - php: config.worker?.capabilities?.php ?? false, - powershell: config.worker?.capabilities?.powershell ?? false, - maxConcurrentTasks: config.worker?.capabilities?.max_concurrent_tasks ?? 4, - }, - backends: { - rustInjector: config.backends?.rust_injector - ? { - enabled: config.backends.rust_injector.enabled ?? false, - binaryPath: config.backends.rust_injector.binary_path ?? '/path/to/wp_injector', - timeout: config.backends.rust_injector.timeout ?? 30000, - } - : undefined, - phpEngine: config.backends?.php_engine - ? { - enabled: config.backends.php_engine.enabled ?? false, - scriptPath: config.backends.php_engine.script_path ?? '/path/to/symbolic-engine.php', - phpBinary: config.backends.php_engine.php_binary ?? 'php', - timeout: config.backends.php_engine.timeout ?? 30000, - } - : undefined, - powershellEngine: config.backends?.powershell_engine - ? { - enabled: config.backends.powershell_engine.enabled ?? false, - scriptPath: config.backends.powershell_engine.script_path ?? '/path/to/symbolic.ps1', - pwshBinary: config.backends.powershell_engine.pwsh_binary ?? 'pwsh', - timeout: config.backends.powershell_engine.timeout ?? 30000, - } - : undefined, - }, - }, - logging: { - level: config.logging?.level ?? 'info', - file: config.logging?.file ?? DEFAULT_LOG_FILE, - console: config.logging?.console ?? true, - format: config.logging?.format ?? 'text', - }, - }; - } catch (error) { - console.error('Failed to load configuration:', error); - process.exit(1); - } -} - -/** - * Initialize logger - */ -function initLogger(config: SwarmConfig): void { - Logger.configure(config.logging); -} - -// ============================================================================ -// Commands -// ============================================================================ - -/** - * Start dispatcher command - */ -async function startDispatcher(configPath: string): Promise { - console.log('Starting WP Praxis Swarm Dispatcher...\n'); - - const config = loadConfig(configPath); - initLogger(config); - - const logger = new Logger('CLI'); - const dispatcher = createDispatcher(config.dispatcher, logger.child('Dispatcher')); - - // Handle graceful shutdown - process.on('SIGINT', async () => { - console.log('\nShutting down dispatcher...'); - await dispatcher.stop(); - process.exit(0); - }); - - process.on('SIGTERM', async () => { - console.log('\nShutting down dispatcher...'); - await dispatcher.stop(); - process.exit(0); - }); - - // Start dispatcher - await dispatcher.start(); - - console.log(`Dispatcher started successfully!`); - console.log(`WebSocket server: ws://localhost:${config.dispatcher.websocketPort}`); - console.log(`State database: ${config.dispatcher.stateDbPath}`); - console.log('\nPress Ctrl+C to stop\n'); - - // Keep process alive - await new Promise(() => {}); -} - -/** - * Start worker command - */ -async function startWorker(configPath: string, nodeName?: string): Promise { - console.log('Starting WP Praxis Swarm Worker...\n'); - - const config = loadConfig(configPath); - initLogger(config); - - const logger = new Logger('CLI'); - - // Override node name if provided - if (nodeName) { - config.worker.nodeName = nodeName; - } - - const stateManager = new StateManager( - `./worker-${config.worker.nodeName}.db`, - logger.child('StateManager') - ); - - const worker = createWorker(config.worker, stateManager, logger.child('Worker')); - - // Handle graceful shutdown - process.on('SIGINT', async () => { - console.log('\nShutting down worker...'); - await worker.stop(); - stateManager.close(); - process.exit(0); - }); - - process.on('SIGTERM', async () => { - console.log('\nShutting down worker...'); - await worker.stop(); - stateManager.close(); - process.exit(0); - }); - - // Start worker - await worker.start(config.worker.dispatcherUrl); - - console.log(`Worker started successfully!`); - console.log(`Node name: ${config.worker.nodeName}`); - console.log(`Connected to: ${config.worker.dispatcherUrl}`); - console.log(`Capabilities: ${JSON.stringify(config.worker.capabilities, null, 2)}`); - console.log('\nPress Ctrl+C to stop\n'); - - // Keep process alive - await new Promise(() => {}); -} - -/** - * Deploy workflow command - */ -async function deployWorkflow(configPath: string, manifestPath: string): Promise { - console.log('Deploying workflow...\n'); - - const config = loadConfig(configPath); - initLogger(config); - - const logger = new Logger('CLI'); - const dispatcher = createDispatcher(config.dispatcher, logger.child('Dispatcher')); - - await dispatcher.start(); - - console.log(`Loading manifest: ${manifestPath}`); - const result = await dispatcher.dispatchFromFile(manifestPath); - - console.log('\nWorkflow Deployment Results:'); - console.log(`Workflow ID: ${result.workflowId}`); - console.log(`Total tasks: ${result.totalTasks}`); - console.log(`Completed: ${result.completedTasks}`); - console.log(`Failed: ${result.failedTasks}`); - console.log(`Duration: ${result.duration}ms`); - - await dispatcher.stop(); - - if (result.failedTasks > 0) { - console.error('\nWorkflow deployment had failures'); - process.exit(1); - } else { - console.log('\nWorkflow deployed successfully!'); - process.exit(0); - } -} - -/** - * Show status command - */ -async function showStatus(configPath: string): Promise { - console.log('WP Praxis Swarm Status\n'); - - const config = loadConfig(configPath); - initLogger(config); - - const logger = new Logger('CLI'); - const dispatcher = createDispatcher(config.dispatcher, logger.child('Dispatcher')); - - await dispatcher.start(); - - const stats = dispatcher.getStats(); - - console.log('Coordinator Status:'); - console.log(` Active nodes: ${stats.coordinator.nodes.active}`); - console.log(` Idle: ${stats.coordinator.nodes.idle}`); - console.log(` Busy: ${stats.coordinator.nodes.busy}`); - console.log(` Queued tasks: ${stats.coordinator.tasks.queued}`); - console.log(` Running tasks: ${stats.coordinator.tasks.running}`); - console.log(` Completed tasks: ${stats.coordinator.tasks.completed}`); - console.log(` Failed tasks: ${stats.coordinator.tasks.failed}`); - console.log(`\nActive workflows: ${stats.activeWorkflows}`); - console.log(`\nState database:`); - Object.entries(stats.state).forEach(([table, count]) => { - console.log(` ${table}: ${count} records`); - }); - - await dispatcher.stop(); -} - -/** - * Generate default configuration - */ -function generateConfig(outputPath: string): void { - const defaultConfig = `# WP Praxis Swarm Configuration - -[dispatcher] -coordinator_endpoint = "ws://localhost:8080" -state_db_path = "./swarm-state.db" -enable_websocket = true -websocket_port = 8080 - -[coordinator] -max_workers = 100 -heartbeat_interval = 5000 -heartbeat_timeout = 15000 -task_retry_limit = 3 -enable_load_balancing = true -priority_queue_enabled = true - -[worker] -node_name = "worker-node-1" -dispatcher_url = "ws://localhost:8080" -heartbeat_interval = 5000 -max_concurrent_tasks = 4 - -[worker.capabilities] -rust = true -php = true -powershell = true -max_concurrent_tasks = 4 - -[backends.rust_injector] -enabled = true -binary_path = "../../wp_injector/target/release/wp_injector" -timeout = 30000 - -[backends.php_engine] -enabled = true -script_path = "../../engine/php/symbolic-engine.php" -php_binary = "php" -timeout = 30000 - -[backends.powershell_engine] -enabled = true -script_path = "../../SymbolicEngine/core/symbolic.ps1" -pwsh_binary = "pwsh" -timeout = 30000 - -[logging] -level = "info" -file = "./swarm.log" -console = true -format = "text" -`; - - writeFileSync(outputPath, defaultConfig, 'utf-8'); - console.log(`Configuration file created: ${outputPath}`); -} - -// ============================================================================ -// Main CLI -// ============================================================================ - -async function main() { - const args = process.argv.slice(2); - const command = args[0]; - - if (!command || command === 'help' || command === '--help' || command === '-h') { - console.log(` -WP Praxis Swarm - Distributed Symbolic Execution System - -Usage: - swarm [options] - -Commands: - start-dispatcher [config] Start the swarm dispatcher - start-worker [config] [name] Start a swarm worker node - deploy [config] Deploy a workflow from manifest - status [config] Show swarm status - config [output] Generate default configuration - -Options: - config Path to config file (default: ./swarm-config.toml) - name Worker node name - manifest Path to workflow manifest (YAML/TOML) - output Output path for config file - -Examples: - swarm start-dispatcher - swarm start-worker ./swarm-config.toml worker-1 - swarm deploy ./workflow.yaml - swarm status - swarm config ./my-config.toml -`); - process.exit(0); - } - - try { - switch (command) { - case 'start-dispatcher': - await startDispatcher(args[1] ?? DEFAULT_CONFIG_PATH); - break; - - case 'start-worker': - await startWorker(args[1] ?? DEFAULT_CONFIG_PATH, args[2]); - break; - - case 'deploy': - if (!args[1]) { - console.error('Error: Manifest path required'); - console.log('Usage: swarm deploy [config]'); - process.exit(1); - } - await deployWorkflow(args[2] ?? DEFAULT_CONFIG_PATH, args[1]); - break; - - case 'status': - await showStatus(args[1] ?? DEFAULT_CONFIG_PATH); - break; - - case 'config': - generateConfig(args[1] ?? DEFAULT_CONFIG_PATH); - break; - - default: - console.error(`Unknown command: ${command}`); - console.log('Run "swarm help" for usage information'); - process.exit(1); - } - } catch (error) { - console.error('Error:', error instanceof Error ? error.message : String(error)); - process.exit(1); - } -} - -// Run CLI -main().catch((error) => { - console.error('Fatal error:', error); - process.exit(1); -}); diff --git a/praxis/SymbolicEngine/swarm/deno.json b/praxis/SymbolicEngine/swarm/deno.json deleted file mode 100644 index 7a94e72..0000000 --- a/praxis/SymbolicEngine/swarm/deno.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "@wp-praxis/swarm", - "version": "0.1.0", - "tasks": { - "build": "deno run --node-modules-dir=auto -A npm:rescript", - "dev": "deno run --node-modules-dir=auto -A npm:rescript -w", - "clean": "deno run --node-modules-dir=auto -A npm:rescript clean" - }, - "imports": { - "rescript": "npm:rescript@^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.1", - "@rescript/runtime/": "npm:/@rescript/runtime@12.2.0/", - "uuid": "npm:uuid@^9.0.1", - "ws": "npm:ws@^8.16.0" - } -} diff --git a/praxis/SymbolicEngine/swarm/deno.lock b/praxis/SymbolicEngine/swarm/deno.lock deleted file mode 100644 index 1f40853..0000000 --- a/praxis/SymbolicEngine/swarm/deno.lock +++ /dev/null @@ -1,453 +0,0 @@ -{ - "version": "5", - "specifiers": { - "npm:@rescript/core@^1.6.1": "1.6.1_rescript@12.2.0", - "npm:@rescript/runtime@12.2.0": "12.2.0", - "npm:@types/better-sqlite3@^7.6.8": "7.6.13", - "npm:@types/uuid@^9.0.7": "9.0.8", - "npm:@types/ws@^8.5.10": "8.18.1", - "npm:better-sqlite3@^9.2.2": "9.6.0", - "npm:bun-types@latest": "1.3.10", - "npm:rescript@*": "12.2.0", - "npm:rescript@12": "12.2.0", - "npm:toml@3": "3.0.0", - "npm:uuid@^9.0.1": "9.0.1", - "npm:winston@^3.11.0": "3.19.0", - "npm:ws@^8.16.0": "8.19.0", - "npm:yaml@^2.3.4": "2.8.2" - }, - "npm": { - "@colors/colors@1.6.0": { - "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" - }, - "@dabh/diagnostics@2.0.8": { - "integrity": "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==", - "dependencies": [ - "@so-ric/colorspace", - "enabled", - "kuler" - ] - }, - "@rescript/core@1.6.1_rescript@12.2.0": { - "integrity": "sha512-vyb5k90ck+65Fgui+5vCja/mUfzKaK3kOPT4Z6aAJdHLH1eljEi1zKhXroCiCtpNLSWp8k4ulh1bdB5WS0hvqA==", - "dependencies": [ - "rescript" - ] - }, - "@rescript/darwin-arm64@12.2.0": { - "integrity": "sha512-xc3K/J7Ujl1vPiFY2009mRf3kWRlUe/VZyJWprseKxlcEtUQv89ter7r6pY+YFbtYvA/fcaEncL9CVGEdattAg==", - "os": ["darwin"], - "cpu": ["arm64"] - }, - "@rescript/darwin-x64@12.2.0": { - "integrity": "sha512-qqcTvnlSeoKkywLjG7cXfYvKZ1e4Gz2kUKcD6SiqDgCqm8TF+spwlFAiM6sloRUOFsc0bpC/0R0B3yr01FCB1A==", - "os": ["darwin"], - "cpu": ["x64"] - }, - "@rescript/linux-arm64@12.2.0": { - "integrity": "sha512-ODmpG3ji+Nj/8d5yvXkeHlfKkmbw1Q4t1iIjVuNwtmFpz7TiEa7n/sQqoYdE+WzbDX3DoJfmJNbp3Ob7qCUoOg==", - "os": ["linux"], - "cpu": ["arm64"] - }, - "@rescript/linux-x64@12.2.0": { - "integrity": "sha512-2W9Y9/g19Y4F/subl8yV3T8QBG2oRaP+HciNRcBjptyEdw9LmCKH8+rhWO6sp3E+nZLwoE2IAkwH0WKV3wqlxQ==", - "os": ["linux"], - "cpu": ["x64"] - }, - "@rescript/runtime@12.2.0": { - "integrity": "sha512-NwfljDRq1rjFPHUaca1nzFz13xsa9ZGkBkLvMhvVgavJT5+A4rMcLu8XAaVTi/oAhO/tlHf9ZDoOTF1AfyAk9Q==" - }, - "@rescript/win32-x64@12.2.0": { - "integrity": "sha512-fhf8CBj3p1lkIXPeNko3mVTKQfXXm4BoxJtR1xAXxUn43wDpd8Lox4w8/EPBbbW6C/YFQW6H7rtpY+2AKuNaDA==", - "os": ["win32"], - "cpu": ["x64"] - }, - "@so-ric/colorspace@1.1.6": { - "integrity": "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==", - "dependencies": [ - "color", - "text-hex" - ] - }, - "@types/better-sqlite3@7.6.13": { - "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", - "dependencies": [ - "@types/node" - ] - }, - "@types/node@25.3.3": { - "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", - "dependencies": [ - "undici-types" - ] - }, - "@types/triple-beam@1.3.5": { - "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" - }, - "@types/uuid@9.0.8": { - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==" - }, - "@types/ws@8.18.1": { - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dependencies": [ - "@types/node" - ] - }, - "async@3.2.6": { - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" - }, - "base64-js@1.5.1": { - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "better-sqlite3@9.6.0": { - "integrity": "sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ==", - "dependencies": [ - "bindings", - "prebuild-install" - ], - "scripts": true - }, - "bindings@1.5.0": { - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": [ - "file-uri-to-path" - ] - }, - "bl@4.1.0": { - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": [ - "buffer", - "inherits", - "readable-stream" - ] - }, - "buffer@5.7.1": { - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dependencies": [ - "base64-js", - "ieee754" - ] - }, - "bun-types@1.3.10": { - "integrity": "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg==", - "dependencies": [ - "@types/node" - ] - }, - "chownr@1.1.4": { - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "color-convert@3.1.3": { - "integrity": "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==", - "dependencies": [ - "color-name" - ] - }, - "color-name@2.1.0": { - "integrity": "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==" - }, - "color-string@2.1.4": { - "integrity": "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==", - "dependencies": [ - "color-name" - ] - }, - "color@5.0.3": { - "integrity": "sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==", - "dependencies": [ - "color-convert", - "color-string" - ] - }, - "decompress-response@6.0.0": { - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": [ - "mimic-response" - ] - }, - "deep-extend@0.6.0": { - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "detect-libc@2.1.2": { - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==" - }, - "enabled@2.0.0": { - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "end-of-stream@1.4.5": { - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dependencies": [ - "once" - ] - }, - "expand-template@2.0.3": { - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" - }, - "fecha@4.2.3": { - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "file-uri-to-path@1.0.0": { - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fn.name@1.1.0": { - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "fs-constants@1.0.0": { - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "github-from-package@0.0.0": { - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, - "ieee754@1.2.1": { - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inherits@2.0.4": { - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini@1.3.8": { - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "is-stream@2.0.1": { - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "kuler@2.0.0": { - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "logform@2.7.0": { - "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", - "dependencies": [ - "@colors/colors", - "@types/triple-beam", - "fecha", - "ms", - "safe-stable-stringify", - "triple-beam" - ] - }, - "mimic-response@3.1.0": { - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - }, - "minimist@1.2.8": { - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "mkdirp-classic@0.5.3": { - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "ms@2.1.3": { - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "napi-build-utils@2.0.0": { - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" - }, - "node-abi@3.87.0": { - "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", - "dependencies": [ - "semver" - ] - }, - "once@1.4.0": { - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": [ - "wrappy" - ] - }, - "one-time@1.0.0": { - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": [ - "fn.name" - ] - }, - "prebuild-install@7.1.3": { - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "dependencies": [ - "detect-libc", - "expand-template", - "github-from-package", - "minimist", - "mkdirp-classic", - "napi-build-utils", - "node-abi", - "pump", - "rc", - "simple-get", - "tar-fs", - "tunnel-agent" - ], - "deprecated": true, - "bin": true - }, - "pump@3.0.4": { - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "dependencies": [ - "end-of-stream", - "once" - ] - }, - "rc@1.2.8": { - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": [ - "deep-extend", - "ini", - "minimist", - "strip-json-comments" - ], - "bin": true - }, - "readable-stream@3.6.2": { - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": [ - "inherits", - "string_decoder", - "util-deprecate" - ] - }, - "rescript@12.2.0": { - "integrity": "sha512-1Jf2cmNhyx5Mj2vwZ4XXPcXvNSjGj9D1jPBUcoqIOqRpLPo1ch2Ta/7eWh23xAHWHK5ow7BCDyYFjvZSjyjLzg==", - "dependencies": [ - "@rescript/runtime" - ], - "optionalDependencies": [ - "@rescript/darwin-arm64", - "@rescript/darwin-x64", - "@rescript/linux-arm64", - "@rescript/linux-x64", - "@rescript/win32-x64" - ], - "bin": true - }, - "safe-buffer@5.2.1": { - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-stable-stringify@2.5.0": { - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==" - }, - "semver@7.7.4": { - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "bin": true - }, - "simple-concat@1.0.1": { - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "simple-get@4.0.1": { - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dependencies": [ - "decompress-response", - "once", - "simple-concat" - ] - }, - "stack-trace@0.0.10": { - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" - }, - "string_decoder@1.3.0": { - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": [ - "safe-buffer" - ] - }, - "strip-json-comments@2.0.1": { - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" - }, - "tar-fs@2.1.4": { - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "dependencies": [ - "chownr", - "mkdirp-classic", - "pump", - "tar-stream" - ] - }, - "tar-stream@2.2.0": { - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": [ - "bl", - "end-of-stream", - "fs-constants", - "inherits", - "readable-stream" - ] - }, - "text-hex@1.0.0": { - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "toml@3.0.0": { - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" - }, - "triple-beam@1.4.1": { - "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==" - }, - "tunnel-agent@0.6.0": { - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": [ - "safe-buffer" - ] - }, - "undici-types@7.18.2": { - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==" - }, - "util-deprecate@1.0.2": { - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid@9.0.1": { - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "bin": true - }, - "winston-transport@4.9.0": { - "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", - "dependencies": [ - "logform", - "readable-stream", - "triple-beam" - ] - }, - "winston@3.19.0": { - "integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==", - "dependencies": [ - "@colors/colors", - "@dabh/diagnostics", - "async", - "is-stream", - "logform", - "one-time", - "readable-stream", - "safe-stable-stringify", - "stack-trace", - "triple-beam", - "winston-transport" - ] - }, - "wrappy@1.0.2": { - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "ws@8.19.0": { - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==" - }, - "yaml@2.8.2": { - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "bin": true - } - }, - "workspace": { - "dependencies": [ - "npm:@rescript/core@^1.6.1", - "npm:@rescript/runtime@12.2.0", - "npm:rescript@12", - "npm:uuid@^9.0.1", - "npm:ws@^8.16.0" - ], - "packageJson": { - "dependencies": [ - "npm:@types/better-sqlite3@^7.6.8", - "npm:@types/uuid@^9.0.7", - "npm:@types/ws@^8.5.10", - "npm:better-sqlite3@^9.2.2", - "npm:bun-types@latest", - "npm:toml@3", - "npm:uuid@^9.0.1", - "npm:winston@^3.11.0", - "npm:ws@^8.16.0", - "npm:yaml@^2.3.4" - ] - } - } -} diff --git a/praxis/SymbolicEngine/swarm/lib/ocaml/Coordinator.ast b/praxis/SymbolicEngine/swarm/lib/ocaml/Coordinator.ast index 68e6c6d..3a22305 100644 Binary files a/praxis/SymbolicEngine/swarm/lib/ocaml/Coordinator.ast and b/praxis/SymbolicEngine/swarm/lib/ocaml/Coordinator.ast differ diff --git a/praxis/SymbolicEngine/swarm/lib/rescript.lock b/praxis/SymbolicEngine/swarm/lib/rescript.lock deleted file mode 100644 index 274fdc4..0000000 --- a/praxis/SymbolicEngine/swarm/lib/rescript.lock +++ /dev/null @@ -1 +0,0 @@ -130119 \ No newline at end of file diff --git a/praxis/SymbolicEngine/swarm/package.json b/praxis/SymbolicEngine/swarm/package.json index f7c93ee..4d0d784 100644 --- a/praxis/SymbolicEngine/swarm/package.json +++ b/praxis/SymbolicEngine/swarm/package.json @@ -27,13 +27,9 @@ "winston": "^3.11.0" }, "devDependencies": { - "@types/ws": "^8.5.10", - "@types/better-sqlite3": "^7.6.8", - "@types/uuid": "^9.0.7", "bun-types": "latest" }, "peerDependencies": { - "typescript": "^5.0.0" }, "keywords": [ "wp-praxis", diff --git a/praxis/SymbolicEngine/swarm/rescript.json b/praxis/SymbolicEngine/swarm/rescript.json deleted file mode 100644 index 4ff2f74..0000000 --- a/praxis/SymbolicEngine/swarm/rescript.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "@wp-praxis/swarm", - "version": "0.1.0", - "sources": [ - { - "dir": "src", - "subdirs": true - } - ], - "package-specs": [ - { - "module": "esmodule", - "in-source": true - } - ], - "suffix": ".res.js", - "dependencies": [ - "@rescript/core" - ], - "compiler-flags": ["-open RescriptCore"], - "uncurried": true -} diff --git a/praxis/SymbolicEngine/swarm/src/Coordinator.res b/praxis/SymbolicEngine/swarm/src/Coordinator.res deleted file mode 100644 index cc4e807..0000000 --- a/praxis/SymbolicEngine/swarm/src/Coordinator.res +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -/** - * WP Praxis Swarm — Task Distribution Coordinator - * Fully ported to ReScript v12 - */ - -module Uuid = { - @module("uuid") external v4: unit => string = "v4" -} - -module Types = { - type nodeStatus = Online | Offline | Busy - - type node = { - id: string, - mutable status: nodeStatus, - mutable lastHeartbeat: float, - capabilities: array, - maxTasks: int, - mutable activeTasks: int, - } - - type taskStatus = Pending | Running | Completed | Failed - - type task = { - id: string, - mutable status: taskStatus, - engine: string, - prerequisites: array, - } -} - -module Coordinator = { - type t = { - nodes: Map.t, - taskQueue: array, - completedSymbols: Set.t, - } - - let make = () => { - { - nodes: Map.make(), - taskQueue: [], - completedSymbols: Set.make(), - } - } - - let isTaskReady = (self: t, task: Types.task) => { - task.status == Types.Pending && - task.prerequisites->Array.every(p => self.completedSymbols->Set.has(p)) - } - - let getBestNodeForTask = (self: t, task: Types.task): option => { - self.nodes - ->Map.values - ->Iterator.toArray - ->Array.filter(node => - node.status == Types.Online && - node.activeTasks < node.maxTasks && - node.capabilities->Array.includes(task.engine) - ) - ->Array.toSorted((a, b) => - Float.compare( - Int.toFloat(a.activeTasks) /. Int.toFloat(a.maxTasks), - Int.toFloat(b.activeTasks) /. Int.toFloat(b.maxTasks) - ) - ) - ->Array.get(0) - } - - let assignTaskToNode = (task: Types.task, node: Types.node) => { - task.status = Types.Running - node.activeTasks = node.activeTasks + 1 - if node.activeTasks >= node.maxTasks { - node.status = Types.Busy - } - Console.log(`Task ${task.id} assigned to node ${node.id}`) - } - - let scheduleTasks = (self: t) => { - let readyTasks = self.taskQueue->Array.filter(task => isTaskReady(self, task)) - - readyTasks->Array.forEach(task => { - switch getBestNodeForTask(self, task) { - | Some(node) => assignTaskToNode(task, node) - | None => () - } - }) - } - - let checkNodeHeartbeats = (self: t, threshold: float) => { - let now = Date.now() - self.nodes->Map.forEach((node, _id) => { - if now -. node.lastHeartbeat > threshold { - node.status = Types.Offline - Console.log(`Node ${node.id} marked offline due to missed heartbeat`) - } - }) - } -} - -let coordinator = Coordinator.make() -// Integration logic for periodic scheduling would go here diff --git a/praxis/SymbolicEngine/swarm/src/coordinator.ts b/praxis/SymbolicEngine/swarm/src/coordinator.ts deleted file mode 100644 index e357816..0000000 --- a/praxis/SymbolicEngine/swarm/src/coordinator.ts +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm — Task Distribution Coordinator. - * - * This module implements the central orchestrator for the Praxis Swarm. - * It is responsible for distributing symbolic tasks across a cluster -//! of worker nodes, ensuring optimal load balancing and strict -//! adherence to task dependency graphs. - * - * KEY RESPONSIBILITIES: - * 1. **Node Registry**: Manages the lifecycle of active worker nodes and - * their health states. - * 2. **Scheduler**: Assigns pending tasks to the most appropriate node - * based on capabilities (Rust, PHP, PowerShell). - * 3. **Dependency Engine**: Ensures that tasks are only executed once their - * prerequisite symbols have successfully completed. - * 4. **Resilience**: Implements heartbeat monitoring and automatic - * task reassignment for offline or failed nodes. - */ - -import { v4 as uuidv4 } from 'uuid'; -import type { Node, Task, Symbol, Execution, CoordinatorConfig } from './types'; -// ... [other imports] - -export class Coordinator { - /** - * SCHEDULING: Evaluates the task queue and assigns ready tasks - * to available worker nodes. - * - * SELECTION CRITERIA: - * - Prerequisite symbols must be 'completed'. - * - Target node must have the required engine capability. - * - Choice is weighted by current node load (activeTasks / maxTasks). - */ - private scheduleTasks(): void { - const readyTasks = this.taskQueue.filter((task) => this.isTaskReady(task)); - for (const task of readyTasks) { - const node = this.getBestNodeForTask(task); - if (node) { this.assignTaskToNode(task, node); } - } - } - - /** - * HEARTBEAT: Periodically audits the `activeNodes` map. - * If a node's `lastHeartbeat` exceeds the threshold, it is - * marked 'offline' and its running tasks are returned to the queue. - */ - private checkNodeHeartbeats(): void { - // ... [Stale node cleanup logic] - } -} diff --git a/praxis/SymbolicEngine/swarm/src/dispatch.ts b/praxis/SymbolicEngine/swarm/src/dispatch.ts deleted file mode 100644 index 1cf27ac..0000000 --- a/praxis/SymbolicEngine/swarm/src/dispatch.ts +++ /dev/null @@ -1,492 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - Dispatcher - * - * Main dispatcher that: - * - Loads and parses manifest files (YAML/TOML) - * - Distributes symbolic workflows across swarm nodes - * - Coordinates execution state - * - Collects and aggregates results - * - Handles failures and retries - */ - -import { readFileSync, existsSync } from 'fs'; -import { parse as parseYAML } from 'yaml'; -import { parse as parseTOML } from 'toml'; -import { v4 as uuidv4 } from 'uuid'; -import type { - Workflow, - Symbol, - DispatcherConfig, - DispatchResult, - Execution, - WebSocketMessage, - TaskCompleteMessage, - TaskFailedMessage, -} from './types'; -import { Coordinator, createCoordinator } from './coordinator'; -import { StateManager } from './state-manager'; -import { WebSocketServer } from './websocket-server'; -import { Logger } from './logger'; - -export class Dispatcher { - private coordinator: Coordinator; - private stateManager: StateManager; - private wsServer?: WebSocketServer; - private logger: Logger; - private config: DispatcherConfig; - - private activeWorkflows: Map = new Map(); // workflowId -> taskIds - - constructor(config: DispatcherConfig, logger?: Logger) { - this.config = config; - this.logger = logger ?? new Logger('Dispatcher'); - - // Initialize state manager - this.stateManager = new StateManager(config.stateDbPath, this.logger.child('StateManager')); - - // Initialize coordinator - this.coordinator = createCoordinator( - { - maxWorkers: 100, - heartbeatInterval: 5000, - heartbeatTimeout: 15000, - taskRetryLimit: 3, - enableLoadBalancing: true, - priorityQueueEnabled: true, - }, - this.stateManager, - this.logger.child('Coordinator') - ); - - // Initialize WebSocket server if enabled - if (config.enableWebSocket) { - this.wsServer = new WebSocketServer( - config.websocketPort, - this.handleWebSocketMessage.bind(this), - this.logger.child('WebSocketServer') - ); - } - - this.logger.info('Dispatcher initialized'); - } - - // ============================================================================ - // Workflow Loading & Parsing - // ============================================================================ - - /** - * Load workflow from manifest file - */ - loadManifest(manifestPath: string): Workflow { - this.logger.info(`Loading manifest: ${manifestPath}`); - - if (!existsSync(manifestPath)) { - throw new Error(`Manifest file not found: ${manifestPath}`); - } - - const content = readFileSync(manifestPath, 'utf-8'); - const workflow = this.parseManifest(content, manifestPath); - - this.logger.info(`Manifest loaded: ${workflow.name} (${workflow.symbols.length} symbols)`); - return workflow; - } - - /** - * Parse manifest content - */ - private parseManifest(content: string, filePath: string): Workflow { - const ext = filePath.split('.').pop()?.toLowerCase(); - - let parsed: any; - - try { - if (ext === 'yaml' || ext === 'yml') { - parsed = parseYAML(content); - } else if (ext === 'toml') { - parsed = parseTOML(content); - } else { - throw new Error(`Unsupported manifest format: ${ext}`); - } - } catch (error) { - this.logger.error('Failed to parse manifest:', error); - throw new Error(`Manifest parsing failed: ${error instanceof Error ? error.message : String(error)}`); - } - - return this.validateWorkflow(parsed); - } - - /** - * Validate workflow structure - */ - private validateWorkflow(data: any): Workflow { - if (!data.name || typeof data.name !== 'string') { - throw new Error('Workflow must have a name'); - } - - if (!data.version || typeof data.version !== 'string') { - throw new Error('Workflow must have a version'); - } - - if (!Array.isArray(data.symbols)) { - throw new Error('Workflow must have a symbols array'); - } - - const symbols: Symbol[] = data.symbols.map((s: any, index: number) => { - if (!s.name || typeof s.name !== 'string') { - throw new Error(`Symbol at index ${index} must have a name`); - } - - if (!s.type || typeof s.type !== 'string') { - throw new Error(`Symbol ${s.name} must have a type`); - } - - return { - name: s.name, - type: s.type, - context: s.context ?? 'generic', - dispatch: s.dispatch ?? 'internal', - parameters: s.parameters ?? {}, - dependencies: s.dependencies ?? [], - priority: s.priority ?? 0, - timeout: s.timeout ?? 30000, - retries: s.retries ?? 3, - rollback: s.rollback, - } as Symbol; - }); - - return { - name: data.name, - version: data.version, - description: data.description, - symbols, - metadata: data.metadata, - }; - } - - // ============================================================================ - // Workflow Dispatch - // ============================================================================ - - /** - * Dispatch workflow for execution - */ - async dispatch(workflow: Workflow): Promise { - const workflowId = uuidv4(); - const startTime = Date.now(); - - this.logger.info(`Dispatching workflow: ${workflow.name} (${workflowId})`); - - // Submit workflow to coordinator - const taskIds = this.coordinator.submitWorkflow(workflowId, workflow.symbols); - this.activeWorkflows.set(workflowId, taskIds); - - // Wait for workflow to complete - const results = await this.waitForWorkflowCompletion(workflowId, taskIds); - - const duration = Date.now() - startTime; - - const dispatchResult: DispatchResult = { - workflowId, - totalTasks: taskIds.length, - completedTasks: results.filter((r) => r.success).length, - failedTasks: results.filter((r) => !r.success).length, - duration, - results, - }; - - this.logger.info( - `Workflow completed: ${workflow.name} (${dispatchResult.completedTasks}/${dispatchResult.totalTasks} successful, ${duration}ms)` - ); - - return dispatchResult; - } - - /** - * Dispatch workflow from manifest file - */ - async dispatchFromFile(manifestPath: string): Promise { - const workflow = this.loadManifest(manifestPath); - return this.dispatch(workflow); - } - - /** - * Wait for workflow completion - */ - private async waitForWorkflowCompletion( - workflowId: string, - taskIds: string[] - ): Promise> { - return new Promise((resolve) => { - const results: Array<{ success: boolean; output?: unknown; error?: string }> = []; - const completedTasks = new Set(); - - const checkInterval = setInterval(() => { - // Get execution status for all tasks - for (const taskId of taskIds) { - if (completedTasks.has(taskId)) { - continue; - } - - const task = this.stateManager.getTask(taskId); - if (!task) { - continue; - } - - const execution = this.stateManager.getExecution(task.executionId); - if (!execution) { - continue; - } - - if (execution.status === 'completed' || execution.status === 'failed') { - completedTasks.add(taskId); - - if (execution.result) { - results.push({ - success: execution.result.success, - output: execution.result.output, - error: execution.result.error, - }); - } else { - results.push({ - success: execution.status === 'completed', - error: execution.status === 'failed' ? 'Unknown error' : undefined, - }); - } - } - } - - // Check if all tasks are complete - if (completedTasks.size === taskIds.length) { - clearInterval(checkInterval); - this.activeWorkflows.delete(workflowId); - resolve(results); - } - }, 100); - - // Timeout after 10 minutes - setTimeout(() => { - clearInterval(checkInterval); - this.logger.error(`Workflow timeout: ${workflowId}`); - - // Add error results for incomplete tasks - for (const taskId of taskIds) { - if (!completedTasks.has(taskId)) { - results.push({ - success: false, - error: 'Workflow timeout', - }); - } - } - - this.activeWorkflows.delete(workflowId); - resolve(results); - }, 600000); - }); - } - - // ============================================================================ - // WebSocket Message Handling - // ============================================================================ - - /** - * Handle WebSocket messages from workers - */ - private handleWebSocketMessage(message: WebSocketMessage, senderId: string): void { - this.logger.debug(`WebSocket message from ${senderId}: ${message.type}`); - - switch (message.type) { - case 'register': - this.handleWorkerRegistration(message); - break; - - case 'heartbeat': - this.handleWorkerHeartbeat(message); - break; - - case 'task_complete': - this.handleTaskComplete(message); - break; - - case 'task_failed': - this.handleTaskFailed(message); - break; - - default: - this.logger.warn(`Unknown message type from worker: ${message.type}`); - } - } - - /** - * Handle worker registration - */ - private handleWorkerRegistration(message: WebSocketMessage): void { - const payload = message.payload as any; - if (payload && payload.node) { - this.coordinator.registerNode(payload.node); - this.logger.info(`Worker registered: ${payload.node.name}`); - } - } - - /** - * Handle worker heartbeat - */ - private handleWorkerHeartbeat(message: WebSocketMessage): void { - const payload = message.payload as any; - if (payload && payload.nodeId && payload.health) { - this.coordinator.updateHeartbeat(payload.nodeId, payload.health); - } - } - - /** - * Handle task completion - */ - private handleTaskComplete(message: WebSocketMessage): void { - const payload = message.payload as TaskCompleteMessage; - if (payload && payload.taskId && payload.result) { - // Update execution with result - const task = this.stateManager.getTask(payload.taskId); - if (task) { - const execution = this.stateManager.getExecution(task.executionId); - if (execution) { - execution.result = payload.result; - execution.status = 'completed'; - execution.completedAt = Date.now(); - execution.updatedAt = Date.now(); - this.stateManager.saveExecution(execution); - } - } - - this.coordinator.completeTask(payload.taskId, true); - } - } - - /** - * Handle task failure - */ - private handleTaskFailed(message: WebSocketMessage): void { - const payload = message.payload as TaskFailedMessage; - if (payload && payload.taskId && payload.error) { - // Update execution with error - const task = this.stateManager.getTask(payload.taskId); - if (task) { - const execution = this.stateManager.getExecution(task.executionId); - if (execution) { - execution.result = { - success: false, - error: payload.error, - stackTrace: payload.stackTrace, - duration: 0, - timestamp: Date.now(), - }; - execution.status = 'failed'; - execution.completedAt = Date.now(); - execution.updatedAt = Date.now(); - this.stateManager.saveExecution(execution); - } - } - - this.coordinator.completeTask(payload.taskId, false, payload.error); - } - } - - // ============================================================================ - // Server Management - // ============================================================================ - - /** - * Start dispatcher server - */ - async start(): Promise { - this.logger.info('Starting dispatcher...'); - - if (this.wsServer) { - await this.wsServer.start(); - this.logger.info(`WebSocket server started on port ${this.config.websocketPort}`); - } - - // Set up coordinator message handler - this.coordinator.setMessageHandler((message) => { - if (this.wsServer) { - this.wsServer.broadcast(message); - } - }); - - this.logger.info('Dispatcher started'); - } - - /** - * Stop dispatcher server - */ - async stop(): Promise { - this.logger.info('Stopping dispatcher...'); - - this.coordinator.shutdown(); - - if (this.wsServer) { - await this.wsServer.stop(); - } - - this.stateManager.close(); - - this.logger.info('Dispatcher stopped'); - } - - // ============================================================================ - // Statistics & Monitoring - // ============================================================================ - - /** - * Get dispatcher statistics - */ - getStats(): { - coordinator: ReturnType; - activeWorkflows: number; - state: Record; - } { - return { - coordinator: this.coordinator.getStats(), - activeWorkflows: this.activeWorkflows.size, - state: this.stateManager.getStats(), - }; - } - - /** - * Get all active workflows - */ - getActiveWorkflows(): Array<{ workflowId: string; taskCount: number }> { - return Array.from(this.activeWorkflows.entries()).map(([workflowId, taskIds]) => ({ - workflowId, - taskCount: taskIds.length, - })); - } - - /** - * Get workflow execution status - */ - getWorkflowStatus(workflowId: string): { - executions: Execution[]; - totalTasks: number; - completedTasks: number; - failedTasks: number; - runningTasks: number; - } { - const executions = this.stateManager.getExecutionsByWorkflow(workflowId); - - return { - executions, - totalTasks: executions.length, - completedTasks: executions.filter((e) => e.status === 'completed').length, - failedTasks: executions.filter((e) => e.status === 'failed').length, - runningTasks: executions.filter((e) => e.status === 'running').length, - }; - } -} - -/** - * Create a dispatcher instance - */ -export function createDispatcher(config: DispatcherConfig, logger?: Logger): Dispatcher { - return new Dispatcher(config, logger); -} diff --git a/praxis/SymbolicEngine/swarm/src/executor.ts b/praxis/SymbolicEngine/swarm/src/executor.ts deleted file mode 100644 index 6fbb764..0000000 --- a/praxis/SymbolicEngine/swarm/src/executor.ts +++ /dev/null @@ -1,551 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - Symbol Executor - * - * Executes symbolic operations by dispatching to appropriate backend engines - * (Rust injector, PHP engine, PowerShell engine, or internal handlers). - */ - -import { spawn } from 'child_process'; -import { promisify } from 'util'; -import { exec } from 'child_process'; -import type { - Symbol, - ExecutionResult, - ExecutorContext, - ExecutorBackend, - BackendConfig, -} from './types'; -import { Logger } from './logger'; - -const execAsync = promisify(exec); - -/** - * Main executor class that coordinates symbol execution - */ -export class Executor { - private backends: Map = new Map(); - private logger: Logger; - - constructor(config: BackendConfig, logger?: Logger) { - this.logger = logger ?? new Logger('Executor'); - this.initializeBackends(config); - } - - /** - * Initialize backend executors based on configuration - */ - private initializeBackends(config: BackendConfig): void { - if (config.rustInjector?.enabled) { - this.backends.set('rust_injector', new RustInjectorBackend(config.rustInjector, this.logger)); - this.logger.info('Rust injector backend initialized'); - } - - if (config.phpEngine?.enabled) { - this.backends.set('php_engine', new PHPEngineBackend(config.phpEngine, this.logger)); - this.logger.info('PHP engine backend initialized'); - } - - if (config.powershellEngine?.enabled) { - this.backends.set( - 'powershell_engine', - new PowerShellEngineBackend(config.powershellEngine, this.logger) - ); - this.logger.info('PowerShell engine backend initialized'); - } - - // Internal backend is always available - this.backends.set('internal', new InternalBackend(this.logger)); - this.logger.info('Internal backend initialized'); - } - - /** - * Execute a symbol - */ - async execute(context: ExecutorContext): Promise { - const startTime = Date.now(); - const { symbol, executionId } = context; - - this.logger.info(`Executing symbol: ${symbol.name} (${executionId})`); - - try { - // Find appropriate backend - const backend = this.getBackendForSymbol(symbol); - if (!backend) { - throw new Error(`No backend available for dispatch target: ${symbol.dispatch}`); - } - - // Check backend health - const healthy = await backend.healthCheck(); - if (!healthy) { - throw new Error(`Backend ${symbol.dispatch} is not healthy`); - } - - // Execute with timeout - const timeout = symbol.timeout ?? 30000; - const result = await this.executeWithTimeout(backend, context, timeout); - - const duration = Date.now() - startTime; - this.logger.info(`Symbol executed successfully: ${symbol.name} (${duration}ms)`); - - return { - ...result, - duration, - timestamp: Date.now(), - }; - } catch (error) { - const duration = Date.now() - startTime; - const errorMessage = error instanceof Error ? error.message : String(error); - const stackTrace = error instanceof Error ? error.stack : undefined; - - this.logger.error(`Symbol execution failed: ${symbol.name}`, error); - - return { - success: false, - error: errorMessage, - stackTrace, - duration, - timestamp: Date.now(), - }; - } - } - - /** - * Execute with timeout - */ - private async executeWithTimeout( - backend: ExecutorBackend, - context: ExecutorContext, - timeoutMs: number - ): Promise { - return Promise.race([ - backend.execute(context), - new Promise((_, reject) => - setTimeout(() => reject(new Error(`Execution timeout after ${timeoutMs}ms`)), timeoutMs) - ), - ]); - } - - /** - * Get backend for symbol - */ - private getBackendForSymbol(symbol: Symbol): ExecutorBackend | null { - const backendKey = symbol.dispatch; - return this.backends.get(backendKey) ?? null; - } - - /** - * Execute rollback operation - */ - async executeRollback(symbol: Symbol, context: ExecutorContext): Promise { - if (!symbol.rollback) { - this.logger.warn(`No rollback defined for symbol: ${symbol.name}`); - return { - success: true, - output: 'No rollback operation defined', - duration: 0, - timestamp: Date.now(), - }; - } - - this.logger.info(`Executing rollback for symbol: ${symbol.name}`); - - const rollbackContext: ExecutorContext = { - ...context, - symbol: symbol.rollback, - }; - - return this.execute(rollbackContext); - } - - /** - * Check health of all backends - */ - async healthCheck(): Promise> { - const health: Record = {}; - - for (const [name, backend] of this.backends.entries()) { - try { - health[name] = await backend.healthCheck(); - } catch (error) { - this.logger.error(`Health check failed for ${name}:`, error); - health[name] = false; - } - } - - return health; - } -} - -// ============================================================================ -// Backend Implementations -// ============================================================================ - -/** - * Rust Injector Backend - */ -class RustInjectorBackend implements ExecutorBackend { - constructor( - private config: NonNullable, - private logger: Logger - ) {} - - async execute(context: ExecutorContext): Promise { - const { symbol } = context; - const args = this.buildArgs(symbol); - - this.logger.debug(`Executing Rust injector: ${this.config.binaryPath} ${args.join(' ')}`); - - return new Promise((resolve) => { - const proc = spawn(this.config.binaryPath, args); - - let stdout = ''; - let stderr = ''; - - proc.stdout.on('data', (data) => { - stdout += data.toString(); - }); - - proc.stderr.on('data', (data) => { - stderr += data.toString(); - }); - - proc.on('close', (code) => { - if (code === 0) { - resolve({ - success: true, - output: this.parseOutput(stdout), - duration: 0, - timestamp: Date.now(), - }); - } else { - resolve({ - success: false, - error: `Rust injector exited with code ${code}`, - stackTrace: stderr, - duration: 0, - timestamp: Date.now(), - }); - } - }); - - proc.on('error', (error) => { - resolve({ - success: false, - error: error.message, - stackTrace: error.stack, - duration: 0, - timestamp: Date.now(), - }); - }); - }); - } - - canHandle(symbol: Symbol): boolean { - return symbol.dispatch === 'rust_injector'; - } - - async healthCheck(): Promise { - try { - const { stdout } = await execAsync(`${this.config.binaryPath} --version`); - return stdout.includes('wp_injector'); - } catch (error) { - this.logger.error('Rust injector health check failed:', error); - return false; - } - } - - private buildArgs(symbol: Symbol): string[] { - const args: string[] = []; - - args.push('--symbol', symbol.name); - args.push('--type', symbol.type); - args.push('--context', symbol.context); - - if (Object.keys(symbol.parameters).length > 0) { - args.push('--params', JSON.stringify(symbol.parameters)); - } - - return args; - } - - private parseOutput(stdout: string): unknown { - try { - return JSON.parse(stdout); - } catch { - return stdout.trim(); - } - } -} - -/** - * PHP Engine Backend - */ -class PHPEngineBackend implements ExecutorBackend { - constructor( - private config: NonNullable, - private logger: Logger - ) {} - - async execute(context: ExecutorContext): Promise { - const { symbol } = context; - const args = this.buildArgs(symbol); - - this.logger.debug(`Executing PHP engine: ${this.config.phpBinary} ${args.join(' ')}`); - - return new Promise((resolve) => { - const proc = spawn(this.config.phpBinary, args); - - let stdout = ''; - let stderr = ''; - - proc.stdout.on('data', (data) => { - stdout += data.toString(); - }); - - proc.stderr.on('data', (data) => { - stderr += data.toString(); - }); - - proc.on('close', (code) => { - if (code === 0) { - resolve({ - success: true, - output: this.parseOutput(stdout), - duration: 0, - timestamp: Date.now(), - }); - } else { - resolve({ - success: false, - error: `PHP engine exited with code ${code}`, - stackTrace: stderr, - duration: 0, - timestamp: Date.now(), - }); - } - }); - - proc.on('error', (error) => { - resolve({ - success: false, - error: error.message, - stackTrace: error.stack, - duration: 0, - timestamp: Date.now(), - }); - }); - }); - } - - canHandle(symbol: Symbol): boolean { - return symbol.dispatch === 'php_engine'; - } - - async healthCheck(): Promise { - try { - const { stdout } = await execAsync(`${this.config.phpBinary} --version`); - return stdout.toLowerCase().includes('php'); - } catch (error) { - this.logger.error('PHP engine health check failed:', error); - return false; - } - } - - private buildArgs(symbol: Symbol): string[] { - const args: string[] = []; - - args.push(this.config.scriptPath); - args.push('--symbol', symbol.name); - args.push('--type', symbol.type); - args.push('--context', symbol.context); - - if (Object.keys(symbol.parameters).length > 0) { - args.push('--params', JSON.stringify(symbol.parameters)); - } - - return args; - } - - private parseOutput(stdout: string): unknown { - try { - return JSON.parse(stdout); - } catch { - return stdout.trim(); - } - } -} - -/** - * PowerShell Engine Backend - */ -class PowerShellEngineBackend implements ExecutorBackend { - constructor( - private config: NonNullable, - private logger: Logger - ) {} - - async execute(context: ExecutorContext): Promise { - const { symbol } = context; - const args = this.buildArgs(symbol); - - this.logger.debug(`Executing PowerShell engine: ${this.config.pwshBinary} ${args.join(' ')}`); - - return new Promise((resolve) => { - const proc = spawn(this.config.pwshBinary, args); - - let stdout = ''; - let stderr = ''; - - proc.stdout.on('data', (data) => { - stdout += data.toString(); - }); - - proc.stderr.on('data', (data) => { - stderr += data.toString(); - }); - - proc.on('close', (code) => { - if (code === 0) { - resolve({ - success: true, - output: this.parseOutput(stdout), - duration: 0, - timestamp: Date.now(), - }); - } else { - resolve({ - success: false, - error: `PowerShell engine exited with code ${code}`, - stackTrace: stderr, - duration: 0, - timestamp: Date.now(), - }); - } - }); - - proc.on('error', (error) => { - resolve({ - success: false, - error: error.message, - stackTrace: error.stack, - duration: 0, - timestamp: Date.now(), - }); - }); - }); - } - - canHandle(symbol: Symbol): boolean { - return symbol.dispatch === 'powershell_engine'; - } - - async healthCheck(): Promise { - try { - const { stdout } = await execAsync(`${this.config.pwshBinary} -Version`); - return stdout.toLowerCase().includes('powershell'); - } catch (error) { - this.logger.error('PowerShell engine health check failed:', error); - return false; - } - } - - private buildArgs(symbol: Symbol): string[] { - const args: string[] = []; - - args.push('-File', this.config.scriptPath); - args.push('-SymbolName', symbol.name); - args.push('-SymbolType', symbol.type); - args.push('-Context', symbol.context); - - if (Object.keys(symbol.parameters).length > 0) { - args.push('-Parameters', JSON.stringify(symbol.parameters)); - } - - return args; - } - - private parseOutput(stdout: string): unknown { - try { - return JSON.parse(stdout); - } catch { - return stdout.trim(); - } - } -} - -/** - * Internal Backend (for built-in operations) - */ -class InternalBackend implements ExecutorBackend { - constructor(private logger: Logger) {} - - async execute(context: ExecutorContext): Promise { - const { symbol } = context; - - this.logger.debug(`Executing internal operation: ${symbol.name}`); - - // Built-in operations - switch (symbol.name) { - case 'noop': - return this.noop(); - case 'echo': - return this.echo(symbol.parameters); - case 'delay': - return this.delay(symbol.parameters); - default: - return { - success: false, - error: `Unknown internal operation: ${symbol.name}`, - duration: 0, - timestamp: Date.now(), - }; - } - } - - canHandle(symbol: Symbol): boolean { - return symbol.dispatch === 'internal'; - } - - async healthCheck(): Promise { - return true; // Internal backend is always healthy - } - - private async noop(): Promise { - return { - success: true, - output: 'noop', - duration: 0, - timestamp: Date.now(), - }; - } - - private async echo(parameters: Record): Promise { - return { - success: true, - output: parameters.message ?? parameters, - duration: 0, - timestamp: Date.now(), - }; - } - - private async delay(parameters: Record): Promise { - const ms = Number(parameters.ms ?? 1000); - await new Promise((resolve) => setTimeout(resolve, ms)); - - return { - success: true, - output: `Delayed ${ms}ms`, - duration: ms, - timestamp: Date.now(), - }; - } -} - -/** - * Create an executor instance - */ -export function createExecutor(config: BackendConfig, logger?: Logger): Executor { - return new Executor(config, logger); -} diff --git a/praxis/SymbolicEngine/swarm/src/index.ts b/praxis/SymbolicEngine/swarm/src/index.ts deleted file mode 100644 index 2e31801..0000000 --- a/praxis/SymbolicEngine/swarm/src/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - Main Entry Point - * - * Exports all public APIs for programmatic usage - */ - -// Core types -export * from './types'; - -// State management -export { StateManager } from './state-manager'; - -// Logging -export { Logger, createLogger } from './logger'; - -// Execution -export { Executor, createExecutor } from './executor'; - -// Coordination -export { Coordinator, createCoordinator } from './coordinator'; - -// Worker -export { Worker, createWorker } from './worker'; - -// Dispatcher -export { Dispatcher, createDispatcher } from './dispatch'; - -// WebSocket server -export { WebSocketServer, createWebSocketServer } from './websocket-server'; - -// Version -export const VERSION = '0.1.0'; -export const NAME = '@wp-praxis/swarm'; diff --git a/praxis/SymbolicEngine/swarm/src/logger.ts b/praxis/SymbolicEngine/swarm/src/logger.ts deleted file mode 100644 index 79cc704..0000000 --- a/praxis/SymbolicEngine/swarm/src/logger.ts +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - Logger - * - * Centralized logging with support for console and file output, - * different log levels, and structured logging. - */ - -import { writeFileSync, appendFileSync, existsSync, mkdirSync } from 'fs'; -import { dirname } from 'path'; -import type { LoggingConfig } from './types'; - -type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'verbose'; - -const LOG_LEVELS: Record = { - error: 0, - warn: 1, - info: 2, - debug: 3, - verbose: 4, -}; - -interface LogEntry { - timestamp: string; - level: LogLevel; - context: string; - message: string; - data?: unknown; -} - -export class Logger { - private context: string; - private static config: LoggingConfig = { - level: 'info', - console: true, - format: 'text', - }; - - constructor(context: string) { - this.context = context; - } - - /** - * Configure global logger settings - */ - static configure(config: LoggingConfig): void { - Logger.config = config; - - // Create log directory if file logging is enabled - if (config.file) { - const dir = dirname(config.file); - if (!existsSync(dir)) { - mkdirSync(dir, { recursive: true }); - } - } - } - - /** - * Log an error message - */ - error(message: string, ...data: unknown[]): void { - this.log('error', message, ...data); - } - - /** - * Log a warning message - */ - warn(message: string, ...data: unknown[]): void { - this.log('warn', message, ...data); - } - - /** - * Log an info message - */ - info(message: string, ...data: unknown[]): void { - this.log('info', message, ...data); - } - - /** - * Log a debug message - */ - debug(message: string, ...data: unknown[]): void { - this.log('debug', message, ...data); - } - - /** - * Log a verbose message - */ - verbose(message: string, ...data: unknown[]): void { - this.log('verbose', message, ...data); - } - - /** - * Core logging method - */ - private log(level: LogLevel, message: string, ...data: unknown[]): void { - // Check if this log level should be output - if (LOG_LEVELS[level] > LOG_LEVELS[Logger.config.level]) { - return; - } - - const entry: LogEntry = { - timestamp: new Date().toISOString(), - level, - context: this.context, - message, - data: data.length > 0 ? data : undefined, - }; - - // Console output - if (Logger.config.console) { - this.outputToConsole(entry); - } - - // File output - if (Logger.config.file) { - this.outputToFile(entry); - } - } - - /** - * Output log entry to console - */ - private outputToConsole(entry: LogEntry): void { - const formatted = this.formatEntry(entry); - - switch (entry.level) { - case 'error': - console.error(formatted); - break; - case 'warn': - console.warn(formatted); - break; - case 'debug': - case 'verbose': - console.log(formatted); - break; - default: - console.log(formatted); - } - } - - /** - * Output log entry to file - */ - private outputToFile(entry: LogEntry): void { - if (!Logger.config.file) return; - - const formatted = - Logger.config.format === 'json' - ? JSON.stringify(entry) + '\n' - : this.formatEntry(entry) + '\n'; - - try { - appendFileSync(Logger.config.file, formatted, 'utf8'); - } catch (error) { - console.error('Failed to write to log file:', error); - } - } - - /** - * Format log entry for text output - */ - private formatEntry(entry: LogEntry): string { - const levelStr = entry.level.toUpperCase().padEnd(7); - const contextStr = `[${entry.context}]`.padEnd(20); - const dataStr = entry.data ? ' ' + JSON.stringify(entry.data) : ''; - - return `${entry.timestamp} ${levelStr} ${contextStr} ${entry.message}${dataStr}`; - } - - /** - * Create a child logger with additional context - */ - child(subContext: string): Logger { - return new Logger(`${this.context}:${subContext}`); - } - - /** - * Measure execution time of an async operation - */ - async measure(operation: string, fn: () => Promise): Promise { - const start = Date.now(); - this.debug(`Starting: ${operation}`); - - try { - const result = await fn(); - const duration = Date.now() - start; - this.info(`Completed: ${operation} (${duration}ms)`); - return result; - } catch (error) { - const duration = Date.now() - start; - this.error(`Failed: ${operation} (${duration}ms)`, error); - throw error; - } - } -} - -/** - * Create a logger instance - */ -export function createLogger(context: string): Logger { - return new Logger(context); -} diff --git a/praxis/SymbolicEngine/swarm/src/state-manager.ts b/praxis/SymbolicEngine/swarm/src/state-manager.ts deleted file mode 100644 index 36e617d..0000000 --- a/praxis/SymbolicEngine/swarm/src/state-manager.ts +++ /dev/null @@ -1,610 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - State Manager - * - * Distributed state management using SQLite with transaction support, - * state synchronization, and recovery capabilities. - */ - -import Database from 'better-sqlite3'; -import { createHash } from 'crypto'; -import type { - StateTransaction, - StateOperation, - StateSnapshot, - Execution, - Task, - Node, -} from './types'; -import { Logger } from './logger'; - -export class StateManager { - private db: Database.Database; - private logger: Logger; - private currentTransaction: StateTransaction | null = null; - - constructor(dbPath: string, logger?: Logger) { - this.logger = logger ?? new Logger('StateManager'); - this.db = new Database(dbPath); - this.initializeSchema(); - this.logger.info(`State manager initialized with database: ${dbPath}`); - } - - /** - * Initialize database schema - */ - private initializeSchema(): void { - // State table - generic key-value store - this.db.exec(` - CREATE TABLE IF NOT EXISTS state ( - key TEXT PRIMARY KEY, - value TEXT NOT NULL, - type TEXT NOT NULL, - updated_at INTEGER NOT NULL, - checksum TEXT NOT NULL - ); - `); - - // Executions table - this.db.exec(` - CREATE TABLE IF NOT EXISTS executions ( - id TEXT PRIMARY KEY, - workflow_id TEXT NOT NULL, - symbol_name TEXT NOT NULL, - status TEXT NOT NULL, - node_id TEXT, - result TEXT, - attempts INTEGER NOT NULL DEFAULT 0, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - started_at INTEGER, - completed_at INTEGER - ); - CREATE INDEX IF NOT EXISTS idx_executions_workflow ON executions(workflow_id); - CREATE INDEX IF NOT EXISTS idx_executions_status ON executions(status); - `); - - // Tasks table - this.db.exec(` - CREATE TABLE IF NOT EXISTS tasks ( - id TEXT PRIMARY KEY, - execution_id TEXT NOT NULL, - symbol TEXT NOT NULL, - priority INTEGER NOT NULL, - dependencies TEXT NOT NULL, - status TEXT NOT NULL, - assigned_to TEXT, - created_at INTEGER NOT NULL, - assigned_at INTEGER, - FOREIGN KEY(execution_id) REFERENCES executions(id) - ); - CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status); - CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority DESC); - `); - - // Nodes table - this.db.exec(` - CREATE TABLE IF NOT EXISTS nodes ( - id TEXT PRIMARY KEY, - name TEXT NOT NULL, - status TEXT NOT NULL, - capabilities TEXT NOT NULL, - health TEXT NOT NULL, - last_heartbeat INTEGER NOT NULL, - connected_at INTEGER NOT NULL, - metadata TEXT - ); - CREATE INDEX IF NOT EXISTS idx_nodes_status ON nodes(status); - `); - - // Transactions log table - this.db.exec(` - CREATE TABLE IF NOT EXISTS transaction_log ( - id TEXT PRIMARY KEY, - operations TEXT NOT NULL, - timestamp INTEGER NOT NULL, - committed INTEGER NOT NULL DEFAULT 0 - ); - CREATE INDEX IF NOT EXISTS idx_transactions_timestamp ON transaction_log(timestamp); - `); - - // Snapshots table - this.db.exec(` - CREATE TABLE IF NOT EXISTS snapshots ( - timestamp INTEGER PRIMARY KEY, - data TEXT NOT NULL, - checksum TEXT NOT NULL - ); - `); - - this.logger.debug('Database schema initialized'); - } - - // ============================================================================ - // Generic State Operations - // ============================================================================ - - /** - * Set a state value - */ - set(key: string, value: unknown, type: string = 'generic'): void { - const serialized = JSON.stringify(value); - const checksum = this.calculateChecksum(serialized); - const timestamp = Date.now(); - - const stmt = this.db.prepare(` - INSERT OR REPLACE INTO state (key, value, type, updated_at, checksum) - VALUES (?, ?, ?, ?, ?) - `); - - stmt.run(key, serialized, type, timestamp, checksum); - - if (this.currentTransaction) { - this.currentTransaction.operations.push({ - type: 'set', - key, - value, - }); - } - - this.logger.debug(`State set: ${key} = ${serialized.substring(0, 100)}...`); - } - - /** - * Get a state value - */ - get(key: string): T | null { - const stmt = this.db.prepare('SELECT value FROM state WHERE key = ?'); - const row = stmt.get(key) as { value: string } | undefined; - - if (!row) { - return null; - } - - try { - return JSON.parse(row.value) as T; - } catch (error) { - this.logger.error(`Failed to parse state value for key ${key}:`, error); - return null; - } - } - - /** - * Delete a state value - */ - delete(key: string): boolean { - const previousValue = this.get(key); - const stmt = this.db.prepare('DELETE FROM state WHERE key = ?'); - const result = stmt.run(key); - - if (this.currentTransaction && result.changes > 0) { - this.currentTransaction.operations.push({ - type: 'delete', - key, - previousValue, - }); - } - - return result.changes > 0; - } - - /** - * Update a state value (partial update for objects) - */ - update(key: string, updates: Record): void { - const current = this.get>(key) ?? {}; - const updated = { ...current, ...updates }; - this.set(key, updated); - - if (this.currentTransaction) { - this.currentTransaction.operations.push({ - type: 'update', - key, - value: updates, - previousValue: current, - }); - } - } - - // ============================================================================ - // Execution Management - // ============================================================================ - - saveExecution(execution: Execution): void { - const stmt = this.db.prepare(` - INSERT OR REPLACE INTO executions - (id, workflow_id, symbol_name, status, node_id, result, attempts, - created_at, updated_at, started_at, completed_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - `); - - stmt.run( - execution.id, - execution.workflowId, - execution.symbolName, - execution.status, - execution.nodeId ?? null, - execution.result ? JSON.stringify(execution.result) : null, - execution.attempts, - execution.createdAt, - execution.updatedAt, - execution.startedAt ?? null, - execution.completedAt ?? null - ); - - this.logger.debug(`Execution saved: ${execution.id} (${execution.status})`); - } - - getExecution(id: string): Execution | null { - const stmt = this.db.prepare('SELECT * FROM executions WHERE id = ?'); - const row = stmt.get(id) as any; - - if (!row) { - return null; - } - - return { - id: row.id, - workflowId: row.workflow_id, - symbolName: row.symbol_name, - status: row.status, - nodeId: row.node_id ?? undefined, - result: row.result ? JSON.parse(row.result) : undefined, - attempts: row.attempts, - createdAt: row.created_at, - updatedAt: row.updated_at, - startedAt: row.started_at ?? undefined, - completedAt: row.completed_at ?? undefined, - }; - } - - getExecutionsByWorkflow(workflowId: string): Execution[] { - const stmt = this.db.prepare('SELECT * FROM executions WHERE workflow_id = ?'); - const rows = stmt.all(workflowId) as any[]; - - return rows.map((row) => ({ - id: row.id, - workflowId: row.workflow_id, - symbolName: row.symbol_name, - status: row.status, - nodeId: row.node_id ?? undefined, - result: row.result ? JSON.parse(row.result) : undefined, - attempts: row.attempts, - createdAt: row.created_at, - updatedAt: row.updated_at, - startedAt: row.started_at ?? undefined, - completedAt: row.completed_at ?? undefined, - })); - } - - // ============================================================================ - // Task Management - // ============================================================================ - - saveTask(task: Task): void { - const stmt = this.db.prepare(` - INSERT OR REPLACE INTO tasks - (id, execution_id, symbol, priority, dependencies, status, assigned_to, created_at, assigned_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) - `); - - stmt.run( - task.id, - task.executionId, - JSON.stringify(task.symbol), - task.priority, - JSON.stringify(task.dependencies), - task.status, - task.assignedTo ?? null, - task.createdAt, - task.assignedAt ?? null - ); - - this.logger.debug(`Task saved: ${task.id} (${task.status})`); - } - - getTask(id: string): Task | null { - const stmt = this.db.prepare('SELECT * FROM tasks WHERE id = ?'); - const row = stmt.get(id) as any; - - if (!row) { - return null; - } - - return { - id: row.id, - executionId: row.execution_id, - symbol: JSON.parse(row.symbol), - priority: row.priority, - dependencies: JSON.parse(row.dependencies), - status: row.status, - assignedTo: row.assigned_to ?? undefined, - createdAt: row.created_at, - assignedAt: row.assigned_at ?? undefined, - }; - } - - getTasksByStatus(status: string): Task[] { - const stmt = this.db.prepare('SELECT * FROM tasks WHERE status = ? ORDER BY priority DESC'); - const rows = stmt.all(status) as any[]; - - return rows.map((row) => ({ - id: row.id, - executionId: row.execution_id, - symbol: JSON.parse(row.symbol), - priority: row.priority, - dependencies: JSON.parse(row.dependencies), - status: row.status, - assignedTo: row.assigned_to ?? undefined, - createdAt: row.created_at, - assignedAt: row.assigned_at ?? undefined, - })); - } - - // ============================================================================ - // Node Management - // ============================================================================ - - saveNode(node: Node): void { - const stmt = this.db.prepare(` - INSERT OR REPLACE INTO nodes - (id, name, status, capabilities, health, last_heartbeat, connected_at, metadata) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - `); - - stmt.run( - node.id, - node.name, - node.status, - JSON.stringify(node.capabilities), - JSON.stringify(node.health), - node.lastHeartbeat, - node.connectedAt, - node.metadata ? JSON.stringify(node.metadata) : null - ); - - this.logger.debug(`Node saved: ${node.id} (${node.status})`); - } - - getNode(id: string): Node | null { - const stmt = this.db.prepare('SELECT * FROM nodes WHERE id = ?'); - const row = stmt.get(id) as any; - - if (!row) { - return null; - } - - return { - id: row.id, - name: row.name, - status: row.status, - capabilities: JSON.parse(row.capabilities), - health: JSON.parse(row.health), - lastHeartbeat: row.last_heartbeat, - connectedAt: row.connected_at, - metadata: row.metadata ? JSON.parse(row.metadata) : undefined, - }; - } - - getAllNodes(): Node[] { - const stmt = this.db.prepare('SELECT * FROM nodes'); - const rows = stmt.all() as any[]; - - return rows.map((row) => ({ - id: row.id, - name: row.name, - status: row.status, - capabilities: JSON.parse(row.capabilities), - health: JSON.parse(row.health), - lastHeartbeat: row.last_heartbeat, - connectedAt: row.connected_at, - metadata: row.metadata ? JSON.parse(row.metadata) : undefined, - })); - } - - // ============================================================================ - // Transaction Support - // ============================================================================ - - beginTransaction(id: string): void { - if (this.currentTransaction) { - throw new Error('Transaction already in progress'); - } - - this.currentTransaction = { - id, - operations: [], - timestamp: Date.now(), - committed: false, - }; - - this.db.prepare('BEGIN TRANSACTION').run(); - this.logger.debug(`Transaction started: ${id}`); - } - - commitTransaction(): void { - if (!this.currentTransaction) { - throw new Error('No transaction in progress'); - } - - // Save transaction log - const stmt = this.db.prepare(` - INSERT INTO transaction_log (id, operations, timestamp, committed) - VALUES (?, ?, ?, 1) - `); - - stmt.run( - this.currentTransaction.id, - JSON.stringify(this.currentTransaction.operations), - this.currentTransaction.timestamp - ); - - this.db.prepare('COMMIT').run(); - this.logger.info(`Transaction committed: ${this.currentTransaction.id}`); - this.currentTransaction = null; - } - - rollbackTransaction(): void { - if (!this.currentTransaction) { - throw new Error('No transaction in progress'); - } - - this.db.prepare('ROLLBACK').run(); - this.logger.warn(`Transaction rolled back: ${this.currentTransaction.id}`); - this.currentTransaction = null; - } - - // ============================================================================ - // Snapshot & Recovery - // ============================================================================ - - createSnapshot(): StateSnapshot { - const timestamp = Date.now(); - const stmt = this.db.prepare('SELECT key, value FROM state'); - const rows = stmt.all() as Array<{ key: string; value: string }>; - - const data: Record = {}; - for (const row of rows) { - data[row.key] = JSON.parse(row.value); - } - - const serialized = JSON.stringify(data); - const checksum = this.calculateChecksum(serialized); - - // Save snapshot - const insertStmt = this.db.prepare(` - INSERT INTO snapshots (timestamp, data, checksum) - VALUES (?, ?, ?) - `); - insertStmt.run(timestamp, serialized, checksum); - - this.logger.info(`Snapshot created: ${timestamp} (checksum: ${checksum})`); - - return { timestamp, data, checksum }; - } - - restoreSnapshot(timestamp: number): boolean { - const stmt = this.db.prepare('SELECT data, checksum FROM snapshots WHERE timestamp = ?'); - const row = stmt.get(timestamp) as { data: string; checksum: string } | undefined; - - if (!row) { - this.logger.error(`Snapshot not found: ${timestamp}`); - return false; - } - - // Verify checksum - const calculatedChecksum = this.calculateChecksum(row.data); - if (calculatedChecksum !== row.checksum) { - this.logger.error('Snapshot checksum mismatch - data may be corrupted'); - return false; - } - - const data = JSON.parse(row.data) as Record; - - // Clear current state - this.db.prepare('DELETE FROM state').run(); - - // Restore snapshot data - const insertStmt = this.db.prepare(` - INSERT INTO state (key, value, type, updated_at, checksum) - VALUES (?, ?, ?, ?, ?) - `); - - for (const [key, value] of Object.entries(data)) { - const serialized = JSON.stringify(value); - const checksum = this.calculateChecksum(serialized); - insertStmt.run(key, serialized, 'generic', timestamp, checksum); - } - - this.logger.info(`Snapshot restored: ${timestamp}`); - return true; - } - - // ============================================================================ - // Utilities - // ============================================================================ - - private calculateChecksum(data: string): string { - return createHash('sha256').update(data).digest('hex'); - } - - /** - * Clean up old data - */ - cleanup(olderThanMs: number): void { - const cutoff = Date.now() - olderThanMs; - - // Clean old completed executions - const execStmt = this.db.prepare(` - DELETE FROM executions - WHERE status IN ('completed', 'failed', 'cancelled') - AND completed_at < ? - `); - const execResult = execStmt.run(cutoff); - - // Clean old transactions - const txStmt = this.db.prepare('DELETE FROM transaction_log WHERE timestamp < ?'); - const txResult = txStmt.run(cutoff); - - // Clean old snapshots (keep last 10) - const snapStmt = this.db.prepare(` - DELETE FROM snapshots - WHERE timestamp NOT IN ( - SELECT timestamp FROM snapshots ORDER BY timestamp DESC LIMIT 10 - ) - `); - const snapResult = snapStmt.run(); - - this.logger.info( - `Cleanup complete: ${execResult.changes} executions, ${txResult.changes} transactions, ${snapResult.changes} snapshots removed` - ); - } - - /** - * Get database statistics - */ - getStats(): Record { - const stats: Record = {}; - - const tables = ['state', 'executions', 'tasks', 'nodes', 'transaction_log', 'snapshots']; - for (const table of tables) { - const stmt = this.db.prepare(`SELECT COUNT(*) as count FROM ${table}`); - const row = stmt.get() as { count: number }; - stats[table] = row.count; - } - - return stats; - } - - /** - * Close database connection - */ - close(): void { - this.db.close(); - this.logger.info('State manager closed'); - } -} - -/** - * Logger class for state manager (will be replaced by actual logger) - */ -class Logger { - constructor(private context: string) {} - - debug(message: string, ...args: unknown[]): void { - console.log(`[${this.context}] DEBUG:`, message, ...args); - } - - info(message: string, ...args: unknown[]): void { - console.log(`[${this.context}] INFO:`, message, ...args); - } - - warn(message: string, ...args: unknown[]): void { - console.warn(`[${this.context}] WARN:`, message, ...args); - } - - error(message: string, ...args: unknown[]): void { - console.error(`[${this.context}] ERROR:`, message, ...args); - } -} diff --git a/praxis/SymbolicEngine/swarm/src/types.ts b/praxis/SymbolicEngine/swarm/src/types.ts deleted file mode 100644 index 2973d51..0000000 --- a/praxis/SymbolicEngine/swarm/src/types.ts +++ /dev/null @@ -1,424 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - Type Definitions - * - * Comprehensive TypeScript interfaces for distributed symbolic execution - */ - -// ============================================================================ -// Symbol Types -// ============================================================================ - -export type SymbolType = 'action' | 'filter' | 'state' | 'query' | 'transform'; - -export type SymbolContext = 'wordpress' | 'filesystem' | 'database' | 'network' | 'generic'; - -export type SymbolDispatchTarget = 'rust_injector' | 'php_engine' | 'powershell_engine' | 'internal'; - -export interface Symbol { - name: string; - type: SymbolType; - context: SymbolContext; - dispatch: SymbolDispatchTarget; - parameters: Record; - dependencies?: string[]; // Names of symbols that must execute first - priority?: number; // Higher = earlier execution (default: 0) - timeout?: number; // Execution timeout in milliseconds - retries?: number; // Number of retry attempts on failure - rollback?: Symbol; // Symbol to execute on rollback -} - -export interface Workflow { - name: string; - version: string; - description?: string; - symbols: Symbol[]; - metadata?: Record; -} - -// ============================================================================ -// Execution Types -// ============================================================================ - -export type ExecutionStatus = - | 'pending' - | 'queued' - | 'assigned' - | 'running' - | 'completed' - | 'failed' - | 'cancelled' - | 'rolled_back'; - -export interface ExecutionResult { - success: boolean; - output?: unknown; - error?: string; - stackTrace?: string; - duration: number; // milliseconds - timestamp: number; - metadata?: Record; -} - -export interface Execution { - id: string; - workflowId: string; - symbolName: string; - status: ExecutionStatus; - nodeId?: string; // Worker node assigned to this execution - result?: ExecutionResult; - attempts: number; - createdAt: number; - updatedAt: number; - startedAt?: number; - completedAt?: number; -} - -// ============================================================================ -// Task Types -// ============================================================================ - -export interface Task { - id: string; - executionId: string; - symbol: Symbol; - priority: number; - dependencies: string[]; // Task IDs that must complete first - status: ExecutionStatus; - assignedTo?: string; // Node ID - createdAt: number; - assignedAt?: number; -} - -// ============================================================================ -// Node Types -// ============================================================================ - -export type NodeStatus = 'initializing' | 'idle' | 'busy' | 'offline' | 'failed'; - -export interface NodeCapabilities { - rust: boolean; - php: boolean; - powershell: boolean; - maxConcurrentTasks: number; -} - -export interface NodeHealth { - cpuUsage: number; // Percentage 0-100 - memoryUsage: number; // Percentage 0-100 - activeTasks: number; - completedTasks: number; - failedTasks: number; - uptime: number; // milliseconds -} - -export interface Node { - id: string; - name: string; - status: NodeStatus; - capabilities: NodeCapabilities; - health: NodeHealth; - lastHeartbeat: number; - connectedAt: number; - metadata?: Record; -} - -// ============================================================================ -// Coordinator Types -// ============================================================================ - -export interface CoordinatorConfig { - maxWorkers: number; - heartbeatInterval: number; // milliseconds - heartbeatTimeout: number; // milliseconds - taskRetryLimit: number; - enableLoadBalancing: boolean; - priorityQueueEnabled: boolean; -} - -export interface CoordinatorState { - activeNodes: Map; - taskQueue: Task[]; - runningTasks: Map; - completedTasks: Set; - failedTasks: Map; // taskId -> error -} - -// ============================================================================ -// Dispatcher Types -// ============================================================================ - -export interface DispatcherConfig { - manifestPath?: string; - workflowName?: string; - coordinatorEndpoint: string; - stateDbPath: string; - enableWebSocket: boolean; - websocketPort: number; -} - -export interface DispatchResult { - workflowId: string; - totalTasks: number; - completedTasks: number; - failedTasks: number; - duration: number; - results: ExecutionResult[]; -} - -// ============================================================================ -// Worker Types -// ============================================================================ - -export interface WorkerConfig { - nodeId?: string; - nodeName: string; - dispatcherUrl: string; - capabilities: NodeCapabilities; - heartbeatInterval: number; - maxConcurrentTasks: number; - backends: BackendConfig; -} - -export interface BackendConfig { - rustInjector?: { - enabled: boolean; - binaryPath: string; - timeout: number; - }; - phpEngine?: { - enabled: boolean; - scriptPath: string; - phpBinary: string; - timeout: number; - }; - powershellEngine?: { - enabled: boolean; - scriptPath: string; - pwshBinary: string; - timeout: number; - }; -} - -// ============================================================================ -// WebSocket Message Types -// ============================================================================ - -export type MessageType = - | 'register' - | 'heartbeat' - | 'task_assign' - | 'task_update' - | 'task_complete' - | 'task_failed' - | 'node_update' - | 'workflow_start' - | 'workflow_complete' - | 'state_sync' - | 'shutdown'; - -export interface WebSocketMessage { - type: MessageType; - senderId: string; - timestamp: number; - payload: unknown; -} - -export interface RegisterMessage { - node: Omit; -} - -export interface HeartbeatMessage { - nodeId: string; - health: NodeHealth; -} - -export interface TaskAssignMessage { - task: Task; -} - -export interface TaskUpdateMessage { - taskId: string; - status: ExecutionStatus; - progress?: number; // 0-100 -} - -export interface TaskCompleteMessage { - taskId: string; - result: ExecutionResult; -} - -export interface TaskFailedMessage { - taskId: string; - error: string; - stackTrace?: string; -} - -// ============================================================================ -// State Manager Types -// ============================================================================ - -export interface StateTransaction { - id: string; - operations: StateOperation[]; - timestamp: number; - committed: boolean; -} - -export interface StateOperation { - type: 'set' | 'delete' | 'update'; - key: string; - value?: unknown; - previousValue?: unknown; -} - -export interface StateSnapshot { - timestamp: number; - data: Record; - checksum: string; -} - -// ============================================================================ -// Executor Types -// ============================================================================ - -export interface ExecutorContext { - symbol: Symbol; - executionId: string; - workflowId: string; - nodeId: string; - stateManager: unknown; // Will be StateManager instance - logger: unknown; // Will be Logger instance -} - -export interface ExecutorBackend { - execute(context: ExecutorContext): Promise; - canHandle(symbol: Symbol): boolean; - healthCheck(): Promise; -} - -// ============================================================================ -// Configuration Types -// ============================================================================ - -export interface SwarmConfig { - dispatcher: DispatcherConfig; - coordinator: CoordinatorConfig; - worker: WorkerConfig; - logging: LoggingConfig; - security?: SecurityConfig; -} - -export interface LoggingConfig { - level: 'error' | 'warn' | 'info' | 'debug' | 'verbose'; - file?: string; - console: boolean; - format: 'json' | 'text'; -} - -export interface SecurityConfig { - enableAuth: boolean; - apiKey?: string; - allowedHosts: string[]; - maxMessageSize: number; // bytes -} - -// ============================================================================ -// CLI Types -// ============================================================================ - -export interface CLICommand { - name: string; - description: string; - options?: CLIOption[]; - action: (args: Record) => Promise; -} - -export interface CLIOption { - name: string; - alias?: string; - description: string; - type: 'string' | 'number' | 'boolean'; - required?: boolean; - default?: unknown; -} - -// ============================================================================ -// Utility Types -// ============================================================================ - -export type AsyncResult = Promise<{ success: true; data: T } | { success: false; error: string }>; - -export interface Retryable { - attempt: () => Promise; - maxAttempts: number; - delayMs: number; - backoffMultiplier?: number; -} - -export interface TimeoutOptions { - timeoutMs: number; - onTimeout?: () => void; -} - -// ============================================================================ -// Export Helper Functions -// ============================================================================ - -export function createSymbol(partial: Partial & Pick): Symbol { - return { - context: 'generic', - dispatch: 'internal', - parameters: {}, - priority: 0, - timeout: 30000, - retries: 3, - ...partial, - }; -} - -export function createNode(partial: Partial & Pick): Node { - return { - status: 'initializing', - capabilities: { - rust: false, - php: false, - powershell: false, - maxConcurrentTasks: 4, - }, - health: { - cpuUsage: 0, - memoryUsage: 0, - activeTasks: 0, - completedTasks: 0, - failedTasks: 0, - uptime: 0, - }, - lastHeartbeat: Date.now(), - connectedAt: Date.now(), - ...partial, - }; -} - -export function createTask(partial: Partial & Pick): Task { - return { - priority: partial.symbol.priority ?? 0, - dependencies: partial.symbol.dependencies ?? [], - status: 'pending', - createdAt: Date.now(), - ...partial, - }; -} - -export function createExecution( - partial: Partial & Pick -): Execution { - return { - status: 'pending', - attempts: 0, - createdAt: Date.now(), - updatedAt: Date.now(), - ...partial, - }; -} diff --git a/praxis/SymbolicEngine/swarm/src/websocket-server.ts b/praxis/SymbolicEngine/swarm/src/websocket-server.ts deleted file mode 100644 index 94196fe..0000000 --- a/praxis/SymbolicEngine/swarm/src/websocket-server.ts +++ /dev/null @@ -1,375 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - WebSocket Server - * - * Real-time communication server for: - * - Worker node communication - * - State synchronization - * - Real-time monitoring - * - Dashboard integration - */ - -import { WebSocketServer as WSServer, WebSocket } from 'ws'; -import { createServer, Server as HTTPServer } from 'http'; -import type { WebSocketMessage } from './types'; -import { Logger } from './logger'; - -export class WebSocketServer { - private wss?: WSServer; - private httpServer?: HTTPServer; - private clients: Map = new Map(); - private logger: Logger; - private messageHandler: (message: WebSocketMessage, senderId: string) => void; - - constructor( - private port: number, - messageHandler: (message: WebSocketMessage, senderId: string) => void, - logger?: Logger - ) { - this.logger = logger ?? new Logger('WebSocketServer'); - this.messageHandler = messageHandler; - } - - // ============================================================================ - // Server Lifecycle - // ============================================================================ - - /** - * Start WebSocket server - */ - async start(): Promise { - return new Promise((resolve, reject) => { - try { - // Create HTTP server - this.httpServer = createServer(); - - // Create WebSocket server - this.wss = new WSServer({ server: this.httpServer }); - - // Set up WebSocket event handlers - this.wss.on('connection', (ws: WebSocket, req) => { - this.handleConnection(ws, req); - }); - - this.wss.on('error', (error) => { - this.logger.error('WebSocket server error:', error); - }); - - // Start HTTP server - this.httpServer.listen(this.port, () => { - this.logger.info(`WebSocket server listening on port ${this.port}`); - resolve(); - }); - - this.httpServer.on('error', (error) => { - this.logger.error('HTTP server error:', error); - reject(error); - }); - } catch (error) { - this.logger.error('Failed to start WebSocket server:', error); - reject(error); - } - }); - } - - /** - * Stop WebSocket server - */ - async stop(): Promise { - return new Promise((resolve) => { - this.logger.info('Stopping WebSocket server...'); - - // Close all client connections - for (const [clientId, ws] of this.clients.entries()) { - this.logger.debug(`Closing connection: ${clientId}`); - ws.close(1000, 'Server shutting down'); - } - this.clients.clear(); - - // Close WebSocket server - if (this.wss) { - this.wss.close(() => { - this.logger.debug('WebSocket server closed'); - - // Close HTTP server - if (this.httpServer) { - this.httpServer.close(() => { - this.logger.info('WebSocket server stopped'); - resolve(); - }); - } else { - resolve(); - } - }); - } else { - resolve(); - } - }); - } - - // ============================================================================ - // Connection Handling - // ============================================================================ - - /** - * Handle new WebSocket connection - */ - private handleConnection(ws: WebSocket, req: any): void { - const clientId = this.generateClientId(); - this.clients.set(clientId, ws); - - this.logger.info(`Client connected: ${clientId} (${req.socket.remoteAddress})`); - - // Set up message handler - ws.on('message', (data: Buffer) => { - this.handleMessage(data, clientId); - }); - - // Handle disconnection - ws.on('close', (code: number, reason: Buffer) => { - this.handleDisconnection(clientId, code, reason.toString()); - }); - - // Handle errors - ws.on('error', (error: Error) => { - this.logger.error(`Client error (${clientId}):`, error); - }); - - // Handle pong (keep-alive) - ws.on('pong', () => { - this.logger.verbose(`Pong received from ${clientId}`); - }); - - // Send welcome message - this.sendToClient(clientId, { - type: 'node_update', - senderId: 'server', - timestamp: Date.now(), - payload: { - message: 'Connected to WP Praxis Swarm', - clientId, - }, - }); - - // Start ping interval - this.startPingInterval(clientId); - } - - /** - * Handle client disconnection - */ - private handleDisconnection(clientId: string, code: number, reason: string): void { - this.clients.delete(clientId); - this.logger.info(`Client disconnected: ${clientId} (code: ${code}, reason: ${reason})`); - } - - /** - * Handle incoming message - */ - private handleMessage(data: Buffer, clientId: string): void { - try { - const message = JSON.parse(data.toString()) as WebSocketMessage; - - this.logger.debug(`Message from ${clientId}: ${message.type}`); - - // Set sender ID if not provided - if (!message.senderId || message.senderId === 'unknown') { - message.senderId = clientId; - } - - // Pass message to handler - this.messageHandler(message, clientId); - } catch (error) { - this.logger.error(`Failed to parse message from ${clientId}:`, error); - - // Send error response - this.sendToClient(clientId, { - type: 'node_update', - senderId: 'server', - timestamp: Date.now(), - payload: { - error: 'Invalid message format', - }, - }); - } - } - - /** - * Generate unique client ID - */ - private generateClientId(): string { - return `client-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; - } - - // ============================================================================ - // Message Sending - // ============================================================================ - - /** - * Send message to specific client - */ - sendToClient(clientId: string, message: WebSocketMessage): void { - const ws = this.clients.get(clientId); - if (!ws || ws.readyState !== WebSocket.OPEN) { - this.logger.warn(`Cannot send to client ${clientId} - not connected`); - return; - } - - try { - ws.send(JSON.stringify(message)); - this.logger.verbose(`Message sent to ${clientId}: ${message.type}`); - } catch (error) { - this.logger.error(`Failed to send message to ${clientId}:`, error); - } - } - - /** - * Broadcast message to all connected clients - */ - broadcast(message: WebSocketMessage): void { - const clientCount = this.clients.size; - let sentCount = 0; - - for (const [clientId, ws] of this.clients.entries()) { - if (ws.readyState === WebSocket.OPEN) { - try { - ws.send(JSON.stringify(message)); - sentCount++; - } catch (error) { - this.logger.error(`Failed to broadcast to ${clientId}:`, error); - } - } - } - - this.logger.debug(`Broadcast: ${message.type} (${sentCount}/${clientCount} clients)`); - } - - /** - * Broadcast to clients matching filter - */ - broadcastFiltered( - message: WebSocketMessage, - filter: (clientId: string) => boolean - ): void { - let sentCount = 0; - - for (const [clientId, ws] of this.clients.entries()) { - if (filter(clientId) && ws.readyState === WebSocket.OPEN) { - try { - ws.send(JSON.stringify(message)); - sentCount++; - } catch (error) { - this.logger.error(`Failed to send to ${clientId}:`, error); - } - } - } - - this.logger.debug(`Filtered broadcast: ${message.type} (${sentCount} clients)`); - } - - // ============================================================================ - // Keep-Alive - // ============================================================================ - - /** - * Start ping interval for client - */ - private startPingInterval(clientId: string): void { - const interval = setInterval(() => { - const ws = this.clients.get(clientId); - if (!ws || ws.readyState !== WebSocket.OPEN) { - clearInterval(interval); - return; - } - - try { - ws.ping(); - this.logger.verbose(`Ping sent to ${clientId}`); - } catch (error) { - this.logger.error(`Failed to ping ${clientId}:`, error); - clearInterval(interval); - } - }, 30000); // Ping every 30 seconds - } - - // ============================================================================ - // Statistics - // ============================================================================ - - /** - * Get server statistics - */ - getStats(): { - port: number; - connectedClients: number; - clients: Array<{ id: string; state: string }>; - } { - const clients = Array.from(this.clients.entries()).map(([id, ws]) => ({ - id, - state: this.getReadyStateString(ws.readyState), - })); - - return { - port: this.port, - connectedClients: this.clients.size, - clients, - }; - } - - /** - * Get WebSocket ready state as string - */ - private getReadyStateString(state: number): string { - switch (state) { - case WebSocket.CONNECTING: - return 'CONNECTING'; - case WebSocket.OPEN: - return 'OPEN'; - case WebSocket.CLOSING: - return 'CLOSING'; - case WebSocket.CLOSED: - return 'CLOSED'; - default: - return 'UNKNOWN'; - } - } - - /** - * Get connected client IDs - */ - getClientIds(): string[] { - return Array.from(this.clients.keys()); - } - - /** - * Check if client is connected - */ - isClientConnected(clientId: string): boolean { - const ws = this.clients.get(clientId); - return ws !== undefined && ws.readyState === WebSocket.OPEN; - } - - /** - * Disconnect client - */ - disconnectClient(clientId: string, reason?: string): void { - const ws = this.clients.get(clientId); - if (ws) { - ws.close(1000, reason ?? 'Disconnected by server'); - this.clients.delete(clientId); - this.logger.info(`Client disconnected by server: ${clientId}`); - } - } -} - -/** - * Create a WebSocket server instance - */ -export function createWebSocketServer( - port: number, - messageHandler: (message: WebSocketMessage, senderId: string) => void, - logger?: Logger -): WebSocketServer { - return new WebSocketServer(port, messageHandler, logger); -} diff --git a/praxis/SymbolicEngine/swarm/src/worker.ts b/praxis/SymbolicEngine/swarm/src/worker.ts deleted file mode 100644 index a1d4dd5..0000000 --- a/praxis/SymbolicEngine/swarm/src/worker.ts +++ /dev/null @@ -1,452 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * WP Praxis Swarm - Worker Node - * - * Worker node that: - * - Registers with the dispatcher/coordinator - * - Receives and executes symbolic tasks - * - Reports progress and results - * - Sends heartbeats - * - Handles graceful shutdown - */ - -import { v4 as uuidv4 } from 'uuid'; -import WebSocket from 'ws'; -import type { - Node, - Task, - WorkerConfig, - WebSocketMessage, - RegisterMessage, - HeartbeatMessage, - TaskAssignMessage, - TaskCompleteMessage, - TaskFailedMessage, - ExecutionResult, - ExecutorContext, - NodeHealth, -} from './types'; -import { createNode } from './types'; -import { Executor, createExecutor } from './executor'; -import { StateManager } from './state-manager'; -import { Logger } from './logger'; - -export class Worker { - private node: Node; - private ws?: WebSocket; - private executor: Executor; - private stateManager: StateManager; - private logger: Logger; - - private heartbeatInterval?: Timer; - private activeTasks: Map = new Map(); - private isShuttingDown = false; - - constructor(config: WorkerConfig, stateManager: StateManager, logger?: Logger) { - this.logger = logger ?? new Logger('Worker'); - this.stateManager = stateManager; - - // Create node instance - this.node = createNode({ - id: config.nodeId ?? uuidv4(), - name: config.nodeName, - capabilities: config.capabilities, - }); - - // Initialize executor - this.executor = createExecutor(config.backends, this.logger.child('Executor')); - - this.logger.info(`Worker initialized: ${this.node.name} (${this.node.id})`); - } - - // ============================================================================ - // Lifecycle Management - // ============================================================================ - - /** - * Start worker and connect to dispatcher - */ - async start(dispatcherUrl: string): Promise { - this.logger.info(`Starting worker, connecting to: ${dispatcherUrl}`); - - return new Promise((resolve, reject) => { - this.ws = new WebSocket(dispatcherUrl); - - this.ws.on('open', () => { - this.logger.info('Connected to dispatcher'); - this.node.status = 'idle'; - this.register(); - this.startHeartbeat(); - resolve(); - }); - - this.ws.on('message', (data) => { - this.handleMessage(data.toString()); - }); - - this.ws.on('error', (error) => { - this.logger.error('WebSocket error:', error); - reject(error); - }); - - this.ws.on('close', () => { - this.logger.warn('Disconnected from dispatcher'); - this.stopHeartbeat(); - - // Attempt reconnection if not shutting down - if (!this.isShuttingDown) { - setTimeout(() => { - this.logger.info('Attempting to reconnect...'); - this.start(dispatcherUrl).catch((err) => { - this.logger.error('Reconnection failed:', err); - }); - }, 5000); - } - }); - }); - } - - /** - * Stop worker gracefully - */ - async stop(): Promise { - this.logger.info('Stopping worker...'); - this.isShuttingDown = true; - - // Wait for active tasks to complete - if (this.activeTasks.size > 0) { - this.logger.info(`Waiting for ${this.activeTasks.size} active tasks to complete...`); - - await new Promise((resolve) => { - const checkInterval = setInterval(() => { - if (this.activeTasks.size === 0) { - clearInterval(checkInterval); - resolve(); - } - }, 1000); - - // Timeout after 30 seconds - setTimeout(() => { - clearInterval(checkInterval); - this.logger.warn('Shutdown timeout - forcing stop'); - resolve(); - }, 30000); - }); - } - - this.stopHeartbeat(); - - if (this.ws) { - this.ws.close(); - this.ws = undefined; - } - - this.logger.info('Worker stopped'); - } - - // ============================================================================ - // Registration & Heartbeat - // ============================================================================ - - /** - * Register with coordinator - */ - private register(): void { - const message: WebSocketMessage = { - type: 'register', - senderId: this.node.id, - timestamp: Date.now(), - payload: { - node: this.node, - } as RegisterMessage, - }; - - this.sendMessage(message); - this.logger.info('Registration message sent'); - } - - /** - * Start sending heartbeats - */ - private startHeartbeat(): void { - this.heartbeatInterval = setInterval(() => { - this.sendHeartbeat(); - }, 5000); // Send heartbeat every 5 seconds - - this.logger.debug('Heartbeat started'); - } - - /** - * Stop sending heartbeats - */ - private stopHeartbeat(): void { - if (this.heartbeatInterval) { - clearInterval(this.heartbeatInterval); - this.heartbeatInterval = undefined; - this.logger.debug('Heartbeat stopped'); - } - } - - /** - * Send heartbeat to coordinator - */ - private sendHeartbeat(): void { - const health = this.getNodeHealth(); - - const message: WebSocketMessage = { - type: 'heartbeat', - senderId: this.node.id, - timestamp: Date.now(), - payload: { - nodeId: this.node.id, - health, - } as HeartbeatMessage, - }; - - this.sendMessage(message); - this.logger.verbose(`Heartbeat sent (active tasks: ${health.activeTasks})`); - } - - /** - * Get current node health - */ - private getNodeHealth(): NodeHealth { - return { - cpuUsage: this.getCpuUsage(), - memoryUsage: this.getMemoryUsage(), - activeTasks: this.activeTasks.size, - completedTasks: this.node.health.completedTasks, - failedTasks: this.node.health.failedTasks, - uptime: Date.now() - this.node.connectedAt, - }; - } - - /** - * Get CPU usage percentage (simplified - would need better implementation) - */ - private getCpuUsage(): number { - // Simplified placeholder - in production, use proper OS metrics - return Math.random() * 100; - } - - /** - * Get memory usage percentage - */ - private getMemoryUsage(): number { - if (typeof process !== 'undefined' && process.memoryUsage) { - const usage = process.memoryUsage(); - const totalHeap = usage.heapTotal; - const usedHeap = usage.heapUsed; - return (usedHeap / totalHeap) * 100; - } - return 0; - } - - // ============================================================================ - // Message Handling - // ============================================================================ - - /** - * Handle incoming WebSocket message - */ - private async handleMessage(data: string): Promise { - try { - const message = JSON.parse(data) as WebSocketMessage; - - this.logger.debug(`Message received: ${message.type}`); - - switch (message.type) { - case 'task_assign': - await this.handleTaskAssign(message.payload as TaskAssignMessage); - break; - - case 'shutdown': - this.logger.info('Shutdown command received'); - await this.stop(); - break; - - default: - this.logger.warn(`Unknown message type: ${message.type}`); - } - } catch (error) { - this.logger.error('Failed to handle message:', error); - } - } - - /** - * Handle task assignment - */ - private async handleTaskAssign(payload: TaskAssignMessage): Promise { - const { task } = payload; - - this.logger.info(`Task assigned: ${task.id} (${task.symbol.name})`); - - // Check if we can accept the task - if (this.activeTasks.size >= this.node.capabilities.maxConcurrentTasks) { - this.logger.warn(`Cannot accept task - at capacity (${this.activeTasks.size} tasks)`); - return; - } - - // Add to active tasks - this.activeTasks.set(task.id, task); - this.node.status = 'busy'; - - // Execute task asynchronously - this.executeTask(task).catch((error) => { - this.logger.error(`Task execution error: ${task.id}`, error); - }); - } - - /** - * Execute a task - */ - private async executeTask(task: Task): Promise { - this.logger.info(`Executing task: ${task.id} (${task.symbol.name})`); - - try { - // Create execution context - const context: ExecutorContext = { - symbol: task.symbol, - executionId: task.executionId, - workflowId: '', // Will be populated by dispatcher - nodeId: this.node.id, - stateManager: this.stateManager, - logger: this.logger, - }; - - // Execute symbol - const result = await this.executor.execute(context); - - // Report success - this.reportTaskComplete(task.id, result); - - // Update stats - this.node.health.completedTasks++; - } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error); - const stackTrace = error instanceof Error ? error.stack : undefined; - - this.logger.error(`Task failed: ${task.id}`, error); - - // Report failure - this.reportTaskFailed(task.id, errorMessage, stackTrace); - - // Update stats - this.node.health.failedTasks++; - } finally { - // Remove from active tasks - this.activeTasks.delete(task.id); - - // Update status - if (this.activeTasks.size < this.node.capabilities.maxConcurrentTasks) { - this.node.status = 'idle'; - } - } - } - - /** - * Report task completion - */ - private reportTaskComplete(taskId: string, result: ExecutionResult): void { - const message: WebSocketMessage = { - type: 'task_complete', - senderId: this.node.id, - timestamp: Date.now(), - payload: { - taskId, - result, - } as TaskCompleteMessage, - }; - - this.sendMessage(message); - this.logger.info(`Task completed: ${taskId}`); - } - - /** - * Report task failure - */ - private reportTaskFailed(taskId: string, error: string, stackTrace?: string): void { - const message: WebSocketMessage = { - type: 'task_failed', - senderId: this.node.id, - timestamp: Date.now(), - payload: { - taskId, - error, - stackTrace, - } as TaskFailedMessage, - }; - - this.sendMessage(message); - this.logger.error(`Task failed: ${taskId} - ${error}`); - } - - // ============================================================================ - // Communication - // ============================================================================ - - /** - * Send WebSocket message - */ - private sendMessage(message: WebSocketMessage): void { - if (!this.ws || this.ws.readyState !== WebSocket.OPEN) { - this.logger.warn('Cannot send message - WebSocket not connected'); - return; - } - - try { - this.ws.send(JSON.stringify(message)); - } catch (error) { - this.logger.error('Failed to send message:', error); - } - } - - // ============================================================================ - // Getters - // ============================================================================ - - /** - * Get node information - */ - getNode(): Node { - return this.node; - } - - /** - * Get active tasks - */ - getActiveTasks(): Task[] { - return Array.from(this.activeTasks.values()); - } - - /** - * Get worker statistics - */ - getStats(): { - nodeId: string; - nodeName: string; - status: string; - activeTasks: number; - completedTasks: number; - failedTasks: number; - uptime: number; - } { - return { - nodeId: this.node.id, - nodeName: this.node.name, - status: this.node.status, - activeTasks: this.activeTasks.size, - completedTasks: this.node.health.completedTasks, - failedTasks: this.node.health.failedTasks, - uptime: Date.now() - this.node.connectedAt, - }; - } -} - -/** - * Create a worker instance - */ -export function createWorker(config: WorkerConfig, stateManager: StateManager, logger?: Logger): Worker { - return new Worker(config, stateManager, logger); -} diff --git a/praxis/SymbolicEngine/swarm/tests/coordinator.test.ts b/praxis/SymbolicEngine/swarm/tests/coordinator.test.ts deleted file mode 100644 index a99adbd..0000000 --- a/praxis/SymbolicEngine/swarm/tests/coordinator.test.ts +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -import { describe, test, expect, beforeEach, mock } from "bun:test"; -import { Coordinator } from "../src/coordinator"; -import { Worker } from "../src/worker"; -import { Symbol, SymbolType } from "../src/types"; - -describe("Coordinator", () => { - let coordinator: Coordinator; - - beforeEach(() => { - coordinator = new Coordinator({ workerCount: 3 }); - }); - - describe("Worker Management", () => { - test("should initialize workers", async () => { - await coordinator.start(); - const workers = coordinator.getWorkers(); - expect(workers).toHaveLength(3); - }); - - test("should add workers dynamically", async () => { - await coordinator.start(); - await coordinator.addWorker(); - - const workers = coordinator.getWorkers(); - expect(workers).toHaveLength(4); - }); - - test("should remove workers", async () => { - await coordinator.start(); - const workers = coordinator.getWorkers(); - await coordinator.removeWorker(workers[0].getId()); - - expect(coordinator.getWorkers()).toHaveLength(2); - }); - - test("should scale workers based on load", async () => { - coordinator = new Coordinator({ - workerCount: 2, - autoScale: true, - minWorkers: 2, - maxWorkers: 5, - }); - - await coordinator.start(); - - // Simulate high load - const symbols = Array.from({ length: 20 }, (_, i) => ({ - name: `task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - })); - - coordinator.scheduleMany(symbols); - - // Wait for auto-scaling - await new Promise((resolve) => setTimeout(resolve, 100)); - - expect(coordinator.getWorkers().length).toBeGreaterThan(2); - }); - }); - - describe("Task Scheduling", () => { - test("should schedule symbol to available worker", async () => { - await coordinator.start(); - - const symbol: Symbol = { - name: "scheduled_task", - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - }; - - const result = await coordinator.schedule(symbol); - expect(result.success).toBe(true); - expect(result.workerId).toBeDefined(); - }); - - test("should balance load across workers", async () => { - await coordinator.start(); - - const symbols = Array.from({ length: 9 }, (_, i) => ({ - name: `balanced_task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - })); - - const results = await coordinator.scheduleMany(symbols); - - // Check that tasks are distributed - const workerIds = results.map((r) => r.workerId); - const uniqueWorkers = new Set(workerIds); - expect(uniqueWorkers.size).toBe(3); - }); - - test("should use round-robin scheduling", async () => { - coordinator = new Coordinator({ workerCount: 3, schedulingStrategy: "round-robin" }); - await coordinator.start(); - - const symbols = Array.from({ length: 6 }, (_, i) => ({ - name: `rr_task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - })); - - const results = await coordinator.scheduleMany(symbols); - - // Each worker should get 2 tasks - const workerCounts = new Map(); - results.forEach((r) => { - workerCounts.set(r.workerId, (workerCounts.get(r.workerId) || 0) + 1); - }); - - Array.from(workerCounts.values()).forEach((count) => { - expect(count).toBe(2); - }); - }); - - test("should use least-loaded scheduling", async () => { - coordinator = new Coordinator({ workerCount: 3, schedulingStrategy: "least-loaded" }); - await coordinator.start(); - - const symbols = Array.from({ length: 10 }, (_, i) => ({ - name: `ll_task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "slow_executor", - parameters: {}, - })); - - const results = await coordinator.scheduleMany(symbols); - expect(results).toHaveLength(10); - }); - }); - - describe("Fault Tolerance", () => { - test("should handle worker failure", async () => { - await coordinator.start(); - - const symbol: Symbol = { - name: "fault_test", - type: SymbolType.Action, - context: "test", - dispatch: "failing_executor", - parameters: {}, - }; - - // First attempt fails, should retry on another worker - try { - await coordinator.schedule(symbol); - } catch (e) { - // Expected on final failure - } - - const stats = coordinator.getStatistics(); - expect(stats.retriesAttempted).toBeGreaterThan(0); - }); - - test("should redistribute tasks from failed worker", async () => { - await coordinator.start(); - const workers = coordinator.getWorkers(); - - // Simulate worker failure - await coordinator.removeWorker(workers[0].getId()); - - // Tasks should be redistributed - const stats = coordinator.getStatistics(); - expect(stats.tasksRedistributed).toBeGreaterThanOrEqual(0); - }); - - test("should maintain service during worker restarts", async () => { - await coordinator.start(); - - const symbol: Symbol = { - name: "restart_test", - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - }; - - // Schedule task while restarting a worker - const schedulePromise = coordinator.schedule(symbol); - - const workers = coordinator.getWorkers(); - await coordinator.restartWorker(workers[0].getId()); - - const result = await schedulePromise; - expect(result.success).toBe(true); - }); - }); - - describe("Monitoring and Metrics", () => { - test("should collect coordinator statistics", async () => { - await coordinator.start(); - - const symbols = Array.from({ length: 5 }, (_, i) => ({ - name: `stat_task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - })); - - await coordinator.scheduleMany(symbols); - - const stats = coordinator.getStatistics(); - expect(stats.totalTasksScheduled).toBe(5); - expect(stats.activeWorkers).toBe(3); - }); - - test("should report system health", async () => { - await coordinator.start(); - - const health = await coordinator.healthCheck(); - expect(health.healthy).toBe(true); - expect(health.workerStatuses).toHaveLength(3); - }); - }); -}); diff --git a/praxis/SymbolicEngine/swarm/tests/dispatcher.test.ts b/praxis/SymbolicEngine/swarm/tests/dispatcher.test.ts deleted file mode 100644 index 52e29af..0000000 --- a/praxis/SymbolicEngine/swarm/tests/dispatcher.test.ts +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -import { describe, test, expect, beforeEach, mock } from "bun:test"; -import { Dispatcher } from "../src/dispatcher"; -import { Symbol, SymbolType } from "../src/types"; - -describe("Dispatcher", () => { - let dispatcher: Dispatcher; - - beforeEach(() => { - dispatcher = new Dispatcher(); - }); - - describe("Symbol Routing", () => { - test("should route symbol to correct executor", () => { - const symbol: Symbol = { - name: "test_symbol", - type: SymbolType.Action, - context: "wordpress", - dispatch: "rust_injector", - parameters: {}, - }; - - const route = dispatcher.getRoute(symbol); - expect(route.executor).toBe("rust_injector"); - expect(route.valid).toBe(true); - }); - - test("should reject invalid executor", () => { - const symbol: Symbol = { - name: "invalid_symbol", - type: SymbolType.Action, - context: "test", - dispatch: "nonexistent_executor", - parameters: {}, - }; - - const route = dispatcher.getRoute(symbol); - expect(route.valid).toBe(false); - expect(route.error).toContain("Unknown executor"); - }); - - test("should handle multiple dispatch targets", () => { - const symbols: Symbol[] = [ - { - name: "symbol1", - type: SymbolType.Action, - context: "test", - dispatch: "rust_injector", - parameters: {}, - }, - { - name: "symbol2", - type: SymbolType.Query, - context: "test", - dispatch: "php_engine", - parameters: {}, - }, - ]; - - const routes = dispatcher.routeMany(symbols); - expect(routes.rust_injector).toHaveLength(1); - expect(routes.php_engine).toHaveLength(1); - }); - }); - - describe("Dispatch Execution", () => { - test("should execute symbol dispatch", async () => { - const symbol: Symbol = { - name: "exec_test", - type: SymbolType.Action, - context: "test", - dispatch: "mock_executor", - parameters: { key: "value" }, - }; - - const mockExecutor = mock(() => Promise.resolve({ success: true, data: "executed" })); - dispatcher.registerExecutor("mock_executor", mockExecutor); - - const result = await dispatcher.dispatch(symbol); - expect(result.success).toBe(true); - expect(result.data).toBe("executed"); - expect(mockExecutor).toHaveBeenCalledTimes(1); - }); - - test("should handle dispatch failures", async () => { - const symbol: Symbol = { - name: "failing_symbol", - type: SymbolType.Action, - context: "test", - dispatch: "failing_executor", - parameters: {}, - }; - - const failingExecutor = mock(() => Promise.reject(new Error("Execution failed"))); - dispatcher.registerExecutor("failing_executor", failingExecutor); - - await expect(dispatcher.dispatch(symbol)).rejects.toThrow("Execution failed"); - }); - - test("should timeout long-running dispatches", async () => { - const symbol: Symbol = { - name: "slow_symbol", - type: SymbolType.Action, - context: "test", - dispatch: "slow_executor", - parameters: {}, - timeout: 100, - }; - - const slowExecutor = mock(() => new Promise((resolve) => setTimeout(resolve, 1000))); - dispatcher.registerExecutor("slow_executor", slowExecutor); - - await expect(dispatcher.dispatch(symbol)).rejects.toThrow("timeout"); - }); - }); - - describe("Batch Dispatching", () => { - test("should batch dispatch multiple symbols", async () => { - const symbols: Symbol[] = Array.from({ length: 5 }, (_, i) => ({ - name: `symbol_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "batch_executor", - parameters: {}, - })); - - const mockExecutor = mock(() => Promise.resolve({ success: true })); - dispatcher.registerExecutor("batch_executor", mockExecutor); - - const results = await dispatcher.dispatchBatch(symbols); - expect(results).toHaveLength(5); - expect(results.every((r) => r.success)).toBe(true); - expect(mockExecutor).toHaveBeenCalledTimes(5); - }); - - test("should handle partial batch failures", async () => { - const symbols: Symbol[] = [ - { name: "symbol1", type: SymbolType.Action, context: "test", dispatch: "executor", parameters: {} }, - { name: "symbol2", type: SymbolType.Action, context: "test", dispatch: "executor", parameters: {} }, - { name: "symbol3", type: SymbolType.Action, context: "test", dispatch: "executor", parameters: {} }, - ]; - - let callCount = 0; - const partialFailExecutor = mock(() => { - callCount++; - if (callCount === 2) { - return Promise.reject(new Error("Failed")); - } - return Promise.resolve({ success: true }); - }); - - dispatcher.registerExecutor("executor", partialFailExecutor); - - const results = await dispatcher.dispatchBatch(symbols, { failFast: false }); - expect(results[0].success).toBe(true); - expect(results[1].success).toBe(false); - expect(results[2].success).toBe(true); - }); - - test("should respect max concurrent dispatches", async () => { - const symbols: Symbol[] = Array.from({ length: 10 }, (_, i) => ({ - name: `symbol_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "concurrent_executor", - parameters: {}, - })); - - let concurrentCount = 0; - let maxConcurrent = 0; - - const concurrentExecutor = mock(async () => { - concurrentCount++; - maxConcurrent = Math.max(maxConcurrent, concurrentCount); - await new Promise((resolve) => setTimeout(resolve, 10)); - concurrentCount--; - return { success: true }; - }); - - dispatcher.registerExecutor("concurrent_executor", concurrentExecutor); - dispatcher.setMaxConcurrent(3); - - await dispatcher.dispatchBatch(symbols); - expect(maxConcurrent).toBeLessThanOrEqual(3); - }); - }); - - describe("Dispatcher Configuration", () => { - test("should load configuration", () => { - const config = { - maxConcurrent: 10, - timeout: 5000, - retries: 3, - }; - - dispatcher.configure(config); - expect(dispatcher.getConfig()).toEqual(config); - }); - - test("should validate configuration", () => { - const invalidConfig = { - maxConcurrent: -1, - timeout: "invalid", - }; - - expect(() => dispatcher.configure(invalidConfig as any)).toThrow("Invalid configuration"); - }); - }); - - describe("Event Handling", () => { - test("should emit dispatch events", async () => { - const events: string[] = []; - - dispatcher.on("dispatch:start", (symbol) => events.push(`start:${symbol.name}`)); - dispatcher.on("dispatch:complete", (symbol) => events.push(`complete:${symbol.name}`)); - - const symbol: Symbol = { - name: "event_test", - type: SymbolType.Action, - context: "test", - dispatch: "event_executor", - parameters: {}, - }; - - const mockExecutor = mock(() => Promise.resolve({ success: true })); - dispatcher.registerExecutor("event_executor", mockExecutor); - - await dispatcher.dispatch(symbol); - - expect(events).toContain("start:event_test"); - expect(events).toContain("complete:event_test"); - }); - - test("should emit error events on failure", async () => { - let errorCaught = false; - - dispatcher.on("dispatch:error", () => { - errorCaught = true; - }); - - const symbol: Symbol = { - name: "error_test", - type: SymbolType.Action, - context: "test", - dispatch: "error_executor", - parameters: {}, - }; - - const errorExecutor = mock(() => Promise.reject(new Error("Test error"))); - dispatcher.registerExecutor("error_executor", errorExecutor); - - await expect(dispatcher.dispatch(symbol)).rejects.toThrow(); - expect(errorCaught).toBe(true); - }); - }); -}); diff --git a/praxis/SymbolicEngine/swarm/tests/worker.test.ts b/praxis/SymbolicEngine/swarm/tests/worker.test.ts deleted file mode 100644 index 26d9780..0000000 --- a/praxis/SymbolicEngine/swarm/tests/worker.test.ts +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -import { describe, test, expect, beforeEach, mock } from "bun:test"; -import { Worker } from "../src/worker"; -import { Symbol, SymbolType } from "../src/types"; - -describe("Worker", () => { - let worker: Worker; - - beforeEach(() => { - worker = new Worker({ id: "worker-1", maxTasks: 5 }); - }); - - describe("Worker Lifecycle", () => { - test("should initialize worker", () => { - expect(worker.getId()).toBe("worker-1"); - expect(worker.getStatus()).toBe("idle"); - }); - - test("should start worker", async () => { - await worker.start(); - expect(worker.getStatus()).toBe("running"); - }); - - test("should stop worker", async () => { - await worker.start(); - await worker.stop(); - expect(worker.getStatus()).toBe("stopped"); - }); - - test("should pause and resume worker", async () => { - await worker.start(); - await worker.pause(); - expect(worker.getStatus()).toBe("paused"); - - await worker.resume(); - expect(worker.getStatus()).toBe("running"); - }); - }); - - describe("Task Execution", () => { - test("should execute assigned symbol", async () => { - const symbol: Symbol = { - name: "worker_task", - type: SymbolType.Action, - context: "test", - dispatch: "worker_executor", - parameters: {}, - }; - - await worker.start(); - const result = await worker.execute(symbol); - - expect(result.success).toBe(true); - expect(result.workerId).toBe("worker-1"); - }); - - test("should reject task when stopped", async () => { - const symbol: Symbol = { - name: "rejected_task", - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - }; - - await expect(worker.execute(symbol)).rejects.toThrow("Worker not running"); - }); - - test("should track concurrent tasks", async () => { - await worker.start(); - - const symbols = Array.from({ length: 3 }, (_, i) => ({ - name: `task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "slow_executor", - parameters: {}, - })); - - const promises = symbols.map((s) => worker.execute(s)); - - // Check concurrent task count - expect(worker.getActiveTasks()).toBe(3); - - await Promise.all(promises); - expect(worker.getActiveTasks()).toBe(0); - }); - - test("should respect max concurrent tasks", async () => { - worker = new Worker({ id: "worker-limited", maxTasks: 2 }); - await worker.start(); - - const symbols = Array.from({ length: 5 }, (_, i) => ({ - name: `task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - })); - - const executionPromises = symbols.map((s) => worker.execute(s)); - - // Some tasks should be queued - expect(worker.getQueuedTasks()).toBeGreaterThan(0); - - await Promise.all(executionPromises); - expect(worker.getQueuedTasks()).toBe(0); - }); - }); - - describe("Worker Statistics", () => { - test("should track execution statistics", async () => { - await worker.start(); - - const symbols = Array.from({ length: 3 }, (_, i) => ({ - name: `stat_task_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "executor", - parameters: {}, - })); - - for (const symbol of symbols) { - await worker.execute(symbol); - } - - const stats = worker.getStatistics(); - expect(stats.tasksCompleted).toBe(3); - expect(stats.tasksSucceeded).toBe(3); - expect(stats.tasksFailed).toBe(0); - }); - - test("should calculate average execution time", async () => { - await worker.start(); - - const symbol: Symbol = { - name: "timed_task", - type: SymbolType.Action, - context: "test", - dispatch: "timed_executor", - parameters: {}, - }; - - await worker.execute(symbol); - await worker.execute(symbol); - - const stats = worker.getStatistics(); - expect(stats.averageExecutionTime).toBeGreaterThan(0); - }); - - test("should track failure rate", async () => { - await worker.start(); - - // Execute some failing tasks - const failingSymbol: Symbol = { - name: "failing_task", - type: SymbolType.Action, - context: "test", - dispatch: "failing_executor", - parameters: {}, - }; - - for (let i = 0; i < 3; i++) { - try { - await worker.execute(failingSymbol); - } catch (e) { - // Expected - } - } - - const stats = worker.getStatistics(); - expect(stats.tasksFailed).toBe(3); - expect(stats.failureRate).toBe(1.0); - }); - }); - - describe("Worker Health", () => { - test("should report healthy status", () => { - expect(worker.isHealthy()).toBe(true); - }); - - test("should report unhealthy on high failure rate", async () => { - await worker.start(); - - // Simulate many failures - for (let i = 0; i < 10; i++) { - try { - await worker.execute({ - name: `fail_${i}`, - type: SymbolType.Action, - context: "test", - dispatch: "failing_executor", - parameters: {}, - }); - } catch (e) { - // Expected - } - } - - expect(worker.isHealthy()).toBe(false); - }); - - test("should perform health check", async () => { - const healthCheck = await worker.healthCheck(); - expect(healthCheck.healthy).toBe(true); - expect(healthCheck.workerId).toBe("worker-1"); - }); - }); - - describe("Worker Communication", () => { - test("should send heartbeat", () => { - const heartbeatReceived = mock(() => {}); - worker.on("heartbeat", heartbeatReceived); - - worker.sendHeartbeat(); - expect(heartbeatReceived).toHaveBeenCalled(); - }); - - test("should receive messages", () => { - const messageHandler = mock(() => {}); - worker.on("message", messageHandler); - - worker.receiveMessage({ type: "command", payload: "test" }); - expect(messageHandler).toHaveBeenCalledWith( - expect.objectContaining({ type: "command" }) - ); - }); - }); -}); diff --git a/praxis/SymbolicEngine/swarm/tsconfig.json b/praxis/SymbolicEngine/swarm/tsconfig.json deleted file mode 100644 index 85b4a6c..0000000 --- a/praxis/SymbolicEngine/swarm/tsconfig.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "compilerOptions": { - "target": "ESNext", - "module": "ESNext", - "lib": ["ESNext"], - "moduleResolution": "bundler", - "types": ["bun-types"], - - // Strict Type-Checking Options - "strict": true, - "noImplicitAny": true, - "strictNullChecks": true, - "strictFunctionTypes": true, - "strictBindCallApply": true, - "strictPropertyInitialization": true, - "noImplicitThis": true, - "alwaysStrict": true, - - // Additional Checks - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedIndexedAccess": true, - - // Module Resolution Options - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "resolveJsonModule": true, - "isolatedModules": true, - - // Output Options - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "./dist", - "rootDir": "./src", - - // Advanced Options - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - }, - "include": [ - "src/**/*", - "bin/**/*" - ], - "exclude": [ - "node_modules", - "dist" - ] -} diff --git a/praxis/examples/EXAMPLES_SUMMARY.md b/praxis/examples/EXAMPLES_SUMMARY.md index 97dd83b..778a12f 100644 --- a/praxis/examples/EXAMPLES_SUMMARY.md +++ b/praxis/examples/EXAMPLES_SUMMARY.md @@ -237,7 +237,7 @@ Five comprehensive tutorials with complete documentation, example files, and tro - Creating custom Rust operations - Custom PHP symbols - Custom PowerShell functions -- Custom TypeScript handlers +- Custom handlers - Testing custom symbols - Best practices @@ -313,7 +313,7 @@ Five comprehensive tutorials with complete documentation, example files, and tro **Script Features**: - Dependency checking -- Automatic building (Rust, Elixir, TypeScript) +- Automatic building (Rust, Elixir, ) - Configuration creation - Directory setup - Optional database setup @@ -538,7 +538,7 @@ examples/ - ✅ PowerShell - ✅ PHP - ✅ Elixir -- ✅ TypeScript +- ✅ - ✅ YAML - ✅ TOML diff --git a/praxis/examples/FAQ.md b/praxis/examples/FAQ.md index 412c4ce..2ef81a6 100644 --- a/praxis/examples/FAQ.md +++ b/praxis/examples/FAQ.md @@ -17,7 +17,7 @@ Each language serves a specific purpose: - **PowerShell**: Symbolic operations and workflows - **PHP**: WordPress-native integration - **Elixir**: Orchestration and state management -- **TypeScript**: Dashboard, swarm coordination +- ****: Dashboard, swarm coordination This polyglot approach allows each component to leverage the best tool for its specific job. @@ -60,7 +60,7 @@ For basic usage, you need: For advanced features: - Elixir (database/state management) -- TypeScript/Bun (swarm/dashboard) +- /Bun (swarm/dashboard) ### Can I run WP Praxis on Windows? diff --git a/praxis/examples/QUICKSTART.md b/praxis/examples/QUICKSTART.md index 1c67adf..53f442b 100644 --- a/praxis/examples/QUICKSTART.md +++ b/praxis/examples/QUICKSTART.md @@ -64,7 +64,7 @@ This script will: 1. Check prerequisites 2. Build Rust injector 3. Setup Elixir CLI -4. Install TypeScript dependencies +4. Install dependencies 5. Create configuration 6. Run example workflow @@ -106,7 +106,7 @@ cargo build --release cd /home/user/wp-praxis/Core/cli-wrapper mix deps.get && mix compile -# TypeScript (Swarm & Dashboard) +# (Swarm & Dashboard) cd /home/user/wp-praxis/SymbolicEngine/swarm bun install cd /home/user/wp-praxis/SymbolicEngine/dashboard diff --git a/praxis/examples/TROUBLESHOOTING.md b/praxis/examples/TROUBLESHOOTING.md index 2a0c440..f3101a6 100644 --- a/praxis/examples/TROUBLESHOOTING.md +++ b/praxis/examples/TROUBLESHOOTING.md @@ -21,7 +21,7 @@ pwsh -Command "Test-Path SymbolicEngine/core/symbolic.ps1" # 3. Elixir CLI cd Core/cli-wrapper && mix --version -# 4. TypeScript (Bun) +# 4. (Bun) bun --version # 5. WordPress connection (if configured) @@ -117,7 +117,7 @@ mix deps.clean --all mix deps.get ``` -### TypeScript Build Fails: "Cannot find module" +### Build Fails: "Cannot find module" **Problem**: Dependencies not installed diff --git a/praxis/examples/tutorials/04-database-integration/README.md b/praxis/examples/tutorials/04-database-integration/README.md index 5477bc0..4396867 100644 --- a/praxis/examples/tutorials/04-database-integration/README.md +++ b/praxis/examples/tutorials/04-database-integration/README.md @@ -189,7 +189,7 @@ query { summary { totalChanges optionsChanged - postsChanged + poshanged } } } diff --git a/praxis/examples/tutorials/05-custom-symbols/README.md b/praxis/examples/tutorials/05-custom-symbols/README.md index 57a30b7..7a014c6 100644 --- a/praxis/examples/tutorials/05-custom-symbols/README.md +++ b/praxis/examples/tutorials/05-custom-symbols/README.md @@ -10,7 +10,7 @@ Learn how to extend WP Praxis by creating custom symbol types and dispatchers. **Time Required**: 30 minutes **Difficulty**: Advanced -**Prerequisites**: Knowledge of Rust, PHP, PowerShell, or TypeScript +**Prerequisites**: Knowledge of Rust, PHP, PowerShell, or ## Custom Symbol Types @@ -321,13 +321,13 @@ symbols: - space_recovered ``` -## Example 4: Custom TypeScript Symbol (Swarm) +## Example 4: Custom Symbol (Swarm) -### Step 1: Create TypeScript Handler +### Step 1: Create Handler Create `/home/user/wp-praxis/SymbolicEngine/swarm/src/handlers/custom-analytics.ts`: -```typescript +``` import { SymbolParameters, SymbolResult } from '../types'; export interface CustomAnalyticsParams extends SymbolParameters { @@ -398,7 +398,7 @@ function generateRecommendations(metrics: Record): string[] { Edit `/home/user/wp-praxis/SymbolicEngine/swarm/src/worker.ts`: -```typescript +``` import { executeCustomAnalytics } from './handlers/custom-analytics'; async function executeSymbol(symbol: Symbol): Promise { @@ -420,7 +420,7 @@ async function executeSymbol(symbol: Symbol): Promise { symbols: - name: "analyze_performance" type: "analysis" - dispatch: "typescript" + dispatch: "" context: "swarm" execution: swarm_enabled: true @@ -522,6 +522,6 @@ You now know how to: ✓ Create custom Rust injector operations ✓ Create custom PHP symbols ✓ Create custom PowerShell functions -✓ Create custom TypeScript handlers +✓ Create custom handlers ✓ Test custom symbols ✓ Use custom symbols in workflows diff --git a/praxis/examples/video-demo/DEMO_SCRIPT.md b/praxis/examples/video-demo/DEMO_SCRIPT.md index 9418038..13ea551 100644 --- a/praxis/examples/video-demo/DEMO_SCRIPT.md +++ b/praxis/examples/video-demo/DEMO_SCRIPT.md @@ -52,7 +52,7 @@ Copyright (c) Jonathan D.A. Jewell - "PowerShell handles core symbolic operations" - "Elixir manages orchestration and state" - "PHP integrates directly with WordPress" -- "TypeScript powers the dashboard and distributed swarm" +- " powers the dashboard and distributed swarm" **[VISUAL: Show data flow diagram]** @@ -331,7 +331,7 @@ query { 1. "WordPress at scale through symbolic workflows" (15s) 2. "4x faster with distributed execution" (10s) 3. "Declarative workflows with automatic rollback" (12s) -4. "Multi-language execution: Rust, PHP, PowerShell, Elixir, TypeScript" (8s) +4. "Multi-language execution: Rust, PHP, PowerShell, Elixir, " (8s) ## Alternative Takes diff --git a/praxis/examples/web-project-deno.json b/praxis/examples/web-project-deno.json deleted file mode 100644 index 5ddd3bd..0000000 --- a/praxis/examples/web-project-deno.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "// NOTE": "Example deno.json for ReScript web projects", - "tasks": { - "build": "deno run -A npm:rescript", - "clean": "deno run -A npm:rescript clean", - "watch": "deno run -A npm:rescript -w", - "serve": "deno run -A jsr:@std/http/file-server .", - "test": "deno test --allow-all" - }, - "imports": { - "rescript": "^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.0", - "safe-dom/": "https://raw.githubusercontent.com/hyperpolymath/rescript-dom-mounter/main/src/", - "proven/": "../proven/bindings/rescript/src/" - }, - "compilerOptions": { - "allowJs": true, - "checkJs": false - } -} diff --git a/praxis/examples/workflows/swarm-distributed.yaml b/praxis/examples/workflows/swarm-distributed.yaml index 15d016c..8d1dcd2 100644 --- a/praxis/examples/workflows/swarm-distributed.yaml +++ b/praxis/examples/workflows/swarm-distributed.yaml @@ -36,7 +36,6 @@ symbols: - name: "initialize_swarm" type: "swarm" description: "Initialize swarm dispatcher and discover workers" - dispatch: "typescript" context: "swarm" parameters: operation: "initialize_dispatcher" @@ -58,7 +57,6 @@ symbols: - name: "register_health_monitors" type: "swarm" description: "Register health monitoring for all workers" - dispatch: "typescript" context: "swarm" depends_on: - "initialize_swarm" @@ -339,7 +337,6 @@ symbols: - name: "aggregate_worker_results" type: "aggregation" description: "Aggregate results from all parallel executions" - dispatch: "typescript" context: "swarm" depends_on: - "create_bulk_posts_1" @@ -371,7 +368,6 @@ symbols: - name: "generate_swarm_performance_report" type: "reporting" description: "Generate performance report for swarm execution" - dispatch: "typescript" context: "swarm" depends_on: - "aggregate_worker_results" @@ -421,7 +417,6 @@ symbols: - name: "scale_down_swarm" type: "swarm" description: "Gracefully scale down swarm workers" - dispatch: "typescript" context: "swarm" depends_on: - "verify_distributed_integrity" @@ -441,7 +436,6 @@ symbols: - name: "cleanup_swarm" type: "swarm" description: "Cleanup swarm dispatcher and resources" - dispatch: "typescript" context: "swarm" depends_on: - "scale_down_swarm" diff --git a/praxis/tests/README.md b/praxis/tests/README.md index b4eb71f..604adda 100644 --- a/praxis/tests/README.md +++ b/praxis/tests/README.md @@ -37,7 +37,7 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # PHP (PHPUnit) composer install -# TypeScript/Bun +# /Bun curl -fsSL https://bun.sh/install | bash ``` @@ -60,8 +60,8 @@ pwsh tests/run-tests.ps1 -Suite rust # PHP tests only pwsh tests/run-tests.ps1 -Suite php -# TypeScript tests only -pwsh tests/run-tests.ps1 -Suite typescript +# tests only +pwsh tests/run-tests.ps1 -Suite # Integration tests pwsh tests/run-tests.ps1 -Suite integration @@ -132,7 +132,7 @@ tests/ - **Coverage**: WordPress integration, Symbol class, Symbolic Engine - **Scope**: Unit tests, WordPress integration tests -#### TypeScript Tests (`SymbolicEngine/swarm/tests/`) +#### Tests (`SymbolicEngine/swarm/tests/`) - **Framework**: Bun test - **Coverage**: Dispatcher, Worker, Coordinator - **Scope**: Unit tests, integration tests @@ -219,7 +219,7 @@ vendor/bin/phpunit --coverage-html tests/coverage/php-html vendor/bin/phpunit --filter test_create_symbol ``` -### TypeScript Tests (Bun) +### Tests (Bun) ```bash # Run all tests @@ -338,9 +338,9 @@ class FeatureTest extends TestCase } ``` -### TypeScript Test Example (Bun) +### Test Example (Bun) -```typescript +``` import { describe, test, expect } from "bun:test"; describe("Feature", () => { @@ -386,7 +386,7 @@ open wp_injector/target/tarpaulin/index.html # PHP coverage open tests/coverage/php-html/index.html -# TypeScript coverage +# coverage open SymbolicEngine/swarm/coverage/index.html ``` @@ -405,7 +405,7 @@ open SymbolicEngine/swarm/coverage/index.html | Rust Injector | 85% | TBD | | Elixir DB Schema | 75% | TBD | | PHP WordPress | 80% | TBD | -| TypeScript Swarm | 75% | TBD | +| Swarm | 75% | TBD | ## CI/CD Integration @@ -422,7 +422,7 @@ Tests run automatically on: 2. **Rust Tests** (Ubuntu) 3. **Elixir Tests** (Ubuntu) 4. **PHP Tests** (Ubuntu with MySQL) -5. **TypeScript Tests** (Ubuntu) +5. ** Tests** (Ubuntu) 6. **E2E Tests** (Ubuntu, requires all previous stages) 7. **Coverage Report** (Combined coverage) @@ -481,7 +481,7 @@ sudo systemctl status mysql # Update phpunit.xml with correct credentials ``` -#### TypeScript Tests Fail +#### Tests Fail ```bash cd SymbolicEngine/swarm diff --git a/praxis/wp_injector/Cargo.lock b/praxis/wp_injector/Cargo.lock index 8e2000e..576fcd0 100644 --- a/praxis/wp_injector/Cargo.lock +++ b/praxis/wp_injector/Cargo.lock @@ -2,23 +2,11 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -31,18 +19,18 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -55,15 +43,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -90,9 +78,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "atoi" @@ -105,9 +93,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base64" @@ -117,15 +105,21 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.0" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" -version = "2.10.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" dependencies = [ "serde_core", ] @@ -141,9 +135,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "byteorder" @@ -153,15 +147,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.2.47" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "shlex", @@ -175,9 +169,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -189,9 +183,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" dependencies = [ "clap_builder", "clap_derive", @@ -199,9 +193,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" dependencies = [ "anstream", "anstyle", @@ -211,36 +205,27 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-oid" @@ -250,9 +235,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation" -version = "0.9.4" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -275,33 +260,33 @@ dependencies = [ [[package]] name = "crc" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" dependencies = [ "crc-catalog", ] [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crossbeam-queue" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +checksum = "803d13fb3b09d88be9f4dbc29062c66b19bf7170867ceb746d2a8689bf6c7a26" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crypto-common" @@ -313,6 +298,37 @@ dependencies = [ "typenum", ] +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.20", +] + [[package]] name = "der" version = "0.7.10" @@ -359,13 +375,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -376,18 +392,18 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" dependencies = [ "serde", ] [[package]] name = "env_filter" -version = "0.1.4" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", "regex", @@ -395,9 +411,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -435,26 +451,25 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.4.1" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" dependencies = [ - "concurrent-queue", "parking", "pin-project-lite", ] [[package]] name = "fastrand" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "flume" @@ -467,6 +482,12 @@ dependencies = [ "spin", ] +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -493,9 +514,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -503,15 +524,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -531,27 +552,27 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-io", @@ -559,7 +580,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -575,9 +595,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", @@ -586,39 +606,39 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi", - "wasip2", ] [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "ahash", "allocator-api2", + "equivalent", + "foldhash", ] [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "hashlink" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.15.5", ] [[package]] @@ -662,9 +682,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -686,12 +706,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -699,9 +720,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -712,9 +733,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -726,16 +747,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -746,15 +768,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -778,9 +800,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -788,12 +810,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", ] [[package]] @@ -804,16 +826,18 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.16" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ + "defmt", + "jiff-core", "jiff-static", "log", "portable-atomic", @@ -821,24 +845,35 @@ dependencies = [ "serde_core", ] +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + [[package]] name = "jiff-static" -version = "0.2.16" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] @@ -853,25 +888,26 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a" dependencies = [ - "bitflags", + "bitflags 2.13.1", "libc", - "redox_syscall", + "plain", + "redox_syscall 0.9.3", ] [[package]] @@ -880,22 +916,21 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ - "cc", "pkg-config", "vcpkg", ] [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "lock_api" @@ -908,9 +943,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "md-5" @@ -924,21 +959,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "mio" -version = "1.1.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -947,9 +976,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ "libc", "log", @@ -962,16 +991,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "num-bigint-dig" version = "0.8.6" @@ -990,20 +1009,19 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1020,9 +1038,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -1032,11 +1050,11 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.80" +version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags", + "bitflags 2.13.1", "cfg-if", "foreign-types", "libc", @@ -1052,20 +1070,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "openssl-probe" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.116" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -1103,17 +1121,11 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -1131,15 +1143,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs1" @@ -1164,30 +1170,36 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.4" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -1203,33 +1215,33 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.42" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" -version = "5.3.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", "rand_chacha", @@ -1252,7 +1264,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] @@ -1261,7 +1273,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.1", +] + +[[package]] +name = "redox_syscall" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d678d17679829e73d371e96880897e98fee2ded7acc0a50bdf8af2affa4b2fe5" +dependencies = [ + "bitflags 2.13.1", ] [[package]] @@ -1270,16 +1291,16 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -1289,9 +1310,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -1300,9 +1321,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rsa" @@ -1326,11 +1347,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -1339,21 +1360,21 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -1366,11 +1387,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.11.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.13.1", "core-foundation", "core-foundation-sys", "libc", @@ -1379,9 +1400,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -1389,9 +1410,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -1399,35 +1420,35 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -1466,9 +1487,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" dependencies = [ "cfg-if", "cpufeatures", @@ -1488,16 +1509,17 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -1513,34 +1535,34 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" dependencies = [ "serde", ] [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] @@ -1555,21 +1577,11 @@ dependencies = [ "der", ] -[[package]] -name = "sqlformat" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" -dependencies = [ - "nom", - "unicode_categories", -] - [[package]] name = "sqlx" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcfa89bea9500db4a0d038513d7a060566bfc51d46d1c014847049a45cce85e8" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" dependencies = [ "sqlx-core", "sqlx-macros", @@ -1580,39 +1592,34 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06e2f2bd861719b1f3f0c7dbe1d80c30bf59e76cf019f07d9014ed7eefb8e08" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ - "atoi", - "byteorder", + "base64", "bytes", "chrono", "crc", "crossbeam-queue", "either", "event-listener", - "futures-channel", "futures-core", "futures-intrusive", "futures-io", "futures-util", - "hashbrown 0.14.5", + "hashbrown 0.15.5", "hashlink", - "hex", "indexmap", "log", "memchr", "native-tls", "once_cell", - "paste", "percent-encoding", "serde", "serde_json", "sha2", "smallvec", - "sqlformat", - "thiserror", + "thiserror 2.0.20", "tokio", "tokio-stream", "tracing", @@ -1621,22 +1628,22 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f998a9defdbd48ed005a89362bd40dd2117502f15294f61c8d47034107dbbdc" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn", + "syn 2.0.119", ] [[package]] name = "sqlx-macros-core" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d100558134176a2629d46cec0c8891ba0be8910f7896abfdb75ef4ab6f4e7ce" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", @@ -1652,21 +1659,20 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn", - "tempfile", + "syn 2.0.119", "tokio", "url", ] [[package]] name = "sqlx-mysql" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cac0ab331b14cb3921c62156d913e4c15b74fb6ec0f3146bd4ef6e4fb3c12" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64", - "bitflags", + "bitflags 2.13.1", "byteorder", "bytes", "chrono", @@ -1696,20 +1702,20 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 2.0.20", "tracing", "whoami", ] [[package]] name = "sqlx-postgres" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9734dbce698c67ecf67c442f768a5e90a49b2a4d61a9f1d59f73874bd4cf0710" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64", - "bitflags", + "bitflags 2.13.1", "byteorder", "chrono", "crc", @@ -1717,7 +1723,6 @@ dependencies = [ "etcetera", "futures-channel", "futures-core", - "futures-io", "futures-util", "hex", "hkdf", @@ -1735,16 +1740,16 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", + "thiserror 2.0.20", "tracing", "whoami", ] [[package]] name = "sqlx-sqlite" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75b419c3c1b1697833dd927bdc4c6545a620bc1bbafabd44e1efbe9afcd337e" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" dependencies = [ "atoi", "chrono", @@ -1760,6 +1765,7 @@ dependencies = [ "serde", "serde_urlencoded", "sqlx-core", + "thiserror 2.0.20", "tracing", "url", ] @@ -1795,9 +1801,20 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.110" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -1812,17 +1829,17 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "tempfile" -version = "3.23.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", @@ -1834,7 +1851,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl 2.0.20", ] [[package]] @@ -1845,14 +1871,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -1860,9 +1897,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -1875,9 +1912,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.48.0" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -1892,20 +1929,20 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -1955,9 +1992,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -1967,29 +2004,29 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-bidi" @@ -1999,9 +2036,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization" @@ -2018,12 +2055,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -2032,13 +2063,14 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -2071,15 +2103,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - [[package]] name = "wasite" version = "0.1.0" @@ -2088,9 +2111,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -2101,9 +2124,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2111,22 +2134,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] @@ -2162,7 +2185,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2173,7 +2196,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2206,16 +2229,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -2233,30 +2247,13 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -2265,105 +2262,51 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - [[package]] name = "wp_injector" version = "0.1.0" @@ -2380,22 +2323,22 @@ dependencies = [ "serde_yaml", "sqlx", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "toml", ] [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -2404,68 +2347,68 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.28" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.28" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -2474,9 +2417,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -2485,11 +2428,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/praxis/wp_injector/IMPLEMENTATION.md b/praxis/wp_injector/IMPLEMENTATION.md index 72cd3a5..fc85667 100644 --- a/praxis/wp_injector/IMPLEMENTATION.md +++ b/praxis/wp_injector/IMPLEMENTATION.md @@ -457,7 +457,7 @@ Manifest (YAML/TOML) - **Elixir CLI**: Orchestration and dispatch - **PowerShell Engine**: Symbolic operations - **PHP Plugin**: WordPress hook registration -- **TypeScript Tools**: Manifest validation and transformation +- ** Tools**: Manifest validation and transformation ## Success Criteria Met diff --git a/project-wharf/.claude/CLAUDE.md b/project-wharf/.claude/CLAUDE.md index 04ef6f8..dfae44d 100644 --- a/project-wharf/.claude/CLAUDE.md +++ b/project-wharf/.claude/CLAUDE.md @@ -29,7 +29,7 @@ Copyright (c) Jonathan D.A. Jewell | Banned | Replacement | |--------|-------------| -| TypeScript | AffineScript | +| | AffineScript | | Node.js | Deno | | npm | Deno | | Bun | Deno | @@ -52,7 +52,7 @@ Both are FOSS with independent governance (no Big Tech). ### Enforcement Rules -1. **No new TypeScript files** - Convert existing TS to AffineScript +1. **No new files** - Convert existing TS to AffineScript 2. **No package.json - use deno.json deps** - Use deno.json imports 3. **No node_modules in production** - Deno caches deps automatically 4. **No Go code** - Use Rust instead diff --git a/project-wharf/.gitignore b/project-wharf/.gitignore index afe0dfb..665c13b 100644 --- a/project-wharf/.gitignore +++ b/project-wharf/.gitignore @@ -37,7 +37,7 @@ erl_crash.dump *.jl.mem /Manifest.toml -# ReScript +# /lib/bs/ /.bsb.lock diff --git a/project-wharf/.nojekyll b/project-wharf/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/project-wharf/Cargo.lock b/project-wharf/Cargo.lock index 23b0653..a6308b8 100644 --- a/project-wharf/Cargo.lock +++ b/project-wharf/Cargo.lock @@ -32,18 +32,18 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -56,15 +56,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "argon2" @@ -103,21 +103,15 @@ checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", "blake2", - "cpufeatures", + "cpufeatures 0.2.17", "password-hash", ] -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "assert_matches" @@ -127,13 +121,13 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -144,9 +138,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "axum" @@ -176,7 +170,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower 0.5.2", + "tower 0.5.3", "tower-layer", "tower-service", "tracing", @@ -211,7 +205,7 @@ checksum = "90eea657cc8028447cbda5068f4e10c4fadba0131624f4f7dd1a9c46ffc8d81f" dependencies = [ "assert_matches", "aya-obj", - "bitflags 2.10.0", + "bitflags 2.13.1", "bytes", "lazy_static", "libc", @@ -248,9 +242,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.1" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" @@ -260,9 +254,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "blake2" @@ -275,15 +269,15 @@ dependencies = [ [[package]] name = "blake3" -version = "1.8.2" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", + "cpufeatures 0.3.0", ] [[package]] @@ -297,30 +291,30 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eb4cdd6cf1b31d671e9efe75c5d1ec614776856cefbe109ca373554a6d514f" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ "hybrid-array", ] [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.2.51" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "jobserver", @@ -336,9 +330,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" @@ -348,7 +342,18 @@ checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", +] + +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", ] [[package]] @@ -358,7 +363,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", - "chacha20", + "chacha20 0.9.1", "cipher", "poly1305", "zeroize", @@ -366,9 +371,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -390,9 +395,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" dependencies = [ "clap_builder", "clap_derive", @@ -400,9 +405,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" dependencies = [ "anstream", "anstyle", @@ -412,21 +417,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cmov" @@ -436,9 +441,9 @@ checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-oid" @@ -448,9 +453,9 @@ checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "core-error" @@ -469,9 +474,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpubits" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" @@ -482,33 +487,42 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crypto-bigint" -version = "0.7.0-rc.27" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b43308b9b6a47554f4612d5b1fb95ff935040aa3927dd42b1d6cbc015a262d96" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ "cpubits", "ctutils", - "getrandom 0.4.1", + "getrandom 0.4.3", "hybrid-array", "num-traits", - "rand_core 0.10.0", + "rand_core 0.10.1", "subtle", "zeroize", ] @@ -526,20 +540,20 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "211f05e03c7d03754740fd9e585de910a095d6b99f8bcfffdef8319fa02a8331" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.4.3", "hybrid-array", - "rand_core 0.10.0", + "rand_core 0.10.1", ] [[package]] name = "ctutils" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1005a6d4446f5120ef475ad3d2af2b30c49c2c9c6904258e3bb30219bebed5e4" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" dependencies = [ "cmov", "subtle", @@ -547,9 +561,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" +checksum = "a69dedd701da44b0536442edf09c81a64b0ab97a7a4a5e3d1971f00027cbc63d" dependencies = [ "const-oid", "zeroize", @@ -568,12 +582,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bf3682cdec91817be507e4aa104314898b95b84d74f3d43882210101a545b6" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.11.0", - "crypto-common 0.2.0", + "block-buffer 0.12.1", + "crypto-common 0.2.2", ] [[package]] @@ -599,13 +613,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -616,9 +630,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "ed448" -version = "0.5.0-rc.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a6517ef61d12c57c218393995d2ee5ab2dac4c27501d24f7595590e097985c9" +checksum = "ae112a25f86ae3598d4e8533ed1e65149cec6eb21918e7a6f4c06dddec370263" dependencies = [ "pkcs8", "signature", @@ -626,34 +640,34 @@ dependencies = [ [[package]] name = "ed448-goldilocks" -version = "0.14.0-pre.10" +version = "0.14.0-pre.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5c8e6341702ff3b4d27a1a21c4ad3d38f3b18facc3b94e04f9157bae4089c0" +checksum = "b805154de2e68f59874ec217ca36790dcffe500cd872c60fe509d28d0814a74d" dependencies = [ "ed448", "elliptic-curve", "hash2curve", - "rand_core 0.10.0", + "rand_core 0.10.1", "serdect", - "sha3 0.11.0-rc.7", + "shake", "signature", "subtle", ] [[package]] name = "elliptic-curve" -version = "0.14.0-rc.28" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde7860544606d222fd6bd6d9f9a0773321bf78072a637e1d560a058c0031978" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", - "crypto-common 0.2.0", + "crypto-common 0.2.2", + "ff", + "group", "hybrid-array", "pkcs8", - "rand_core 0.10.0", - "rustcrypto-ff", - "rustcrypto-group", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", @@ -677,27 +691,35 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "ff" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" +dependencies = [ + "rand_core 0.10.1", + "subtle", +] [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", - "windows-sys 0.60.2", ] [[package]] name = "find-msvc-tools" -version = "0.1.6" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "fnv" @@ -705,12 +727,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -731,41 +747,41 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-task", "pin-project-lite", - "pin-utils", + "slab", ] [[package]] @@ -780,9 +796,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -798,38 +814,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", - "r-efi", - "rand_core 0.10.0", - "wasip2", - "wasip3", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasm-bindgen", ] [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "group" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" +dependencies = [ + "ff", + "rand_core 0.10.1", + "subtle", +] [[package]] name = "h2" -version = "0.4.12" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "839c0e8a181239723652be9062bb56ca5bf5f64011f73b623f6f4fc59086a228" dependencies = [ "atomic-waker", "bytes", @@ -846,11 +871,11 @@ dependencies = [ [[package]] name = "hash2curve" -version = "0.14.0-rc.10" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3448b4c05089875da77b94b1177c36f79a5dcf4b316bc999f8dd3d7f3da42eda" +checksum = "1eaf40612d7d854743e7189228a6d528f0f6e8502cf6a0cb831d28a218b7f3f6" dependencies = [ - "digest 0.11.0", + "digest 0.11.3", "elliptic-curve", ] @@ -866,18 +891,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -911,9 +927,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -921,9 +937,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -931,9 +947,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -956,9 +972,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.7" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b229d73f5803b562cc26e4da0396c8610a4ee209f4fac8fa4f8d709166dc45" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" dependencies = [ "subtle", "typenum", @@ -967,9 +983,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" dependencies = [ "atomic-waker", "bytes", @@ -982,7 +998,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -990,15 +1005,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", @@ -1007,14 +1021,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", "bytes", "futures-channel", - "futures-core", "futures-util", "http", "http-body", @@ -1031,9 +1044,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1055,12 +1068,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1068,9 +1082,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -1081,9 +1095,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1095,16 +1109,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -1115,15 +1130,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -1134,12 +1149,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "idna" version = "1.1.0" @@ -1153,9 +1162,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1163,14 +1172,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", - "serde", - "serde_core", + "hashbrown 0.17.1", ] [[package]] @@ -1186,9 +1193,9 @@ dependencies = [ [[package]] name = "inotify-sys" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +checksum = "c033f80b2c113cdf91ab7a33faa9cbc014726dcad99880c8609af2a370edf37d" dependencies = [ "libc", ] @@ -1204,19 +1211,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" -dependencies = [ - "memchr", - "serde", -] +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" [[package]] name = "is_terminal_polyfill" @@ -1226,27 +1223,28 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] @@ -1256,23 +1254,24 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] name = "keccak" -version = "0.2.0-rc.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a412fe37705d515cba9dbf1448291a717e187e2351df908cfc0137cbec3d480" +checksum = "d8f198d1db720e4940b5a493201d199d9f24f568f8f746bd13706243a2f71598" dependencies = [ - "cpufeatures", + "cfg-if", + "cpufeatures 0.3.0", ] [[package]] name = "kqueue" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +checksum = "8d763e5b24120b4ddf50de6c92308156765aabfbbccebf401da7cff2d70a41ea" dependencies = [ "kqueue-sys", "libc", @@ -1280,11 +1279,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.4" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.13.1", "libc", ] @@ -1294,40 +1293,32 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" -version = "0.2.178" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "28d0a00925a9f930d679b6789b721e3a7f9ed110f41b86d2497caa780c3a070a" dependencies = [ - "bitflags 2.10.0", "libc", - "redox_syscall 0.7.0", ] [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "lock_api" @@ -1340,9 +1331,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "lru-slab" @@ -1358,9 +1349,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "mime" @@ -1382,9 +1373,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -1397,7 +1388,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.1", "crossbeam-channel", "filetime", "fsevent-sys", @@ -1439,9 +1430,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -1479,7 +1470,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -1509,21 +1500,15 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.11.0-rc.11" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -1535,16 +1520,16 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -1590,30 +1575,20 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" -version = "1.0.104" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", @@ -1623,7 +1598,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror 2.0.18", + "thiserror 2.0.20", "tokio", "tracing", "web-time", @@ -1631,20 +1606,21 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83" dependencies = [ "bytes", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", "rand", + "rand_pcg", "ring", "rustc-hash", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 2.0.20", "tinyvec", "tracing", "web-time", @@ -1652,23 +1628,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.42" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -1679,14 +1655,21 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" -version = "0.9.4" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", + "chacha20 0.10.1", + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] @@ -1699,56 +1682,37 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "rand_pcg" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" dependencies = [ - "bitflags 2.10.0", + "rand_core 0.10.1", ] [[package]] name = "redox_syscall" -version = "0.7.0" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.1", ] [[package]] @@ -1757,7 +1721,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", "thiserror 1.0.69", ] @@ -1790,7 +1754,7 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", - "tower 0.5.2", + "tower 0.5.3", "tower-http", "tower-service", "url", @@ -1808,7 +1772,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -1816,38 +1780,17 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustcrypto-ff" -version = "0.14.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5db129183b2c139d7d87d08be57cba626c715789db17aec65c8866bfd767d1f" -dependencies = [ - "rand_core 0.10.0", - "subtle", -] - -[[package]] -name = "rustcrypto-group" -version = "0.14.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c4b1463f274a3ff6fb2f44da43e576cb9424367bd96f185ead87b52fe00523" -dependencies = [ - "rand_core 0.10.0", - "rustcrypto-ff", - "subtle", -] +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -1856,9 +1799,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "once_cell", "ring", @@ -1870,9 +1813,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "web-time", "zeroize", @@ -1880,9 +1823,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "ring", "rustls-pki-types", @@ -1891,15 +1834,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -1918,9 +1861,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.8.0-rc.13" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2400ed44a13193820aa528a19f376c3843141a8ce96ff34b11104cc79763f2" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", "ctutils", @@ -1930,17 +1873,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -1948,29 +1885,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.148" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -2013,9 +1950,9 @@ dependencies = [ [[package]] name = "serdect" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af4a3e75ebd5599b30d4de5768e00b5095d518a79fefc3ecbaf77e665d1ec06" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" dependencies = [ "base16ct", "serde", @@ -2023,22 +1960,23 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" dependencies = [ "digest 0.10.7", "keccak 0.1.6", ] [[package]] -name = "sha3" -version = "0.11.0-rc.7" +name = "shake" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5bfe7820113e633d8886e839aae78c1184b8d7011000db6bc7eb61e34f28350" +checksum = "09057cb2149ad4cbd2da1e26b351f9a4c354219421229c69c3063e6f61947c4a" dependencies = [ - "digest 0.11.0", - "keccak 0.2.0-rc.1", + "digest 0.11.3", + "keccak 0.2.2", + "sponge-cursor", ] [[package]] @@ -2052,9 +1990,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -2068,46 +2006,52 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.10" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ - "digest 0.11.0", - "rand_core 0.10.0", + "digest 0.11.3", + "rand_core 0.10.1", ] [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "spki" -version = "0.8.0-rc.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] +[[package]] +name = "sponge-cursor" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" + [[package]] name = "sqlparser" version = "0.39.0" @@ -2137,9 +2081,20 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.111" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -2163,17 +2118,17 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "tempfile" -version = "3.24.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", @@ -2190,11 +2145,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.20", ] [[package]] @@ -2205,34 +2160,34 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -2240,9 +2195,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -2255,13 +2210,13 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.48.0" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", - "mio 1.1.1", + "mio 1.2.2", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -2272,13 +2227,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -2293,13 +2248,14 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.17" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] @@ -2358,9 +2314,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -2374,20 +2330,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.1", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", - "tower 0.5.2", + "tower 0.5.3", "tower-layer", "tower-service", + "url", ] [[package]] @@ -2422,7 +2378,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2458,9 +2414,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "nu-ansi-term", "serde", @@ -2481,21 +2437,15 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "universal-hash" @@ -2576,27 +2526,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen 0.46.0", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -2607,22 +2548,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2630,65 +2568,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.10.0", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" dependencies = [ "js-sys", "wasm-bindgen", @@ -2706,9 +2610,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" dependencies = [ "rustls-pki-types", ] @@ -2745,12 +2649,12 @@ dependencies = [ "hkdf", "pqcrypto-mldsa", "pqcrypto-traits", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", "reqwest", "serde", "serde_json", - "sha3 0.10.8", + "sha3", "sqlparser", "tempfile", "thiserror 1.0.69", @@ -2789,7 +2693,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2800,7 +2704,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2845,15 +2749,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -2887,30 +2782,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -2923,12 +2801,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -2941,12 +2813,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -2959,24 +2825,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -2989,12 +2843,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3007,12 +2855,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3025,12 +2867,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3043,120 +2879,26 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.10.0", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "xtask" @@ -3189,9 +2931,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -3200,82 +2942,82 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -3284,9 +3026,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -3295,17 +3037,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "zmij" -version = "1.0.2" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/resurrect/.claude/CLAUDE.md b/resurrect/.claude/CLAUDE.md index 5a0b803..96308ba 100644 --- a/resurrect/.claude/CLAUDE.md +++ b/resurrect/.claude/CLAUDE.md @@ -28,7 +28,7 @@ Copyright (c) Jonathan D.A. Jewell | Banned | Replacement | |--------|-------------| -| TypeScript | AffineScript | +| | AffineScript | | Node.js | Deno | | npm | Deno | | Bun | Deno | @@ -51,7 +51,7 @@ Both are FOSS with independent governance (no Big Tech). ### Enforcement Rules -1. **No new TypeScript files** - Convert existing TS to AffineScript +1. **No new files** - Convert existing TS to AffineScript 2. **No package.json - use deno.json deps** - Use deno.json imports 3. **No node_modules in production** - Deno caches deps automatically 4. **No Go code** - Use Rust instead diff --git a/resurrect/.github/workflows/codeql.yml b/resurrect/.github/workflows/codeql.yml index 7158018..e3f6e22 100644 --- a/resurrect/.github/workflows/codeql.yml +++ b/resurrect/.github/workflows/codeql.yml @@ -43,10 +43,8 @@ jobs: include: - language: actions build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how diff --git a/resurrect/.gitignore b/resurrect/.gitignore index 45f10b1..7e40e94 100644 --- a/resurrect/.gitignore +++ b/resurrect/.gitignore @@ -37,7 +37,7 @@ erl_crash.dump *.jl.mem /Manifest.toml -# ReScript +# /lib/bs/ /.bsb.lock diff --git a/resurrect/.nojekyll b/resurrect/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/resurrect/ABI-FFI-README.md b/resurrect/ABI-FFI-README.md index ada05ff..d27c3ea 100644 --- a/resurrect/ABI-FFI-README.md +++ b/resurrect/ABI-FFI-README.md @@ -47,7 +47,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: ▼ ┌─────────────────────────────────────────────┐ │ Any Language via C ABI │ -│ - Rust, ReScript, Julia, Python, etc. │ +│ - Rust, , Julia, Python, etc. │ └─────────────────────────────────────────────┘ ``` @@ -79,7 +79,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: │ └── bindings/ # Language-specific wrappers (optional) ├── rust/ - ├── rescript/ + ├── / └── julia/ ``` @@ -343,8 +343,8 @@ zig build test-integration -- Runtime checks main : IO () main = do - verifyLayoutsCorrect - verifyAlignmentsCorrect + verifyLayouorrect + verifyAlignmenorrect putStrLn "ABI verification passed" ``` diff --git a/resurrect/RSR_OUTLINE.adoc b/resurrect/RSR_OUTLINE.adoc index 0ad555a..036001f 100644 --- a/resurrect/RSR_OUTLINE.adoc +++ b/resurrect/RSR_OUTLINE.adoc @@ -148,7 +148,7 @@ project/ === Language Tiers -* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, ReScript +* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, * **Tier 2** (Silver): Nickel, Racket, Guile Scheme, Nix * **Infrastructure**: Guix channels, derivations @@ -168,7 +168,7 @@ project/ === Prohibited * Python outside `salt/` directory -* TypeScript/JavaScript (use ReScript) +* /JavaScript (use ) * CUE (use Guile/Nickel) * `Dockerfile` (use `Containerfile`) diff --git a/resurrect/examples/web-project-deno.json b/resurrect/examples/web-project-deno.json deleted file mode 100644 index 5ddd3bd..0000000 --- a/resurrect/examples/web-project-deno.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "// NOTE": "Example deno.json for ReScript web projects", - "tasks": { - "build": "deno run -A npm:rescript", - "clean": "deno run -A npm:rescript clean", - "watch": "deno run -A npm:rescript -w", - "serve": "deno run -A jsr:@std/http/file-server .", - "test": "deno test --allow-all" - }, - "imports": { - "rescript": "^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.0", - "safe-dom/": "https://raw.githubusercontent.com/hyperpolymath/rescript-dom-mounter/main/src/", - "proven/": "../proven/bindings/rescript/src/" - }, - "compilerOptions": { - "allowJs": true, - "checkJs": false - } -} diff --git a/secured/.github/workflows/codeql.yml b/secured/.github/workflows/codeql.yml index 0607869..72fc11e 100644 --- a/secured/.github/workflows/codeql.yml +++ b/secured/.github/workflows/codeql.yml @@ -19,7 +19,6 @@ jobs: fail-fast: false matrix: include: - - language: javascript-typescript build-mode: none steps: - name: Checkout diff --git a/secured/ABI-FFI-README.md b/secured/ABI-FFI-README.md index ada05ff..d27c3ea 100644 --- a/secured/ABI-FFI-README.md +++ b/secured/ABI-FFI-README.md @@ -47,7 +47,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: ▼ ┌─────────────────────────────────────────────┐ │ Any Language via C ABI │ -│ - Rust, ReScript, Julia, Python, etc. │ +│ - Rust, , Julia, Python, etc. │ └─────────────────────────────────────────────┘ ``` @@ -79,7 +79,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: │ └── bindings/ # Language-specific wrappers (optional) ├── rust/ - ├── rescript/ + ├── / └── julia/ ``` @@ -343,8 +343,8 @@ zig build test-integration -- Runtime checks main : IO () main = do - verifyLayoutsCorrect - verifyAlignmentsCorrect + verifyLayouorrect + verifyAlignmenorrect putStrLn "ABI verification passed" ``` diff --git a/secured/README.adoc b/secured/README.adoc index 537c523..4f9420e 100644 --- a/secured/README.adoc +++ b/secured/README.adoc @@ -48,17 +48,17 @@ project/ === Web Projects -ReScript web projects in the hyperpolymath ecosystem **MUST** use these formally verified components: + web projects in the hyperpolymath ecosystem **MUST** use these formally verified components: [cols="1,2,1"] |=== |Library |Purpose |Status -|link:https://github.com/hyperpolymath/rescript-dom-mounter[rescript-dom-mounter] +|link:https://github.com/hyperpolymath/-dom-mounter[-dom-mounter] |Formally verified DOM mounting |**REQUIRED** -|link:https://github.com/hyperpolymath/rescript-tea[rescript-tea] +|link:https://github.com/hyperpolymath/-tea[-tea] |TEA architecture framework |Recommended @@ -84,7 +84,7 @@ el.innerHTML = html // 💥 SafeDOM provides **compile-time proofs** that DOM operations cannot fail: -[source,rescript] +[source,] ---- // ✅ PROVEN SAFE: Mathematically guaranteed SafeDOM.mountSafe("#app", html, @@ -97,7 +97,7 @@ SafeDOM.mountSafe("#app", html, ✓ No null pointer dereferences (Idris2 proof) ✓ No invalid CSS selectors (dependent types) ✓ No malformed HTML (balanced tag checking) -✓ Type-safe operations (ReScript + Idris2) +✓ Type-safe operations ( + Idris2) ✓ Zero runtime overhead (proofs erased) -See link:https://github.com/hyperpolymath/rescript-dom-mounter[rescript-dom-mounter documentation] for full details. +See link:https://github.com/hyperpolymath/-dom-mounter[-dom-mounter documentation] for full details. diff --git a/secured/RSR_OUTLINE.adoc b/secured/RSR_OUTLINE.adoc index 0ad555a..036001f 100644 --- a/secured/RSR_OUTLINE.adoc +++ b/secured/RSR_OUTLINE.adoc @@ -148,7 +148,7 @@ project/ === Language Tiers -* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, ReScript +* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, * **Tier 2** (Silver): Nickel, Racket, Guile Scheme, Nix * **Infrastructure**: Guix channels, derivations @@ -168,7 +168,7 @@ project/ === Prohibited * Python outside `salt/` directory -* TypeScript/JavaScript (use ReScript) +* /JavaScript (use ) * CUE (use Guile/Nickel) * `Dockerfile` (use `Containerfile`) diff --git a/secured/examples/web-project-deno.json b/secured/examples/web-project-deno.json deleted file mode 100644 index 5ddd3bd..0000000 --- a/secured/examples/web-project-deno.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "// NOTE": "Example deno.json for ReScript web projects", - "tasks": { - "build": "deno run -A npm:rescript", - "clean": "deno run -A npm:rescript clean", - "watch": "deno run -A npm:rescript -w", - "serve": "deno run -A jsr:@std/http/file-server .", - "test": "deno test --allow-all" - }, - "imports": { - "rescript": "^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.0", - "safe-dom/": "https://raw.githubusercontent.com/hyperpolymath/rescript-dom-mounter/main/src/", - "proven/": "../proven/bindings/rescript/src/" - }, - "compilerOptions": { - "allowJs": true, - "checkJs": false - } -} diff --git a/secured/php-aegis/.claude/CLAUDE.md b/secured/php-aegis/.claude/CLAUDE.md index 9b0b940..efa504e 100644 --- a/secured/php-aegis/.claude/CLAUDE.md +++ b/secured/php-aegis/.claude/CLAUDE.md @@ -41,7 +41,7 @@ The following files in `.machine_readable/` contain structured project metadata: | Banned | Replacement | |--------|-------------| -| TypeScript | AffineScript | +| | AffineScript | | Node.js | Deno | | npm | Deno | | Bun | Deno | @@ -64,7 +64,7 @@ Both are FOSS with independent governance (no Big Tech). ### Enforcement Rules -1. **No new TypeScript files** - Convert existing TS to AffineScript +1. **No new files** - Convert existing TS to AffineScript 2. **No package.json - use deno.json deps** - Use deno.json imports 3. **No node_modules in production** - Deno caches deps automatically 4. **No Go code** - Use Rust instead diff --git a/secured/php-aegis/.github/workflows/codeql.yml b/secured/php-aegis/.github/workflows/codeql.yml index 32b827f..4e50d8d 100644 --- a/secured/php-aegis/.github/workflows/codeql.yml +++ b/secured/php-aegis/.github/workflows/codeql.yml @@ -19,7 +19,6 @@ jobs: fail-fast: false matrix: include: - - language: javascript-typescript build-mode: none steps: - name: Checkout diff --git a/secured/php-aegis/.gitignore b/secured/php-aegis/.gitignore index 3872813..7145cc0 100644 --- a/secured/php-aegis/.gitignore +++ b/secured/php-aegis/.gitignore @@ -37,7 +37,7 @@ erl_crash.dump *.jl.mem /Manifest.toml -# ReScript +# /lib/bs/ /.bsb.lock diff --git a/secured/php-aegis/.nojekyll b/secured/php-aegis/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/secured/php-aegis/docs/CERRO-TORRE-INTEGRATION.md b/secured/php-aegis/docs/CERRO-TORRE-INTEGRATION.md index 5ea9f73..61a2146 100644 --- a/secured/php-aegis/docs/CERRO-TORRE-INTEGRATION.md +++ b/secured/php-aegis/docs/CERRO-TORRE-INTEGRATION.md @@ -21,8 +21,8 @@ This guide explains how to deploy php-aegis WordPress using the **Verified Conta ┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ SVALINN │ │ VÖRÐR │ │ CERRO TORRE │ │ Edge Gateway │───────▶│ Container Runtime│◀────────│ Builder │ -│ (Deno/ │delegate│ (Rust/Ada) │produces │ (Ada/SPARK) │ -│ ReScript) │ │ │ │ │ +│ (/ │delegate│ (Rust/Ada) │produces │ (Ada/SPARK) │ +│ ) │ │ │ │ │ └──────┬───────┘ └────────┬─────────┘ └────────┬────────┘ │ │ │ │ │ │ @@ -82,8 +82,8 @@ alr build git clone https://github.com/hyperpolymath/svalinn.git cd svalinn -# Install with Deno -deno install --allow-all svalinn-compose +# Install with + install --allow-all svalinn-compose # Verify installation svalinn-compose --version diff --git a/secured/php-aegis/validation/VALIDATION-REPORT.md b/secured/php-aegis/validation/VALIDATION-REPORT.md index 95701f8..047eab6 100644 --- a/secured/php-aegis/validation/VALIDATION-REPORT.md +++ b/secured/php-aegis/validation/VALIDATION-REPORT.md @@ -344,7 +344,7 @@ All tests must pass with the following outcomes: ### Known Limitations -1. **Attestation Coverage**: 25% - Shadow verifier exists but requires patscc +1. **Attestation Coverage**: 25% - Shadow verifier exists but requires pac 2. **Plugin Install Failures**: Some plugins may fail to install in test environment 3. **Theme Rendering**: Visual verification not automated 4. **Performance Impact**: Rate limiting adds ~1-2ms per request diff --git a/sinople-theme/.claude/CLAUDE.md b/sinople-theme/.claude/CLAUDE.md index 9b0b940..efa504e 100644 --- a/sinople-theme/.claude/CLAUDE.md +++ b/sinople-theme/.claude/CLAUDE.md @@ -41,7 +41,7 @@ The following files in `.machine_readable/` contain structured project metadata: | Banned | Replacement | |--------|-------------| -| TypeScript | AffineScript | +| | AffineScript | | Node.js | Deno | | npm | Deno | | Bun | Deno | @@ -64,7 +64,7 @@ Both are FOSS with independent governance (no Big Tech). ### Enforcement Rules -1. **No new TypeScript files** - Convert existing TS to AffineScript +1. **No new files** - Convert existing TS to AffineScript 2. **No package.json - use deno.json deps** - Use deno.json imports 3. **No node_modules in production** - Deno caches deps automatically 4. **No Go code** - Use Rust instead diff --git a/sinople-theme/.github/workflows/codeql.yml b/sinople-theme/.github/workflows/codeql.yml index 2a0c0ee..fdb5ee6 100644 --- a/sinople-theme/.github/workflows/codeql.yml +++ b/sinople-theme/.github/workflows/codeql.yml @@ -41,16 +41,12 @@ jobs: fail-fast: false matrix: include: - - language: javascript-typescript build-mode: none - - language: javascript-typescript build-mode: none - language: rust build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how diff --git a/sinople-theme/.gitignore b/sinople-theme/.gitignore index 70aa2dd..0665a23 100644 --- a/sinople-theme/.gitignore +++ b/sinople-theme/.gitignore @@ -37,13 +37,13 @@ erl_crash.dump *.jl.mem /Manifest.toml -# ReScript +# /lib/bs/ /.bsb.lock *.res.js -rescript/lib/ -rescript/node_modules/ -rescript/package-lock.json +/lib/ +/node_modules/ +/package-lock.json # Python (SaltStack only) __pycache__/ diff --git a/sinople-theme/.gitlab-ci.yml b/sinople-theme/.gitlab-ci.yml index f70692c..3612825 100644 --- a/sinople-theme/.gitlab-ci.yml +++ b/sinople-theme/.gitlab-ci.yml @@ -64,33 +64,33 @@ build:wasm: key: rust-wasm-${CI_COMMIT_REF_SLUG} paths: - wasm/semantic_processor/target/ -build:rescript: +build:: stage: build image: node:${NODE_VERSION} script: - - cd rescript + - cd - npm install - - npx rescript clean - - npx rescript build + - npx clean + - npx build artifacts: paths: - - rescript/src/**/*.res.js + - /src/**/*.res.js expire_in: 1 day cache: - key: node-rescript-${CI_COMMIT_REF_SLUG} + key: node--${CI_COMMIT_REF_SLUG} paths: - - rescript/node_modules/ + - /node_modules/ build:theme: stage: build dependencies: - build:wasm - - build:rescript + - build: script: - mkdir -p wordpress/assets/wasm - mkdir -p wordpress/assets/js - cp wasm/semantic_processor/pkg/*.js wordpress/assets/wasm/ || true - cp wasm/semantic_processor/pkg/*.wasm wordpress/assets/wasm/ || true - - find rescript/src -name "*.res.js" -exec cp {} wordpress/assets/js/ \; || true + - find /src -name "*.res.js" -exec cp {} wordpress/assets/js/ \; || true - echo "✅ Theme assembled" artifacts: paths: @@ -113,23 +113,23 @@ test:rust: junit: wasm/semantic_processor/target/nextest/junit.xml expire_in: 1 week allow_failure: true # Until tests are fully implemented -test:rescript: +test:: stage: test image: node:${NODE_VERSION} dependencies: - - build:rescript + - build: script: - - cd rescript - - npm test || echo "No ReScript tests configured" + - cd + - npm test || echo "No tests configured" allow_failure: true # Until tests are fully implemented test:integration: stage: test - image: denoland/deno:${DENO_VERSION} + image: denoland/:${DENO_VERSION} dependencies: - build:wasm - - build:rescript + - build: script: - - deno test --allow-read tests/ || echo "No integration tests configured" + - test --allow-read tests/ || echo "No integration tests configured" allow_failure: true # Until tests are fully implemented # ============================================================================ # SECURITY STAGE @@ -146,7 +146,7 @@ security:audit-npm: stage: security image: node:${NODE_VERSION} script: - - cd rescript + - cd - npm audit --production || true allow_failure: true # Don't fail build on advisories (warn only) security:sast: @@ -216,7 +216,7 @@ cache: paths: - .cargo/ - wasm/semantic_processor/target/ - - rescript/node_modules/ + - /node_modules/ # ============================================================================ # WORKFLOW RULES # ============================================================================ diff --git a/sinople-theme/.nojekyll b/sinople-theme/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/sinople-theme/.tool-versions b/sinople-theme/.tool-versions new file mode 100644 index 0000000..1eea92a --- /dev/null +++ b/sinople-theme/.tool-versions @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: MPL-2.0 +# asdf version management +# Run 'asdf install' to install all tools + +# Primary runtime +deno 2.1.4 + diff --git a/sinople-theme/ABI-FFI-README.md b/sinople-theme/ABI-FFI-README.md index ada05ff..d27c3ea 100644 --- a/sinople-theme/ABI-FFI-README.md +++ b/sinople-theme/ABI-FFI-README.md @@ -47,7 +47,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: ▼ ┌─────────────────────────────────────────────┐ │ Any Language via C ABI │ -│ - Rust, ReScript, Julia, Python, etc. │ +│ - Rust, , Julia, Python, etc. │ └─────────────────────────────────────────────┘ ``` @@ -79,7 +79,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: │ └── bindings/ # Language-specific wrappers (optional) ├── rust/ - ├── rescript/ + ├── / └── julia/ ``` @@ -343,8 +343,8 @@ zig build test-integration -- Runtime checks main : IO () main = do - verifyLayoutsCorrect - verifyAlignmentsCorrect + verifyLayouorrect + verifyAlignmenorrect putStrLn "ABI verification passed" ``` diff --git a/sinople-theme/CHANGELOG.adoc b/sinople-theme/CHANGELOG.adoc index 9f1cfd4..7bc45ef 100644 --- a/sinople-theme/CHANGELOG.adoc +++ b/sinople-theme/CHANGELOG.adoc @@ -36,12 +36,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Turtle format parser - Construct/Entanglement/Character queries - Network graph generation for visualization -- ReScript type-safe bindings (450+ lines) +- type-safe bindings (450+ lines) - WASM integration layer - Domain models (Construct, Entanglement, Character, Gloss) - Error handling with Result types - Example usage patterns -- Deno + Fresh framework integration +- + Fresh framework integration - Server-side rendering setup - API route structure - Island architecture @@ -123,8 +123,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ==== Build System - Master build.sh script - WASM-specific build.sh for Rust compilation -- ReScript compilation configuration -- Deno task definitions +- compilation configuration +- task definitions - .gitignore for build artifacts ==== Documentation diff --git a/sinople-theme/CLAUDE.md b/sinople-theme/CLAUDE.md index a1d8c28..09475b7 100644 --- a/sinople-theme/CLAUDE.md +++ b/sinople-theme/CLAUDE.md @@ -6,13 +6,13 @@ Copyright (c) Jonathan D.A. Jewell ## Project Overview -**Sinople** (from the heraldic term for green) is a modern, semantically-aware WordPress theme built with cutting-edge web technologies. It combines traditional WordPress theming with a modern ReScript + Deno + WASM stack for maximum type safety, performance, and semantic web capabilities. +**Sinople** (from the heraldic term for green) is a modern, semantically-aware WordPress theme built with cutting-edge web technologies. It combines traditional WordPress theming with a modern + + WASM stack for maximum type safety, performance, and semantic web capabilities. ### Core Mission - **Semantic Web First**: RDF/OWL processing for character relationships, glosses, and entanglements - **IndieWeb Level 4**: Full Webmention and Micropub support - **Maximum Accessibility**: WCAG 2.3 AAA compliance mandatory -- **Type Safety**: ReScript-only (NO TypeScript) with WASM integration +- **Type Safety**: -only (NO ) with WASM integration - **Performance**: Rust-powered WASM for semantic processing ## Architecture Overview @@ -25,13 +25,13 @@ Copyright (c) Jonathan D.A. Jewell │ ▼ ┌─────────────────────────────────────────────────────────┐ -│ Deno + Fresh Framework │ +│ + Fresh Framework │ │ (Server-side rendering, API routes, Islands) │ └────────────────┬────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ -│ ReScript Business Logic │ +│ Business Logic │ │ (Type-safe bindings, components, utilities) │ └────────────────┬────────────────────────────────────────┘ │ @@ -53,7 +53,7 @@ This section clarifies the responsibilities and boundaries between each layer, i | **WordPress** | Production-ready | 85% | Fully functional theme with CPTs, IndieWeb, RDF endpoints | | **Rust/WASM** | Production-ready | 100% | Complete semantic processor with Sophia 0.8 | | **AffineScript** | Bindings complete | 40% | WASM bindings done; components/services not started | -| **Deno/Fresh** | Scaffolded only | 5% | Config exists; no routes or islands implemented | +| **/Fresh** | Scaffolded only | 5% | Config exists; no routes or islands implemented | ### Layer Responsibilities @@ -82,7 +82,7 @@ This section clarifies the responsibilities and boundaries between each layer, i ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ DENO/FRESH LAYER (Future) │ -│ Runtime: Deno 1.40+ Location: deno/ │ +│ Runtime: 1.40+ Location: / │ ├─────────────────────────────────────────────────────────────────────────────┤ │ PLANNED RESPONSIBILITIES: │ │ ○ Server-side rendering of enhanced pages │ @@ -92,7 +92,7 @@ This section clarifies the responsibilities and boundaries between each layer, i │ ○ Real-time subscriptions (WebSocket) │ │ │ │ CURRENT STATUS: │ -│ ⚠ Only configuration files exist (deno.json, main.ts, dev.ts) │ +│ ⚠ Only configuration files exist (.json, main.ts, dev.ts) │ │ ⚠ No routes/ or islands/ directories implemented │ │ ⚠ lib/ has type definitions only │ └─────────────────────────────────────────────────────────────────────────────┘ @@ -100,8 +100,8 @@ This section clarifies the responsibilities and boundaries between each layer, i │ ES6 Imports ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ -│ RESCRIPT LAYER │ -│ Runtime: Compiled to ES6 JS Location: rescript/ │ +│ LAYER │ +│ Runtime: Compiled to ES6 JS Location: / │ ├─────────────────────────────────────────────────────────────────────────────┤ │ IMPLEMENTED: │ │ ✓ SemanticProcessor.res - Complete WASM bindings with types │ @@ -113,14 +113,14 @@ This section clarifies the responsibilities and boundaries between each layer, i │ ✗ UI components (Graph.res, Navigation.res, Card.res) │ │ ✗ Domain models (Construct.res, Entanglement.res) │ │ ✗ Service layer (SemanticService.res, WordPressService.res) │ -│ ✗ WordPress.res and Deno.res bindings │ +│ ✗ WordPress.res and .res bindings │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ wasm-bindgen FFI ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ RUST/WASM LAYER │ -│ Runtime: Browser WASM or Deno Location: wasm/semantic_processor/ │ +│ Runtime: Browser WASM or Location: wasm/semantic_processor/ │ ├─────────────────────────────────────────────────────────────────────────────┤ │ FULLY IMPLEMENTED: │ │ ✓ SemanticProcessor struct with FastGraph │ @@ -154,20 +154,20 @@ Browser → WordPress REST API → JSON ↓ Browser → Load WASM Module ↓ -Browser → ReScript calls WASM → Semantic Graph Data +Browser → calls WASM → Semantic Graph Data ↓ Browser → Render visualization (D3.js/Canvas) ``` -Available now: WASM processor + ReScript bindings work. +Available now: WASM processor + bindings work. Missing: UI components and integration. -#### Pattern 3: Deno Edge Rendering (Planned, Not Implemented) +#### Pattern 3: Edge Rendering (Planned, Not Implemented) ``` -Browser → Deno/Fresh → WordPress REST API → JSON +Browser → /Fresh → WordPress REST API → JSON ↳ WASM Processing ↳ SSR HTML Response ``` -This pattern is not yet implemented. Deno layer is scaffolded only. +This pattern is not yet implemented. layer is scaffolded only. ### Communication Protocols @@ -179,9 +179,9 @@ This pattern is not yet implemented. Deno layer is scaffolded only. | Browser | WordPress | POST | `/wp-json/sinople/v1/webmention` | ✓ Active | | Browser | WordPress | POST | `/wp-json/sinople/v1/micropub` | ✓ Active | | Browser | WASM | FFI | `wasm-bindgen` calls | ✓ Active | -| ReScript | WASM | FFI | `@module` bindings | ✓ Active | -| Deno | WordPress | REST | Proxy `/api/wordpress` | ○ Planned | -| Deno | Browser | SSR | Fresh routes | ○ Planned | +| | WASM | FFI | `@module` bindings | ✓ Active | +| | WordPress | REST | Proxy `/api/wordpress` | ○ Planned | +| | Browser | SSR | Fresh routes | ○ Planned | ### Deployment Modes @@ -195,18 +195,18 @@ This pattern is not yet implemented. Deno layer is scaffolded only. ``` - Install `wordpress/` as a standard WP theme - WASM optional client-side enhancement -- No Deno required +- No required -#### Mode B: Headless + Deno (Future) +#### Mode B: Headless + (Future) ``` ┌─────────────────────────────┐ ┌─────────────────────────┐ -│ WordPress (Headless API) │────▶│ Deno/Fresh (Edge) │ +│ WordPress (Headless API) │────▶│ /Fresh (Edge) │ │ Content Management Only │ │ SSR + Islands │ └─────────────────────────────┘ └─────────────────────────┘ ``` - WordPress provides content API only -- Deno handles all user-facing rendering -- Requires implementing `deno/routes/` and `deno/islands/` +- handles all user-facing rendering +- Requires implementing `/routes/` and `/islands/` ### File Ownership by Layer @@ -214,12 +214,12 @@ This pattern is not yet implemented. Deno layer is scaffolded only. |-------|----------|------------| | `wordpress/**/*.php` | WordPress | WordPress only | | `wordpress/assets/css/*` | WordPress | WordPress, build scripts | -| `wordpress/assets/js/*` | WordPress | WordPress, compiled ReScript | -| `rescript/src/**/*.res` | ReScript | ReScript only | -| `rescript/src/**/*.res.js` | Build | Generated (do not edit) | +| `wordpress/assets/js/*` | WordPress | WordPress, compiled | +| `/src/**/*.res` | | only | +| `/src/**/*.res.js` | Build | Generated (do not edit) | | `wasm/semantic_processor/src/*` | Rust | Rust only | | `wasm/semantic_processor/pkg/*` | Build | Generated (do not edit) | -| `deno/**/*.ts` | Deno | Deno, compiled ReScript | +| `/**/*.ts` | | , compiled | | `ontology/*.ttl` | Ontology | Ontology editors | ### Integration Points @@ -231,7 +231,7 @@ This pattern is not yet implemented. Deno layer is scaffolded only. 2. **Browser ↔ WASM** - JavaScript loads `semantic_processor_bg.wasm` - - ReScript-compiled JS calls WASM via bindings + - -compiled JS calls WASM via bindings - Graph data returned as JS objects (serde_wasm_bindgen) 3. **WordPress ↔ RDF** @@ -301,14 +301,14 @@ wp-sinople-theme/ │ └── languages/ # i18n translation files │ └── sinople.pot │ -├── deno/ # Deno + Fresh application -│ ├── deno.json # Deno configuration +├── / # + Fresh application +│ ├── .json # configuration │ ├── import_map.json # Import maps │ ├── dev.ts # Development server │ ├── main.ts # Production server │ ├── fresh.gen.ts # Auto-generated Fresh manifest │ ├── routes/ # Fresh file-based routing -│ │ ├── index.tsx # Home page (ReScript) +│ │ ├── index.tsx # Home page () │ │ ├── api/ │ │ │ ├── webmention.ts # Webmention endpoint │ │ │ ├── micropub.ts # Micropub endpoint @@ -319,12 +319,12 @@ wp-sinople-theme/ │ │ │ └── [slug].tsx # Dynamic construct pages │ │ └── entanglements/ │ │ └── [slug].tsx # Dynamic entanglement pages -│ ├── islands/ # Interactive islands (ReScript) +│ ├── islands/ # Interactive islands () │ │ ├── SemanticGraph.tsx # RDF graph visualization │ │ ├── GlossAnnotation.tsx # Inline glosses │ │ ├── CharacterNetwork.tsx # Character relationship viewer │ │ └── SearchFilter.tsx # Accessible search/filter -│ ├── components/ # Shared components (ReScript) +│ ├── components/ # Shared components () │ │ ├── Layout.res │ │ ├── Navigation.res │ │ ├── Footer.res @@ -335,13 +335,13 @@ wp-sinople-theme/ │ ├── IndieWeb.res # Webmention/Micropub │ └── Cache.ts # Caching layer │ -├── rescript/ # ReScript source code -│ ├── bsconfig.json # ReScript configuration +├── / # source code +│ ├── bsconfig.json # configuration │ ├── src/ │ │ ├── bindings/ # External bindings │ │ │ ├── SemanticProcessor.res # WASM bindings │ │ │ ├── WordPress.res # WP REST API -│ │ │ └── Deno.res # Deno runtime +│ │ │ └── .res # runtime │ │ ├── components/ # UI components │ │ │ ├── Graph.res # RDF graph viewer │ │ │ ├── Gloss.res # Annotation components @@ -387,12 +387,12 @@ wp-sinople-theme/ │ └── characters.ttl # Character relationships │ ├── build/ # Build outputs -│ ├── rescript/ # Compiled ReScript -│ └── deno/ # Deno bundles +│ ├── / # Compiled +│ └── / # bundles │ ├── tests/ # Test suites │ ├── integration/ -│ │ ├── wasm-rescript.test.ts +│ │ ├── wasm-.test.ts │ │ ├── wordpress-api.test.ts │ │ └── indieweb.test.ts │ └── accessibility/ @@ -408,8 +408,8 @@ wp-sinople-theme/ ### Core Technologies - **WordPress**: 6.0+ (PHP 7.4+) - **Rust**: Stable (WASM compilation) -- **ReScript**: 11+ (NO TypeScript!) -- **Deno**: 1.40+ with Fresh framework +- ****: 11+ (NO !) +- ****: 1.40+ with Fresh framework - **Sophia RDF**: 0.8 (Rust RDF library) ### Key Libraries & Tools @@ -429,7 +429,7 @@ wasm-opt = false # Network restrictions opt-level = "z" # Size optimization ``` -#### ReScript +#### ```json { "name": "sinople-theme", @@ -443,11 +443,11 @@ opt-level = "z" # Size optimization } ``` -#### Deno +#### ```json { "imports": { - "$fresh/": "https://deno.land/x/fresh@1.6.0/", + "$fresh/": "https:///x/fresh@1.6.0/", "preact": "https://esm.sh/preact@10.19.2", "preact/": "https://esm.sh/preact@10.19.2/" }, @@ -525,9 +525,9 @@ impl SemanticProcessor { } ``` -### ReScript Bindings +### Bindings -```rescript +``` // SemanticProcessor.res type t @@ -567,8 +567,8 @@ sn:hasGloss a owl:DatatypeProperty ; ### Webmention Endpoint -```typescript -// deno/routes/api/webmention.ts +``` +// /routes/api/webmention.ts export const handler: Handlers = { async POST(req, ctx) { const form = await req.formData(); @@ -586,8 +586,8 @@ export const handler: Handlers = { ### Micropub Endpoint -```typescript -// deno/routes/api/micropub.ts +``` +// /routes/api/micropub.ts export const handler: Handlers = { async POST(req, ctx) { // Authenticate request @@ -693,25 +693,25 @@ cargo install wasm-pack # Install via cargo (curl blocked) wasm-pack build --target web --out-dir pkg cd ../.. -# 2. Compile ReScript -echo "🔧 Compiling ReScript..." -cd rescript +# 2. Compile +echo "🔧 Compiling ..." +cd npm install # or yarn -npx rescript build +npx build cd .. -# 3. Bundle Deno application -echo "🦕 Bundling Deno..." -cd deno -deno task build +# 3. Bundle application +echo "🦕 Bundling ..." +cd + task build cd .. # 4. Copy assets to WordPress theme echo "📋 Copying assets..." mkdir -p wordpress/assets/wasm cp wasm/semantic_processor/pkg/* wordpress/assets/wasm/ -cp -r build/rescript/* wordpress/assets/js/ -cp -r build/deno/* wordpress/assets/js/ +cp -r build//* wordpress/assets/js/ +cp -r build//* wordpress/assets/js/ echo "✅ Build complete!" ``` @@ -722,11 +722,11 @@ echo "✅ Build complete!" #!/bin/bash # dev.sh -# Watch ReScript files -cd rescript && npx rescript build -w & +# Watch files +cd && npx build -w & -# Watch Deno Fresh -cd deno && deno task start & +# Watch Fresh +cd && task start & # Watch Rust (requires manual rebuild) echo "📝 Rust WASM requires manual rebuild: cd wasm/semantic_processor && ./build.sh" @@ -736,9 +736,9 @@ wait ## Development Guidelines -### ReScript Coding Standards +### Coding Standards -```rescript +``` // Use descriptive names type construct = { id: string, @@ -814,11 +814,11 @@ pub fn load_turtle(&mut self, ttl: &str) -> Result<(), JsValue> { ### Integration Tests -```typescript -// tests/integration/wasm-rescript.test.ts -Deno.test("WASM semantic processor loads ontology", async () => { +``` +// tests/integration/wasm-.test.ts +.test("WASM semantic processor loads ontology", async () => { const processor = new SemanticProcessor(); - const ttl = await Deno.readTextFile("./ontology/sinople.ttl"); + const ttl = await .readTextFile("./ontology/sinople.ttl"); await processor.load_turtle(ttl); const constructs = await processor.query_constructs(); @@ -829,11 +829,11 @@ Deno.test("WASM semantic processor loads ontology", async () => { ### Accessibility Tests -```typescript +``` // tests/accessibility/wcag-aaa.test.ts -import { assertEquals } from "https://deno.land/std/assert/mod.ts"; +import { assertEquals } from "https:///std/assert/mod.ts"; -Deno.test("All text meets AAA contrast ratio", async () => { +.test("All text meets AAA contrast ratio", async () => { // Use axe-core or pa11y const violations = await checkContrast(); assertEquals(violations.length, 0); @@ -955,13 +955,13 @@ Tests panic without browser `console` object → Always skip with `cargo test -- - [REST API Handbook](https://developer.wordpress.org/rest-api/) - [Coding Standards](https://developer.wordpress.org/coding-standards/) -### ReScript -- [ReScript Documentation](https://rescript-lang.org/docs/manual/latest/introduction) -- [ReScript & React](https://rescript-lang.org/docs/react/latest/introduction) +### +- [ Documentation](https://-lang.org/docs/manual/latest/introduction) +- [ & React](https://-lang.org/docs/react/latest/introduction) -### Deno & Fresh -- [Deno Manual](https://deno.land/manual) -- [Fresh Documentation](https://fresh.deno.dev/docs/introduction) +### & Fresh +- [ Manual](https:///manual) +- [Fresh Documentation](https://fresh..dev/docs/introduction) ### Semantic Web - [Sophia RDF](https://docs.rs/sophia/latest/sophia/) @@ -979,7 +979,7 @@ Tests panic without browser `console` object → Always skip with `cargo test -- ## Critical Notes for Claude -1. **NO TypeScript**: This project uses ReScript exclusively +1. **NO **: This project uses exclusively 2. **WCAG 2.3 AAA**: Non-negotiable; always verify contrast, keyboard nav, screen readers 3. **Sophia 0.8**: Use separate crates, not unified package 4. **WASM Tests**: Always skip in CLI builds (need browser environment) @@ -987,13 +987,13 @@ Tests panic without browser `console` object → Always skip with `cargo test -- 6. **IndieWeb**: Webmention + Micropub are core features, not optional 7. **Semantic First**: RDF/OWL processing is central to theme identity 8. **Build Gotchas**: Document all network restrictions and workarounds -9. **Type Safety**: Leverage ReScript's type system; use Result for errors +9. **Type Safety**: Leverage 's type system; use Result for errors 10. **Performance**: WASM is for semantic processing; keep bundle size reasonable ## Support & Community - **Repository**: `Hyperpolymath/wp-sinople-theme` -- **Issues**: File issues on GitHub with `[WASM]`, `[ReScript]`, `[A11y]`, or `[IndieWeb]` tags +- **Issues**: File issues on GitHub with `[WASM]`, `[]`, `[A11y]`, or `[IndieWeb]` tags - **Discussions**: Use GitHub Discussions for architecture questions - **Documentation**: Keep USAGE.md, ROADMAP.md, and STACK.md in sync diff --git a/sinople-theme/CONTRIBUTING.md b/sinople-theme/CONTRIBUTING.md new file mode 100644 index 0000000..99fc819 --- /dev/null +++ b/sinople-theme/CONTRIBUTING.md @@ -0,0 +1,120 @@ + +# Clone the repository +git clone https://github.com/hyperpolymath/wordpress-tools.git +cd wordpress-tools + +# Using Nix (recommended for reproducibility) +nix develop + +# Or using toolbox/distrobox +toolbox create wordpress-tools-dev +toolbox enter wordpress-tools-dev +# Install dependencies manually + +# Verify setup +just check # or: cargo check / mix compile / etc. +just test # Run test suite +``` + +### Repository Structure +``` +wordpress-tools/ +├── src/ # Source code (Perimeter 1-2) +├── lib/ # Library code (Perimeter 1-2) +├── extensions/ # Extensions (Perimeter 2) +├── plugins/ # Plugins (Perimeter 2) +├── tools/ # Tooling (Perimeter 2) +├── docs/ # Documentation (Perimeter 3) +│ ├── architecture/ # ADRs, specs (Perimeter 2) +│ └── proposals/ # RFCs (Perimeter 3) +├── examples/ # Examples (Perimeter 3) +├── spec/ # Spec tests (Perimeter 3) +├── tests/ # Test suite (Perimeter 2-3) +├── .well-known/ # Protocol files (Perimeter 1-3) +├── .github/ # GitHub config (Perimeter 1) +│ ├── ISSUE_TEMPLATE/ +│ └── workflows/ +├── CHANGELOG.md +├── CODE_OF_CONDUCT.md +├── CONTRIBUTING.md # This file +├── GOVERNANCE.md +├── LICENSE +├── MAINTAINERS.md +├── README.adoc +├── SECURITY.md +├── flake.nix # Nix flake (Perimeter 1) +└── justfile # Task runner (Perimeter 1) +``` + +--- + +## How to Contribute + +### Reporting Bugs + +**Before reporting**: +1. Search existing issues +2. Check if it's already fixed in `main` +3. Determine which perimeter the bug affects + +**When reporting**: + +Use the [bug report template](.github/ISSUE_TEMPLATE/bug_report.md) and include: + +- Clear, descriptive title +- Environment details (OS, versions, toolchain) +- Steps to reproduce +- Expected vs actual behaviour +- Logs, screenshots, or minimal reproduction + +### Suggesting Features + +**Before suggesting**: +1. Check the [roadmap](ROADMAP.md) if available +2. Search existing issues and discussions +3. Consider which perimeter the feature belongs to + +**When suggesting**: + +Use the [feature request template](.github/ISSUE_TEMPLATE/feature_request.md) and include: + +- Problem statement (what pain point does this solve?) +- Proposed solution +- Alternatives considered +- Which perimeter this affects + +### Your First Contribution + +Look for issues labelled: + +- [`good first issue`](https://github.com/hyperpolymath/wordpress-tools/labels/good%20first%20issue) — Simple Perimeter 3 tasks +- [`help wanted`](https://github.com/hyperpolymath/wordpress-tools/labels/help%20wanted) — Community help needed +- [`documentation`](https://github.com/hyperpolymath/wordpress-tools/labels/documentation) — Docs improvements +- [`perimeter-3`](https://github.com/hyperpolymath/wordpress-tools/labels/perimeter-3) — Community sandbox scope + +--- + +## Development Workflow + +### Branch Naming +``` +docs/short-description # Documentation (P3) +test/what-added # Test additions (P3) +feat/short-description # New features (P2) +fix/issue-number-description # Bug fixes (P2) +refactor/what-changed # Code improvements (P2) +security/what-fixed # Security fixes (P1-2) +``` + +### Commit Messages + +We follow [Conventional Commits](https://www.conventionalcommits.org/): +``` +(): + +[optional body] + +[optional footer] diff --git a/sinople-theme/DOGFOODING-LESSONS.md b/sinople-theme/DOGFOODING-LESSONS.md index 6d40e6c..3dcec62 100644 --- a/sinople-theme/DOGFOODING-LESSONS.md +++ b/sinople-theme/DOGFOODING-LESSONS.md @@ -163,23 +163,23 @@ Rocket Loader, aggressive caching, respect origin cache headers. **Action:** Create `scripts/cloudflare-baseline.sh` that applies these settings to any zone via the Cloudflare API. -### P6: Replace innerHTML with rescript-dom-mounter (CRITICAL) +### P6: Replace innerHTML with -dom-mounter (CRITICAL) panic-attack flagged innerHTML usage in graph-viewer.js and navigation.js as HIGH severity. The correct fix is NOT to replace innerHTML with createElement (that's just a different unsafe API). The correct fix is to use -**rescript-dom-mounter** (`hyperpolymath/rescript-dom-mounter`) which provides: +**-dom-mounter** (`hyperpolymath/-dom-mounter`) which provides: - 4-layer defence-in-depth (validation, DOMPurify, Trusted Types, CSP nonce) - `mountStringParsed` — DOMParser-based mounting with NO innerHTML sink - Compile-time guarantees via opaque `validSelector` and `validHtml` types - Formal verification of mount correctness via Idris2 ABI proofs -**Action:** Add rescript-dom-mounter as a dependency. Rewrite graph-viewer.js -and navigation.js in ReScript using SafeDOM.mountStringParsed. Remove all raw +**Action:** Add -dom-mounter as a dependency. Rewrite graph-viewer.js +and navigation.js in using SafeDOM.mountStringParsed. Remove all raw innerHTML/document.write calls from the theme's JS. This is the whole point of the library — eat your own dogfood. -```rescript +``` // Before (UNSAFE): // element.innerHTML = graphHtml diff --git a/sinople-theme/EXPLAINME.adoc b/sinople-theme/EXPLAINME.adoc deleted file mode 100644 index 48f3974..0000000 --- a/sinople-theme/EXPLAINME.adoc +++ /dev/null @@ -1,138 +0,0 @@ -= Sinople — Show Me The Receipts - -The README makes claims. This file backs them up. - -A WordPress theme with a built-in knowledge graph, strong security defaults, and IndieWeb support. - -— link:README.adoc[README] - -== Status key - -* ✅ Proven — code exists and is exercised (tests, CI, or both) -* 🔶 Partial — real code exists, but verification is incomplete -* 🚧 In progress — actively being built -* 🎯 Goal — designed, not yet evidenced - -== Claims and receipts - -[cols="2,1,2", options="header"] -|=== -| README claim | Status | Where to check - -| Rust-powered WebAssembly semantic engine -| 🔶 Partial -| `wasm/semantic_processor/` — run `cargo test`, then `./build.sh` - -| ReScript-only, type-safe code (no TypeScript) -| ✅ Proven -| `rescript/` — no `.ts` files exist in the project - -| Deno + Fresh server-side rendering -| 🔶 Partial -| `deno/` — run `deno task start` - -| Constructs and Entanglements post types -| ✅ Proven -| `wordpress/` — registered in theme functions; activate and check the admin menu - -| Webmention endpoint -| 🔶 Partial -| `wordpress/` REST routes — `POST /wp-json/sinople/v1/webmention` - -| Micropub endpoint -| 🚧 In progress -| Endpoint exists at `/wp-json/sinople/v1/micropub`; auth hardening is tracked in open issues. Do not rely on it in production yet. - -| Microformats2 markup on all posts -| 🔶 Partial -| View source on any post; look for `h-entry`. Full parser validation not yet in CI. - -| Argon2id hashing, XChaCha20-Poly1305, Ed25519 -| 🔶 Partial -| link:CRYPTOGRAPHIC-INTEGRATION.md[CRYPTOGRAPHIC-INTEGRATION.md]; all use PHP's built-in `sodium` extension. Note: Argon2id memory cost is configurable — the 512 MiB ceiling will exceed `memory_limit` on shared hosting. - -| Post-quantum signatures -| 🎯 Goal -| PHP and OpenSSL have no native support yet. Plan: deliver ML-DSA (FIPS 204) via our existing Rust→WASM pipeline rather than waiting on PHP. - -| Removes Akismet and Hello Dolly on activation -| ✅ Proven -| `wordpress/` activation hook + `mu-plugins/sinople-no-default-plugins.php` - -| Libravatar support with Gravatar fallback -| 🔶 Partial -| Setting lives under *Settings → Discussion*; manual fallback test not yet automated. - -| Encrypted SMTP (TLS 587) by default -| 🔶 Partial -| PHPMailer hook in `wordpress/`; only applies when SMTP is configured. Disable in `wp-config.php`. - -| WCAG 2.2 AA (AAA where feasible) -| 🎯 Goal -| Contrast and keyboard work are in the CSS/templates; a full audit with axe-core + manual testing has not been run or published. - -| 7:1 contrast ratio -| 🔶 Partial -| Theme stylesheet — verify with any contrast checker against the Sinople palette. - -| Browser support: current Chrome, Firefox, Safari, Edge -| ✅ Proven -| We target link:https://web.dev/baseline[Baseline, Widely Available]. No legacy shims shipped. -|=== - -== File map - -[cols="1,2", options="header"] -|=== -| Path | What's there - -| `wordpress/` | The theme itself — PHP templates, styles, hooks -| `wasm/semantic_processor/` | Rust source for the WebAssembly semantic engine -| `rescript/` | Type-safe application source (ReScript) -| `deno/` | Deno + Fresh server-side application -| `ontology/` | RDF/OWL vocabularies in Turtle format -| `cli/` | Command-line tooling -| `ffi/zig/` | Zig FFI bridge -| `fuzz/` | Fuzz-testing targets -| `contractiles/` | Executable contract checks -| `docs/` | Documentation -| `examples/` | Usage examples -| `data/` | Seed and reference data -| `.machine_readable/6a2` | Machine-readable project metadata -| `.github/` | CI workflows -|=== - -== How to verify for yourself - -[source,bash] ----- -# Rust / WASM -cd wasm/semantic_processor && cargo test - -# ReScript -cd rescript && npm install && npm run build - -# Deno -cd deno && deno task test - -# PHP lint (theme) -find wordpress -name '*.php' -exec php -l {} \; ----- - -== Known gaps — the honest list - -* No `security.txt` is published yet, so we make no RFC 9116 claim. It will be added with a valid `Expires` field. -* `.well-known/humans.txt` and `ai.txt` are planned, not present. -* The full WCAG 2.2 audit has not been run. -* Static-analysis alerts are being triaged; see the Security tab for current counts. -* Earlier versions of this README claimed an "OSI-approved" Palimpsest licence and a `LICENSE.txt` file. Both were wrong and have been corrected. - -== Questions? - -Open an issue or reach out directly — happy to explain anything in more detail. - -== License - -This document is licensed under Creative Commons Attribution-ShareAlike 4.0. Project code is licensed under the Mozilla Public License, v. 2.0. See the LICENSE file for details. - -SPDX-License-Identifier: CC-BY-SA-4.0 diff --git a/sinople-theme/Justfile b/sinople-theme/Justfile index fd3c1ee..9ade0df 100644 --- a/sinople-theme/Justfile +++ b/sinople-theme/Justfile @@ -13,11 +13,11 @@ default: # BUILD RECIPES # ============================================================================ -# Build all components (WASM + ReScript + Deno) +# Build all components (WASM + + Deno) build: @echo "🏗️ Building all components..." just build-wasm - just build-rescript + just build- just build-deno just assemble @echo "✅ Build complete!" @@ -29,14 +29,14 @@ build-wasm: wasm-pack build --target web --out-dir pkg @echo "✅ WASM build complete" -# Build ReScript only -build-rescript: - @echo "🔧 Compiling ReScript..." - cd rescript && \ +# Build only +build-: + @echo "🔧 Compiling ..." + cd && \ npm install && \ - npx rescript clean && \ - npx rescript build - @echo "✅ ReScript compilation complete" + npx clean && \ + npx build + @echo "✅ compilation complete" # Build Deno application build-deno: @@ -52,7 +52,7 @@ assemble: mkdir -p wordpress/assets/js cp wasm/semantic_processor/pkg/*.js wordpress/assets/wasm/ || true cp wasm/semantic_processor/pkg/*.wasm wordpress/assets/wasm/ || true - find rescript/src -name "*.res.js" -exec cp {} wordpress/assets/js/ \; || true + find /src -name "*.res.js" -exec cp {} wordpress/assets/js/ \; || true @echo "✅ Assets assembled" # Clean all build artifacts @@ -60,8 +60,8 @@ clean: @echo "🧹 Cleaning build artifacts..." rm -rf wasm/semantic_processor/target rm -rf wasm/semantic_processor/pkg - rm -rf rescript/lib - rm -rf rescript/node_modules + rm -rf /lib + rm -rf /node_modules rm -rf build rm -rf wordpress/assets/wasm/* find wordpress/assets/js -name "*.res.js" -delete || true @@ -74,16 +74,16 @@ clean: # Start development mode (watch files) dev: @echo "🔥 Starting development mode..." - @echo "Starting ReScript watch..." - cd rescript && npx rescript build -w & + @echo "Starting watch..." + cd && npx build -w & @echo "Starting Deno watch..." cd deno && deno task dev & @echo "Press Ctrl+C to stop" wait -# Watch ReScript files only -watch-rescript: - cd rescript && npx rescript build -w +# Watch files only +watch-: + cd && npx build -w # Watch Deno files only watch-deno: @@ -102,7 +102,7 @@ watch-wasm: test: @echo "🧪 Running all tests..." just test-rust - just test-rescript + just test- just test-deno @echo "✅ All tests passed!" @@ -111,10 +111,10 @@ test-rust: @echo "Testing Rust code..." cd wasm/semantic_processor && cargo test --lib -# Test ReScript code -test-rescript: - @echo "Testing ReScript code..." - cd rescript && npm test || echo "No ReScript tests configured" +# Test code +test-: + @echo "Testing code..." + cd && npm test || echo "No tests configured" # Test Deno code test-deno: @@ -133,7 +133,7 @@ test-integration: # Run all linters and formatters lint: just lint-rust - just lint-rescript + just lint- just lint-php # Lint Rust code @@ -147,10 +147,10 @@ fmt-rust: @echo "Formatting Rust code..." cd wasm/semantic_processor && cargo fmt -# Lint ReScript code -lint-rescript: - @echo "Linting ReScript code..." - cd rescript && npx rescript build || echo "ReScript type-checks on build" +# Lint code +lint-: + @echo "Linting code..." + cd && npx build || echo " type-checks on build" # Lint PHP code (requires phpcs) lint-php: @@ -180,7 +180,7 @@ audit-rust: # Audit NPM dependencies audit-npm: @echo "Auditing NPM dependencies..." - cd rescript && npm audit || echo "Run 'npm audit fix' if needed" + cd && npm audit || echo "Run 'npm audit fix' if needed" # Check for known vulnerabilities check-vulns: @@ -246,7 +246,7 @@ validate-build: @test -f build.sh || (echo "❌ Missing build.sh" && exit 1) @test -x build.sh || (echo "❌ build.sh not executable" && exit 1) @test -f wasm/semantic_processor/Cargo.toml || (echo "❌ Missing Cargo.toml" && exit 1) - @test -f rescript/bsconfig.json || (echo "❌ Missing bsconfig.json" && exit 1) + @test -f /bsconfig.json || (echo "❌ Missing bsconfig.json" && exit 1) @echo "✅ Build system valid" # Validate test suite @@ -265,8 +265,8 @@ stats: @echo "=====================" @echo "Rust:" @find wasm -name "*.rs" | xargs wc -l | tail -1 - @echo "ReScript:" - @find rescript/src -name "*.res" | xargs wc -l | tail -1 || echo " 0 lines" + @echo ":" + @find /src -name "*.res" | xargs wc -l | tail -1 || echo " 0 lines" @echo "PHP:" @find wordpress -name "*.php" | xargs wc -l | tail -1 @echo "JavaScript:" @@ -289,7 +289,7 @@ check-deps: install-deps: @echo "Installing dependencies..." cargo install wasm-pack - cd rescript && npm install + cd && npm install @echo "✅ Dependencies installed" # Show help (alias for default) @@ -320,7 +320,7 @@ ci-build-test: build test # Run example (loads sample ontology) example: @echo "Running example..." - cd rescript && node src/examples/example.res.js || echo "Build ReScript first: just build-rescript" + cd && node src/examples/example.res.js || echo "Build first: just build-" # Serve WordPress locally (requires local WordPress) serve: @@ -336,14 +336,14 @@ serve: update: @echo "Updating dependencies..." cd wasm/semantic_processor && cargo update - cd rescript && npm update + cd && npm update @echo "✅ Dependencies updated" # Check for outdated dependencies outdated: @echo "Checking for outdated dependencies..." cd wasm/semantic_processor && cargo outdated || cargo install cargo-outdated && cargo outdated - cd rescript && npm outdated || true + cd && npm outdated || true # ============================================================================ # ADVANCED RECIPES diff --git a/sinople-theme/MAINTAINERS.md b/sinople-theme/MAINTAINERS.md index 9de904c..f0b1db0 100644 --- a/sinople-theme/MAINTAINERS.md +++ b/sinople-theme/MAINTAINERS.md @@ -58,7 +58,7 @@ Verified contributors can: | Name / Handle | Focus Area | GitHub | Joined | |--------------|------------|--------|--------| | _[To be filled]_ | Documentation | @handle | 2025-11 | -| _[To be filled]_ | ReScript | @handle | 2025-12 | +| _[To be filled]_ | | @handle | 2025-12 | | _[To be filled]_ | Accessibility | @handle | 2025-12 | ### How to Become a Verified Contributor @@ -111,7 +111,7 @@ This project builds on ideas from: - **WordPress Community** - Theme standards and best practices - **Rust Community** - Memory safety and type safety culture -- **ReScript Community** - Sound type system for web development +- ** Community** - Sound type system for web development - **IndieWeb Movement** - Decentralized web standards - **Semantic Web Community** - RDF/OWL ontologies - **Accessibility Advocates** - WCAG compliance and inclusive design diff --git a/sinople-theme/PROJECT_SUMMARY.md b/sinople-theme/PROJECT_SUMMARY.md index 7a65c0f..9ea4073 100644 --- a/sinople-theme/PROJECT_SUMMARY.md +++ b/sinople-theme/PROJECT_SUMMARY.md @@ -6,7 +6,7 @@ Copyright (c) Jonathan D.A. Jewell ## Project Completion Status: ✅ COMPREHENSIVE IMPLEMENTATION -This document summarizes the extensive autonomous development completed for the Sinople WordPress theme - a modern, semantically-aware theme powered by ReScript, Deno, and WASM. +This document summarizes the extensive autonomous development completed for the Sinople WordPress theme - a modern, semantically-aware theme powered by , , and WASM. --- @@ -14,7 +14,7 @@ This document summarizes the extensive autonomous development completed for the - **Total Files Created**: 50+ - **Lines of Code**: 5,800+ -- **Technologies Integrated**: 7 (WordPress, PHP, Rust, ReScript, Deno, RDF, JavaScript) +- **Technologies Integrated**: 7 (WordPress, PHP, Rust, , , RDF, JavaScript) - **Git Commits**: 2 comprehensive commits - **Documentation Pages**: 5 (README, USAGE, ROADMAP, STACK, CLAUDE) @@ -46,10 +46,10 @@ wasm-bindgen = "0.2" serde = "1.0" ``` -### 2. **ReScript Type-Safe Bindings** ✅ +### 2. ** Type-Safe Bindings** ✅ **Files**: -- `rescript/src/bindings/SemanticProcessor.res` (300+ lines) -- `rescript/src/examples/example.res` (150+ lines) +- `/src/bindings/SemanticProcessor.res` (300+ lines) +- `/src/examples/example.res` (150+ lines) - **Domain Types**: Construct, Entanglement, Character, Gloss - **Error Types**: LoadError, ParseError, SerializationError @@ -59,7 +59,7 @@ serde = "1.0" - `findEntanglement()` - Lookup relationships - `errorToString()` - Human-readable errors - `initWithOntology()` - One-step initialization -- **NO TypeScript**: Pure ReScript as required +- **NO **: Pure as required - **Examples**: Comprehensive usage patterns ### 3. **RDF Ontologies** ✅ @@ -206,9 +206,9 @@ Complete template hierarchy: - Status updates for screen readers - Error handling and fallbacks -### 8. **Deno + Fresh Framework** ✅ +### 8. ** + Fresh Framework** ✅ -**deno.json**: +**.json**: - Task definitions (start, build, dev) - Import maps for Fresh 1.6.0 - Compiler options for JSX @@ -223,8 +223,8 @@ Complete template hierarchy: **build.sh** (Master build script): 1. Build Rust WASM with wasm-pack -2. Compile ReScript to ES6 -3. Bundle Deno application +2. Compile to ES6 +3. Bundle application 4. Copy assets to WordPress theme 5. Generate build report @@ -253,7 +253,7 @@ Complete template hierarchy: **ROADMAP.md**: - Version 1.0.0 features (current) -- Version 1.1.0 plans (Deno integration, UI) +- Version 1.1.0 plans ( integration, UI) - Version 1.2.0 future (collaboration, ML) - Version 2.0.0 vision (distributed, VR/AR) @@ -279,7 +279,7 @@ Complete template hierarchy: ### ✅ Implemented as Specified -1. **ReScript Only** - NO TypeScript used anywhere +1. ** Only** - NO used anywhere 2. **Sophia 0.8** - Separate crates (sophia_api, sophia_inmem, sophia_turtle) 3. **wasm-opt Disabled** - Network restrictions accommodated 4. **WASM Tests Skipped** - Browser environment requirement noted @@ -290,7 +290,7 @@ Complete template hierarchy: ### 📐 Technical Patterns -- **Error Handling**: Result types throughout ReScript +- **Error Handling**: Result types throughout - **Accessibility**: ARIA labels, landmarks, live regions - **Security**: Nonces, capability checks, escaping - **Performance**: Code splitting, lazy loading, caching @@ -303,12 +303,12 @@ Complete template hierarchy: ### Code Files (50+) ``` ✅ Rust WASM processor (lib.rs, Cargo.toml, build.sh) -✅ ReScript bindings (SemanticProcessor.res, example.res, bsconfig.json) +✅ bindings (SemanticProcessor.res, example.res, bsconfig.json) ✅ RDF ontologies (4 .ttl files) ✅ WordPress theme (style.css, functions.php, 8 templates, 7 inc files) ✅ CSS architecture (4 files: layout, components, accessibility, print) ✅ JavaScript (navigation.js, graph-viewer.js) -✅ Deno framework (5 config/entry files) +✅ framework (5 config/entry files) ✅ Build system (2 build scripts) ✅ Git configuration (.gitignore) ``` @@ -347,7 +347,7 @@ cp -r wordpress /path/to/wordpress/wp-content/themes/sinople ### 4. **Extend** - Add more constructs to the ontology - Create custom templates for specific post types -- Build Deno + Fresh islands for interactive features +- Build + Fresh islands for interactive features - Integrate with external RDF datasets - Add SPARQL query interface @@ -356,7 +356,7 @@ cp -r wordpress /path/to/wordpress/wp-content/themes/sinople ## 🔬 Testing Recommendations 1. **WASM**: Browser-based integration tests -2. **ReScript**: Type checking via `npx rescript build` +2. ****: Type checking via `npx build` 3. **WordPress**: Theme Check plugin 4. **Accessibility**: axe DevTools, screen reader testing 5. **IndieWeb**: Webmention.io testing @@ -367,7 +367,7 @@ cp -r wordpress /path/to/wordpress/wp-content/themes/sinople ## 🚀 Deployment Checklist - [ ] Build WASM module (`cd wasm/semantic_processor && ./build.sh`) -- [ ] Compile ReScript (`cd rescript && npm run build`) +- [ ] Compile (`cd && npm run build`) - [ ] Copy wordpress/ to WordPress themes directory - [ ] Activate theme in WordPress - [ ] Test construct creation @@ -387,7 +387,7 @@ cp -r wordpress /path/to/wordpress/wp-content/themes/sinople - **Security**: All WordPress security best practices - **Accessibility**: WCAG 2.3 AAA compliant - **Performance**: Optimized WASM, lazy loading -- **Type Safety**: ReScript throughout, no `any` types +- **Type Safety**: throughout, no `any` types - **Documentation**: Comprehensive inline comments ### Standards Compliance @@ -407,14 +407,14 @@ cp -r wordpress /path/to/wordpress/wp-content/themes/sinople This autonomous development session created a **production-ready foundation** for a modern, semantically-aware WordPress theme. The implementation includes: 1. ✅ Full WASM semantic processor in Rust -2. ✅ Type-safe ReScript bindings +2. ✅ Type-safe bindings 3. ✅ Comprehensive RDF ontologies 4. ✅ Complete WordPress theme with custom post types 5. ✅ IndieWeb Level 4 compliance 6. ✅ WCAG 2.3 AAA accessibility 7. ✅ Responsive CSS architecture 8. ✅ Accessible JavaScript features -9. ✅ Deno + Fresh framework integration +9. ✅ + Fresh framework integration 10. ✅ Build system and documentation **Total Value Delivered**: A complete, modern WordPress theme with cutting-edge semantic web capabilities, ready for further development and deployment. diff --git a/sinople-theme/README.adoc b/sinople-theme/README.adoc index b86e15e..a2edbd3 100644 --- a/sinople-theme/README.adoc +++ b/sinople-theme/README.adoc @@ -1,97 +1,269 @@ -= Sinople -:toc: macro -:icons: font +// SPDX-License-Identifier: CC-BY-SA-4.0 +// Copyright (c) Jonathan D.A. Jewell += Sinople WordPress Theme + +image:https://img.shields.io/badge/License-MPL--2.0-blue.svg[License: PMPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] +image:https://img.shields.io/badge/Philosophy-Palimpsest-indigo.svg[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"] + + +A modern, semantically-aware WordPress theme powered by **, **, and *WASM*. Sinople (from the heraldic term for green) combines traditional WordPress theming with cutting-edge semantic web technologies for character relationships, glosses, and knowledge graphs. + +== Current Status + +Sinople is currently best understood as an ambitious integration prototype rather than a finished production platform. + +* The repo contains real WordPress, , and WASM implementation work. +* Several headline claims still outrun the automated test surface and the audit record in link:RSR_AUDIT.md[RSR_AUDIT.md]. +* In particular, Micropub/auth, accessibility verification, and standards-compliance claims should be treated as in-progress unless separately evidenced. + +== Features + +- 🧠 *Semantic Web Processing*: RDF/OWL processing via Rust WASM for construct relationships +- 🌐 *IndieWeb Integration Work*: Webmention and Micropub-related endpoints exist, but the auth/completeness story is still in progress +- ♿ *Accessibility-First Direction*: strong accessibility intent, but full AAA-style verification is still pending +- 🔒 *Type Safety*: -only architecture (NO ) +- ⚡ *Performance*: Rust-powered WASM semantic processor +- 🎨 *Modern Stack*: + Fresh framework for server-side rendering +- 🤖 *Theme Transpilation System* (🚧 WIP): Automatically extract and recreate WordPress themes + - Web scraper with license detection + - Schema-based transformation (Cue/Nix) + - Haskell → transpiler + - ML-powered learning (LSM + Julia + Logtalk) + - See [THEME_TRANSPILATION_ARCHITECTURE.md](THEME_TRANSPILATION_ARCHITECTURE.md) + +== Production-Ready Enhancements + +Sinople includes several enhancements to improve user experience, security, and FOSS philosophy compliance. See [THEME-ENHANCEMENTS.md](THEME-ENHANCEMENTS.md) for detailed documentation. + +=== Visual Identity +- *Professional Screenshot* (1200x900): Sinople green (#006400) with theme branding +- *Multi-Size Favicons*: Complete favicon set for all devices and browsers (16px to 512px) + - Includes: ICO, PNG variants, Apple Touch Icon + - Auto-injected into `` via `wp_head` hook + - Design: Sinople green with white "S" monogram + +=== Clean Default Installation +- *No Bloatware*: Akismet and Hello Dolly automatically removed on theme activation +- *User Freedom Preserved*: Users can still manually install these plugins if needed +- *Automatic Translations*: WordPress translations download immediately on first installation +- *Update Triggers*: Core, plugin, and theme updates checked automatically +- **Implementation**: + - Theme activation hook removes default plugins + - Must-use plugin (`mu-plugins/sinople-no-default-plugins.php`) filters installation-time defaults + - Translation pack downloads on first admin visit + +=== Libravatar Support (FOSS Gravatar Alternative) +- *Service*: Libravatar (https://libravatar.org) - free/open-source avatar service +- *Privacy*: Users can host their own Libravatar instance +- *Fallback*: Gracefully falls back to Gravatar if image not found +- *User Control*: Enable/disable via checkbox in Settings > Discussion +- *Default*: Enabled (aligns with FOSS-first philosophy) + +=== Secure Email by Default +- *Problem Solved*: WordPress defaults to insecure SMTP on port 25 +- *Solution*: Automatic PHPMailer configuration for encrypted connections +- *Default Protocol*: TLS (STARTTLS) on port 587 (recommended) +- *Alternative*: SSL (SMTPS) on port 465 (configurable) +- *User Control*: Encryption type and port customizable in Settings > General +- *Benefits*: + - Prevents email interception and tampering + - Improves deliverability (many ISPs block port 25) + - Protects SMTP authentication credentials +- *Compatibility*: Only applies when SMTP is used; can be disabled via `wp-config.php` + +=== Cryptographic Security Suite (Phase 1) +- *Goal*: Post-quantum ready cryptography where feasible in PHP +- *Based On*: Absolute Max Cryptographic Suite specification +- **Implementation Status**: ✅ Phase 1 complete (native PHP support) +- **What's Included**: + - *Argon2id Password Hashing*: 512 MiB, 8 iterations, 4 lanes (GPU-resistant) + - *XChaCha20-Poly1305*: Authenticated encryption for sensitive options + - *SHAKE256*: File integrity hashing (512-bit output) + - *Ed25519*: Digital signatures for API authentication + - *HKDF-SHAKE256*: Key derivation from master key +- **Configuration**: Set `SINOPLE_MASTER_KEY` in wp-config.php +- **Use Cases**: + - Automatic password hashing upgrade (all users) + - Encrypted API keys and credentials + - File upload integrity verification + - REST API request signing + - Webmention source verification +- **Performance**: Optimized (except Argon2id, which is intentionally slow) +- **Future**: Phase 2-3 will add post-quantum signatures (Dilithium5, SPHINCS+) when PHP/OpenSSL support arrives +- **Documentation**: See [CRYPTOGRAPHIC-INTEGRATION.md](CRYPTOGRAPHIC-INTEGRATION.md) for technical details + +For complete technical details, testing checklists, and implementation notes, see [THEME-ENHANCEMENTS.md](THEME-ENHANCEMENTS.md). + +== Quick Start + +=== Prerequisites + +- WordPress 6.0+ +- PHP 7.4+ +- Rust (for building WASM) +- 1.40+ +- Node.js 18+ (for ) + +=== Installation + +1. *Clone the repository*: + ```bash + git clone https://github.com/Hyperpolymath/wp-sinople-theme.git + cd wp-sinople-theme + ``` + +2. *Build WASM module*: + ```bash + cd wasm/semantic_processor + cargo install wasm-pack + ./build.sh + cd ../.. + ``` + +3. *Compile *: + ```bash + cd + npm install + npm run build + cd .. + ``` + +4. *Set up WordPress*: + ```bash + # Copy wordpress/ directory to your WordPress themes folder + cp -r wordpress /path/to/wordpress/wp-content/themes/sinople + ``` + +5. *Activate theme* in WordPress admin + +=== Development + +```bash += Build everything + +./build.sh + += Development mode (watch files) + +./dev.sh + += Run tests + +cd tests + test integration/ +``` + +== Project Structure + +``` +wp-sinople-theme/ +├── wasm/ # Rust WASM semantic processor +├── / # source code +├── / # + Fresh application +├── wordpress/ # WordPress theme files +├── ontology/ # RDF ontologies (Turtle format) +├── tests/ # Integration tests +└── docs/ # Documentation +``` + +== Custom Post Types + +=== Constructs +Abstract concepts, entities, or ideas (e.g., "Time", "Consciousness", "Justice") + +=== Entanglements +Relationships between constructs (e.g., "Time → Space", "Consciousness → Free Will") + +== IndieWeb Features -[.lead] -A WordPress theme that does more than style your posts. It helps you connect them. +- *Webmention*: `/wp-json/sinople/v1/webmention` +- *Micropub*: `/wp-json/sinople/v1/micropub` (endpoint present; authentication and production posture still need tightening) +- *Microformats2*: All posts include h-entry markup -Sinople is a modern theme for WordPress. It is fast. It is accessible. It respects your privacy. And it has one feature most themes do not: a built-in knowledge graph. You can tag ideas, people, and concepts in your writing, and link them together. Sinople stores those links as data. Your site can then use them, export them, and share them with other sites. +== Semantic Web APIs -It is made for everyone. If you can install a WordPress theme, you can use Sinople. The advanced parts stay out of your way until you want them. +- *Semantic Graph*: `/wp-json/sinople/v1/semantic-graph` +- *RDF Export*: `/wp-json/sinople/v1/constructs/{id}/rdf` +- *Full Ontology*: `/wp-json/sinople/v1/ontology` -toc::[] - -== Why Sinople is different - -Most themes change how your site *looks*. Sinople also changes what your site *knows*. - -*It understands your content.* Link a post about "Time" to one about "Space," and that link becomes real data — not just words on a page. - -*It is built on safe, fast tech.* The heavy work runs in WebAssembly — code that runs quickly and safely — written in Rust. The rest is written in ReScript, a language designed to rule out whole classes of bugs before they happen. - -*It is private by default.* No trackers. No bloat. It even removes the two plugins WordPress ships that you never asked for. (You can add them back. Your site, your choice.) - -*It is secure by default.* Modern password hashing. Encrypted storage for sensitive settings. Signed API requests. All on from the start — not sold as add-ons. - -*It belongs to the open web.* Sinople supports IndieWeb standards, so your site can talk to other sites directly. No platform in the middle. - -== Honest status +== Accessibility -NOTE: Sinople is a working prototype, not a finished product. Some features are complete. Some are partly done. Some are goals. We tell you exactly which is which. Every claim in this file is backed up in link:EXPLAINME.adoc[EXPLAINME — Show Me The Receipts]. +Sinople is designed with strong accessibility goals, but full WCAG AAA-style verification is still pending: -== What you get +- 7:1 contrast ratio for normal text +- Full keyboard navigation support +- Screen reader optimized +- Respects `prefers-reduced-motion` +- Skip links to main content +- Semantic HTML5 markup -*A clean, readable theme.* Good contrast. Keyboard-friendly. Works with screen readers. +== Browser Support -*Knowledge tools.* Two new content types: *Constructs* (ideas and concepts) and *Entanglements* (the links between them). Plus APIs to query and export the graph. +- Chrome/Edge 90+ +- Firefox 88+ +- Safari 14+ -*IndieWeb built in.* Your posts carry machine-readable markup (Microformats2). Webmentions let other sites reply to yours. Micropub support is in progress. +== Contributing -*Private avatars.* Support for Libravatar, the free and open avatar service, instead of sending your readers' data to a third party. +We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for: +- Development guidelines +- Tri-Perimeter Contribution Framework (TPCF) +- Code style and commit conventions +- Pull request process -*Safer email.* WordPress sends mail over an unencrypted connection by default. Sinople switches it to encrypted (TLS) automatically. +Please also review our [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md). -*Strong security defaults.* Argon2id password hashing, authenticated encryption for sensitive options, and digital signatures for API requests. Details in link:CRYPTOGRAPHIC-INTEGRATION.md[CRYPTOGRAPHIC-INTEGRATION]. +== Documentation -== For site owners — no code needed +=== User Documentation +- *[USAGE.md](USAGE.md)*: Developer usage guide +- *[ROADMAP.md](ROADMAP.md)*: Development roadmap +- *[STACK.md](STACK.md)*: Technical stack details +- *[CHANGELOG.md](CHANGELOG.md)*: Version history and release notes -. Download the `wordpress/` folder from this repository. -. Copy it to `wp-content/themes/sinople` on your site. -. Go to *Appearance → Themes* and activate Sinople. +=== Project Governance +- *[CONTRIBUTING.md](CONTRIBUTING.md)*: Contribution guidelines and TPCF +- *[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)*: Community standards +- *[SECURITY.md](SECURITY.md)*: Security policy and vulnerability reporting +- *[MAINTAINERS.md](MAINTAINERS.md)*: Project maintainers and governance +- *[TPCF.md](TPCF.md)*: Tri-Perimeter Contribution Framework details -You need: *WordPress 6.7 or later* and *PHP 8.3 or later* (8.4 recommended). If your host offers older PHP, ask them to upgrade — or move. Old PHP is a security risk. +=== Development +- *[CLAUDE.md](CLAUDE.md)*: AI assistant guidelines and architecture +- *[RSR_AUDIT.md](RSR_AUDIT.md)*: Rhodium Standard Repository compliance audit -== For developers +== Security -[cols="1,1", options="header"] -|=== -| Tool | Version -| WordPress | 6.7+ (tested up to 6.8) -| PHP | 8.3+ (8.4 recommended, CI-tested on 8.5) -| Deno | 2.x -| Node.js | 22 LTS -| Rust | stable, with the `wasm32-unknown-unknown` target -| ReScript | 11.1 -|=== +Security vulnerabilities can be reported via: +- Email: security@sinople.org +- Security policy: [SECURITY.md](SECURITY.md) +- Security.txt: [/.well-known/security.txt](.well-known/security.txt) -[source,bash] ----- -git clone https://github.com/hyperpolymath/wordpress-tools.git -cd wordpress-tools/sinople-theme -./build.sh # build everything -./dev.sh # watch mode ----- +We follow coordinated disclosure practices with 24-hour acknowledgment and 7-day patch timelines. -== Accessibility +== License -We aim for WCAG 2.2 level AA across the theme, and AAA where we can. That means strong contrast, full keyboard access, screen-reader support, and respect for reduced-motion settings. A full independent audit is still to come — current status is in link:EXPLAINME.adoc[the receipts file]. +*Dual Licensed* - Choose either: -== Security +- *Palimpsest-MPL-1.0 License* (OSI-approved, permissive) +- *Palimpsest License v0.8* (political autonomy focus) -Found a vulnerability? Please see link:SECURITY.md[SECURITY.md]. We use coordinated disclosure. +See [LICENSE.txt](LICENSE.txt) for full terms. -== Documentation +*SPDX-License-Identifier*: `MIT OR Palimpsest-0.8` -* link:EXPLAINME.adoc[EXPLAINME — Show Me The Receipts] (claims and evidence) -* link:USAGE.md[Usage guide] -* link:STACK.md[Technical stack] -* link:ROADMAP.adoc[Roadmap] -* link:CONTRIBUTING.adoc[Contributing] -* link:CODE_OF_CONDUCT.md[Code of conduct] +== Standards Compliance -== License +- ⚠️ *RSR*: see link:RSR_AUDIT.md[RSR_AUDIT.md] for the real current audit posture +- ⚠️ *Accessibility*: goals are strong, but full verification is not yet evidenced here +- ⚠️ *IndieWeb*: endpoints and integration work exist, but production-complete Micropub/auth claims are premature +- ✅ *Semantic Versioning 2.0.0*: Version management +- ✅ *Conventional Commits*: Commit message format +- ✅ *RFC 9116*: security.txt implementation -*Code:* Mozilla Public License 2.0 (MPL-2.0). See link:LICENSE[LICENSE]. -*Documentation:* Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA-4.0). +== Credits -SPDX-License-Identifier: CC-BY-SA-4.0 +*Development*: Claude Code (Anthropic) + Human collaboration +*License*: MIT OR Palimpsest-0.8 +*Humans*: See [.well-known/humans.txt](.well-known/humans.txt) +*AI Policy*: See [.well-known/ai.txt](.well-known/ai.txt) diff --git a/sinople-theme/ROADMAP.adoc b/sinople-theme/ROADMAP.adoc index de8c2f1..031ea38 100644 --- a/sinople-theme/ROADMAP.adoc +++ b/sinople-theme/ROADMAP.adoc @@ -6,7 +6,7 @@ This repo is a broad prototype and integration surface, not a finished platform. -* The theme contains real implementation across WordPress, Rust/WASM, and ReScript. +* The theme contains real implementation across WordPress, Rust/WASM, and . * Public-facing claims currently outrun the evidence in `RSR_AUDIT.md` and the small test surface. * The most useful role for this repo right now is to act as the application proving ground for the rest of the stack. @@ -26,7 +26,7 @@ This repo is a broad prototype and integration surface, not a finished platform. == P2 Platform Growth -* [ ] Expand tests across WASM, ReScript, and WordPress integration paths. +* [ ] Expand tests across WASM, , and WordPress integration paths. * [ ] Decide which advanced features are real near-term scope and which belong in design documents only. * [ ] Add one authoritative current-status document and demote stale or aspirational summaries. diff --git a/sinople-theme/RSR_AUDIT.md b/sinople-theme/RSR_AUDIT.md index b9b9371..bdcae06 100644 --- a/sinople-theme/RSR_AUDIT.md +++ b/sinople-theme/RSR_AUDIT.md @@ -10,7 +10,7 @@ Copyright (c) Jonathan D.A. Jewell #### Type Safety (Partial - 50%) - ✅ Rust: Full compile-time type safety in WASM module -- ✅ ReScript: Sound type system with no `any` types +- ✅ : Sound type system with no `any` types - ⚠️ PHP: No static typing (WordPress requirement) - ⚠️ JavaScript: Untyped (vanilla JS for compatibility) @@ -18,7 +18,7 @@ Copyright (c) Jonathan D.A. Jewell - ✅ Rust: Ownership model, zero `unsafe` blocks - ❌ PHP: Manual memory management - ❌ JavaScript: Garbage collected but no safety guarantees -- ❌ ReScript: Compiles to JS (inherits JS memory model) +- ❌ : Compiles to JS (inherits JS memory model) #### Documentation (60%) - ✅ README.md @@ -101,7 +101,7 @@ Copyright (c) Jonathan D.A. Jewell | Category | Score | Status | Notes | |----------|-------|--------|-------| -| 1. Type Safety | 50% | 🟡 Partial | Rust + ReScript only | +| 1. Type Safety | 50% | 🟡 Partial | Rust + only | | 2. Memory Safety | 25% | 🔴 Low | Rust only | | 3. Documentation | 60% | 🟡 Partial | Missing 6 key docs | | 4. Build System | 30% | 🔴 Low | No justfile/Nix | @@ -149,7 +149,7 @@ Bronze Level requires: 70% minimum across all categories ### Phase 6: Testing (2 hours) 1. Add Rust tests for WASM -2. Add ReScript tests +2. Add tests 3. Add integration tests 4. RSR self-verification script @@ -175,7 +175,7 @@ Bronze Level requires: 70% minimum across all categories ### Long-term Considerations - **Offline-First**: Consider static site generation alternative to WordPress -- **Type Safety**: Explore TypeScript or typed PHP alternatives +- **Type Safety**: Explore or typed PHP alternatives - **CRDTs**: Add for distributed state management - **Formal Verification**: Consider Ada + SPARK for critical components diff --git a/sinople-theme/RSR_COMPLETION.md b/sinople-theme/RSR_COMPLETION.md index 7b3f090..1eb553b 100644 --- a/sinople-theme/RSR_COMPLETION.md +++ b/sinople-theme/RSR_COMPLETION.md @@ -49,7 +49,7 @@ Successfully implemented comprehensive Rhodium Standard Repository (RSR) complia **Added**: - ✅ **justfile**: 20+ build automation recipes - - Build: `just build`, `just build-wasm`, `just build-rescript` + - Build: `just build`, `just build-wasm`, `just build-` - Test: `just test`, `just test-integration`, `just test-a11y` - Lint: `just lint`, `just lint-rust`, `just lint-php` - Security: `just security`, `just audit-rust`, `just audit-npm` @@ -58,7 +58,7 @@ Successfully implemented comprehensive Rhodium Standard Repository (RSR) complia - ✅ **flake.nix**: Nix reproducible builds - Development shell with all dependencies - - Build outputs for WASM, ReScript, WordPress theme + - Build outputs for WASM, , WordPress theme - Cross-platform reproducibility - ✅ **.gitlab-ci.yml**: Complete CI/CD pipeline @@ -152,7 +152,7 @@ Successfully implemented comprehensive Rhodium Standard Repository (RSR) complia **Current**: - ✅ Rust for WASM (100% type safe) -- ✅ ReScript for business logic (100% type safe) +- ✅ for business logic (100% type safe) - ⚠️ PHP for WordPress (no static typing) - ⚠️ JavaScript for navigation (no types) @@ -176,7 +176,7 @@ Successfully implemented comprehensive Rhodium Standard Repository (RSR) complia **Added**: - ✅ Test stage in GitLab CI -- ✅ Test jobs for Rust, ReScript, integration +- ✅ Test jobs for Rust, , integration - ✅ `just test` recipes - ⚠️ Actual test implementation still pending @@ -272,8 +272,8 @@ The `justfile` provides 20+ recipes for common tasks: ### Build - `just build` - Build all components - `just build-wasm` - Build Rust WASM module -- `just build-rescript` - Compile ReScript -- `just build-deno` - Bundle Deno application +- `just build-` - Compile +- `just build-` - Bundle application ### Test - `just test` - Run all tests @@ -314,14 +314,14 @@ The `justfile` provides 20+ recipes for common tasks: 2. **Build**: - Rust WASM compilation - - ReScript compilation + - compilation - WordPress theme assembly - Artifact caching 3. **Test**: - Rust unit tests - - ReScript tests - - Integration tests (Deno) + - tests + - Integration tests () 4. **Security**: - Cargo audit (Rust dependencies) @@ -349,13 +349,13 @@ The `flake.nix` provides: ### Development Shell ```bash nix develop -# Includes: Rust, wasm-pack, Node.js, Deno, just, PHP +# Includes: Rust, wasm-pack, Node.js, , just, PHP ``` ### Build Outputs ```bash nix build .#wasm-semantic-processor # Rust WASM -nix build .#rescript # ReScript output +nix build .# # output nix build .#sinople-theme # Complete theme ``` @@ -373,8 +373,8 @@ nix build .#sinople-theme # Complete theme 1. **Testing (40% → 80%)**: - Implement Rust unit tests for WASM module - - Add ReScript component tests - - Create integration test suite (Deno) + - Add component tests + - Create integration test suite () - Add accessibility test automation (axe-core) - Target: 70%+ code coverage @@ -387,7 +387,7 @@ nix build .#sinople-theme # Complete theme 3. **Type Safety (50% → 60%)**: - Add JSDoc types to navigation.js - - Consider TypeScript for graph-viewer.js (if user approves) + - Consider for graph-viewer.js (if user approves) - Add PHPStan for WordPress code **Estimated Time**: 12-16 hours @@ -441,7 +441,7 @@ nix build .#sinople-theme # Complete theme **Commit 1**: Initial CLAUDE.md and project structure **Commit 2**: Comprehensive WordPress theme implementation (50+ files, 5,800+ lines) -**Commit 3**: Complete templates, CSS/JS assets, Deno integration +**Commit 3**: Complete templates, CSS/JS assets, integration **Commit 4**: Project summary and completion report **Commit 5**: **RSR compliance framework (this commit)** (14 files, 3,197+ lines) diff --git a/sinople-theme/RSR_OUTLINE.adoc b/sinople-theme/RSR_OUTLINE.adoc index 0ad555a..036001f 100644 --- a/sinople-theme/RSR_OUTLINE.adoc +++ b/sinople-theme/RSR_OUTLINE.adoc @@ -148,7 +148,7 @@ project/ === Language Tiers -* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, ReScript +* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, * **Tier 2** (Silver): Nickel, Racket, Guile Scheme, Nix * **Infrastructure**: Guix channels, derivations @@ -168,7 +168,7 @@ project/ === Prohibited * Python outside `salt/` directory -* TypeScript/JavaScript (use ReScript) +* /JavaScript (use ) * CUE (use Guile/Nickel) * `Dockerfile` (use `Containerfile`) diff --git a/sinople-theme/SECURITY.md b/sinople-theme/SECURITY.md index 8a1c163..a61f009 100644 --- a/sinople-theme/SECURITY.md +++ b/sinople-theme/SECURITY.md @@ -16,7 +16,7 @@ Copyright (c) Jonathan D.A. Jewell The Sinople WordPress theme follows a **defense-in-depth** approach with multiple security layers: 1. **Memory Safety**: Rust WASM module (zero `unsafe` blocks) -2. **Type Safety**: ReScript bindings (sound type system) +2. **Type Safety**: bindings (sound type system) 3. **Input Sanitization**: All WordPress inputs sanitized 4. **Output Escaping**: All outputs escaped (XSS prevention) 5. **CSRF Protection**: Nonces for all form submissions @@ -45,7 +45,7 @@ Use PGP encryption for sensitive disclosures (key available at `.well-known/secu Please provide: 1. **Type of vulnerability** (XSS, CSRF, injection, etc.) -2. **Affected component** (WASM, PHP, ReScript, JavaScript, etc.) +2. **Affected component** (WASM, PHP, , JavaScript, etc.) 3. **Affected versions** (1.0.0, 1.0.1, etc.) 4. **Steps to reproduce** (detailed, with code samples if possible) 5. **Proof of concept** (if applicable, responsibly disclosed) diff --git a/sinople-theme/STACK.md b/sinople-theme/STACK.md index 97f1f70..3f7a76f 100644 --- a/sinople-theme/STACK.md +++ b/sinople-theme/STACK.md @@ -6,13 +6,13 @@ Copyright (c) Jonathan D.A. Jewell ## Frontend -### ReScript 11+ -- **Why**: Type safety without TypeScript overhead +### 11+ +- **Why**: Type safety without overhead - **Use**: UI components, WASM bindings, domain logic - **Compiles to**: ES6 JavaScript -### Deno 1.40+ with Fresh -- **Why**: Modern runtime, no build step, native TypeScript +### 1.40+ with Fresh +- **Why**: Modern runtime, no build step, native - **Use**: Server-side rendering, API routes, islands architecture - **Security**: Permissions-based, secure by default @@ -69,15 +69,15 @@ Copyright (c) Jonathan D.A. Jewell ### wasm-pack - **Why**: Rust → WASM compilation -- **Output**: ES modules + TypeScript definitions +- **Output**: ES modules + definitions -### ReScript Compiler -- **Why**: ReScript → JavaScript +### Compiler +- **Why**: → JavaScript - **Output**: Clean, readable ES6 ## Testing -### Deno Test +### Test - **Use**: Integration tests, API tests - **Features**: Built-in assertions, async support @@ -92,8 +92,8 @@ Copyright (c) Jonathan D.A. Jewell - **Commits**: Conventional commits format ### Hot Reload -- ReScript watch mode -- Deno --watch flag +- watch mode +- --watch flag - WordPress auto-refresh ## Deployment @@ -118,5 +118,5 @@ Copyright (c) Jonathan D.A. Jewell - Rust: Memory safety guarantees - WordPress: Security best practices -- Deno: Permissions-based sandbox +- : Permissions-based sandbox - HTTPS: Required for WASM/Service Workers diff --git a/sinople-theme/THEME-ENHANCEMENTS.md b/sinople-theme/THEME-ENHANCEMENTS.md index c19a6fc..c945fcc 100644 --- a/sinople-theme/THEME-ENHANCEMENTS.md +++ b/sinople-theme/THEME-ENHANCEMENTS.md @@ -14,7 +14,7 @@ Recent enhancements to make Sinople a production-ready, user-friendly WordPress ### 1. Theme Screenshot (1200x900px) - **Design:** Sinople green (#006400) background with theme name and feature highlights -- **Text:** "Sinople Theme" with taglines "Semantic Web • IndieWeb • WCAG AAA" and "ReScript • Deno • WASM" +- **Text:** "Sinople Theme" with taglines "Semantic Web • IndieWeb • WCAG AAA" and " • • WASM" - **Purpose:** Professional appearance in WordPress admin Themes page - **Location:** `wordpress/screenshot.png` - **Commit:** `dbd8607` diff --git a/sinople-theme/THEME_TRANSPILATION_ARCHITECTURE.md b/sinople-theme/THEME_TRANSPILATION_ARCHITECTURE.md index a292cb5..743896a 100644 --- a/sinople-theme/THEME_TRANSPILATION_ARCHITECTURE.md +++ b/sinople-theme/THEME_TRANSPILATION_ARCHITECTURE.md @@ -17,7 +17,7 @@ Build a **self-learning theme generation system** that can: 1. **Analyze** any WordPress theme (or website) and extract its design patterns 2. **Validate** licensing to ensure legal compliance 3. **Transform** the design using schema-based transpilation -4. **Generate** ReScript/WASM-powered themes with Sinople's semantic features +4. **Generate** /WASM-powered themes with Sinople's semantic features 5. **Learn** from user feedback to improve extraction/generation over time ### Ultimate Goal @@ -35,7 +35,7 @@ Enable users to: ``` ┌─────────────────────────────────────────────────────────────────┐ │ Web Scraper + Analyzer │ -│ (Deno-based, respects robots.txt, checks licensing) │ +│ (-based, respects robots.txt, checks licensing) │ └────────────────┬────────────────────────────────────────────────┘ │ ├─► License Detection (security.txt, LICENSE, meta) @@ -51,13 +51,13 @@ Enable users to: │ ▼ ┌─────────────────────────────────────────────────────────────────┐ -│ Haskell Transpiler (Schema → ReScript) │ +│ Haskell Transpiler (Schema → ) │ │ (Type-safe transformation with validation) │ └────────────────┬────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ -│ ReScript Theme Generator + WASM Integration │ +│ Theme Generator + WASM Integration │ │ (Produces Sinople-compatible theme with semantic features) │ └────────────────┬────────────────────────────────────────────────┘ │ @@ -79,15 +79,15 @@ Enable users to: ## Component 1: Web Scraper + Analyzer ### Technology Stack -- **Deno**: HTTP client with fetch API -- **TypeScript/ReScript**: Type-safe scraping logic -- **Deno DOM**: HTML parsing (https://deno.land/x/deno_dom) +- ****: HTTP client with fetch API +- **/**: Type-safe scraping logic +- ** DOM**: HTML parsing (https:///x/deno_dom) - **CSS Parser**: PostCSS or similar ### Responsibilities #### 1.1 License Detection -```typescript +``` // Checks multiple sources for license information interface LicenseInfo { detected: boolean; @@ -124,7 +124,7 @@ async function detectLicense(url: string): Promise { #### 1.2 DOM Structure Extraction -```typescript +``` interface DOMStructure { hierarchy: { header: ElementNode; @@ -150,7 +150,7 @@ interface ElementNode { #### 1.3 CSS Analysis -```typescript +``` interface DesignTokens { colors: { primary: string[]; @@ -190,7 +190,7 @@ async function extractDesignTokens(cssText: string): Promise #### 1.4 Asset Catalog -```typescript +``` interface AssetCatalog { images: Array<{ url: string; @@ -373,7 +373,7 @@ module Transpiler.Main where import qualified Data.Aeson as JSON import qualified Data.Text as T import qualified Transpiler.Schema as Schema -import qualified Transpiler.ReScript as ReScript +import qualified Transpiler. as import qualified Transpiler.WordPress as WordPress -- Main pipeline @@ -385,8 +385,8 @@ transpileTheme schemaPath = do -- 2. Validate schema validated <- Schema.validate schema - -- 3. Generate ReScript components - rescriptComponents <- ReScript.generateComponents validated + -- 3. Generate components + Components <- .generateComponents validated -- 4. Generate WordPress PHP templates wpTemplates <- WordPress.generateTemplates validated @@ -396,21 +396,21 @@ transpileTheme schemaPath = do -- 6. Combine into theme package pure $ ThemeOutput { - rescript = rescriptComponents, + = Components, wordpress = wpTemplates, css = css, metadata = Schema.metadata validated } --- Example: Convert design tokens to ReScript +-- Example: Convert design tokens to data DesignTokens = DesignTokens { colors :: ColorPalette, typography :: Typography, spacing :: SpacingScale } -generateReScriptModule :: DesignTokens -> T.Text -generateReScriptModule tokens = +generateModule :: DesignTokens -> T.Text +generateModule tokens = T.unlines [ "// Auto-generated from theme schema", "module DesignTokens = {", @@ -464,13 +464,13 @@ data License = MIT | GPL2 | GPL3 | Apache2 | CCBY4 deriving (Show, Eq, Generic, FromJSON, ToJSON) ``` -### ReScript Code Generation +### Code Generation ```haskell --- src/Transpiler/ReScript.hs -module Transpiler.ReScript where +-- src/Transpiler/.hs +module Transpiler. where -generateComponents :: ThemeSchema -> IO [ReScriptModule] +generateComponents :: ThemeSchema -> IO [Module] generateComponents schema = do let tokens = designTokens schema struct = structure schema @@ -482,14 +482,14 @@ generateComponents schema = do generateTemplatesModule (templates schema) ] -data ReScriptModule = ReScriptModule { +data Module = Module { moduleName :: Text, moduleContent :: Text, filePath :: FilePath } -generateDesignTokensModule :: DesignTokens -> ReScriptModule -generateDesignTokensModule tokens = ReScriptModule { +generateDesignTokensModule :: DesignTokens -> Module +generateDesignTokensModule tokens = Module { moduleName = "DesignTokens", moduleContent = renderTemplate tokensTemplate tokens, filePath = "src/generated/DesignTokens.res" @@ -502,8 +502,8 @@ generateDesignTokensModule tokens = ReScriptModule { ### CSS Parser -```typescript -// deno/lib/css-parser.ts +``` +// /lib/css-parser.ts import { parse } from "https://esm.sh/postcss@8.4.31"; interface CSSRule { @@ -585,9 +585,9 @@ export function detectDesignSystem(rules: CSSRule[]): DesignTokens { ### DOM Structure Analyzer -```typescript -// deno/lib/dom-analyzer.ts -import { DOMParser } from "https://deno.land/x/deno_dom/deno-dom-wasm.ts"; +``` +// /lib/dom-analyzer.ts +import { DOMParser } from "https:///x/deno_dom/-dom-wasm.ts"; export async function analyzeDOMStructure(html: string): Promise { const doc = new DOMParser().parseFromString(html, "text/html"); @@ -632,8 +632,8 @@ function extractElement(el: Element | null): ElementNode | null { #### 5.1 JSON Feedback API -```typescript -// deno/routes/api/feedback/theme.ts +``` +// /routes/api/feedback/theme.ts export const handler: Handlers = { async POST(req, ctx) { const feedback: ThemeFeedback = await req.json(); @@ -641,7 +641,7 @@ export const handler: Handlers = { // Validate feedback schema const validated = await validateFeedback(feedback); - // Store in database (Deno KV or PostgreSQL) + // Store in database ( KV or PostgreSQL) await storeFeedback(validated); // Enqueue for ML training @@ -730,8 +730,8 @@ timestamp: "2025-11-23T10:30:00Z" #### 5.3 Web UI Feedback Form -```typescript -// deno/islands/FeedbackForm.tsx +``` +// /islands/FeedbackForm.tsx import { useState } from "preact/hooks"; export default function ThemeFeedbackForm({ themeId }: { themeId: string }) { @@ -957,7 +957,7 @@ end #### 6.3 Julia AI Supervised Learning -**Use Case**: Train model to predict optimal ReScript code from schema. +**Use Case**: Train model to predict optimal code from schema. ```julia # ml/julia/theme_generator.jl @@ -978,7 +978,7 @@ function create_theme_generator() Dense(128, 64, tanh) ) - # Decoder: Latent representation -> ReScript code (token sequence) + # Decoder: Latent representation -> code (token sequence) decoder = Chain( LSTM(64, 128), LSTM(128, 256), @@ -999,11 +999,11 @@ function train_generator!(model::ThemeGeneratorModel, training_data::Vector{Them schema_vector = schema_to_vector(example.schema) latent = model.encoder(schema_vector) - # Decode to ReScript token sequence + # Decode to token sequence predicted_tokens = model.decoder(latent) - # Compare with actual ReScript code - target_tokens = tokenize_rescript(example.rescript_code) + # Compare with actual code + target_tokens = tokenize_(example._code) loss = crossentropy(predicted_tokens, target_tokens) # Backpropagation @@ -1016,32 +1016,32 @@ function train_generator!(model::ThemeGeneratorModel, training_data::Vector{Them end end -function generate_rescript(model::ThemeGeneratorModel, schema::ThemeSchema)::String +function generate_(model::ThemeGeneratorModel, schema::ThemeSchema)::String schema_vector = schema_to_vector(schema) latent = model.encoder(schema_vector) token_sequence = model.decoder(latent) - # Decode tokens back to ReScript source code - detokenize_rescript(token_sequence) + # Decode tokens back to source code + detokenize_(token_sequence) end struct ThemeTrainingExample schema::ThemeSchema - rescript_code::String + _code::String user_rating::Float64 # From feedback system end ``` #### 6.4 Training Data Pipeline -```typescript +``` // ml/pipeline/training-data-collector.ts -import { Database } from "https://deno.land/x/denodb/mod.ts"; +import { Database } from "https:///x/denodb/mod.ts"; interface TrainingDataPoint { id: string; schema: ThemeSchema; - generatedReScript: string; + generated: string; userFeedback: ThemeFeedback; rating: number; // Derived from feedback timestamp: string; @@ -1055,7 +1055,7 @@ export async function collectTrainingData(): Promise { SELECT e.id, e.schema, - e.generated_rescript, + e.generated_, f.extraction_quality, f.correctness, f.improvements @@ -1067,7 +1067,7 @@ export async function collectTrainingData(): Promise { return data.map(row => ({ id: row.id, schema: JSON.parse(row.schema), - generatedReScript: row.generated_rescript, + generated: row.generated_, userFeedback: row, rating: calculateRating(row), timestamp: row.created_at, @@ -1096,18 +1096,18 @@ export async function exportForMLTraining(outputDir: string) { const data = await collectTrainingData(); // Export as JSON for Julia - await Deno.writeTextFile( + await .writeTextFile( `${outputDir}/training-data.json`, JSON.stringify(data, null, 2) ); // Export as CSV for easy loading const csv = convertToCSV(data); - await Deno.writeTextFile(`${outputDir}/training-data.csv`, csv); + await .writeTextFile(`${outputDir}/training-data.csv`, csv); // Export Logtalk facts const logTalkFacts = convertToLogTalkFacts(data); - await Deno.writeTextFile(`${outputDir}/training-facts.lgt`, logTalkFacts); + await .writeTextFile(`${outputDir}/training-facts.lgt`, logTalkFacts); } ``` @@ -1117,7 +1117,7 @@ export async function exportForMLTraining(outputDir: string) { ### Official WordPress Themes (2003-Present) -```typescript +``` // data/wordpress-themes-catalog.ts export const WORDPRESS_OFFICIAL_THEMES = [ // 2003-2010: The early years @@ -1156,7 +1156,7 @@ export async function downloadOfficialTheme(slug: string): Promise { ### IndieWeb Themes -```typescript +``` // data/indieweb-themes-catalog.ts export const INDIEWEB_THEMES = [ { @@ -1208,13 +1208,13 @@ export const INDIEWEB_THEMES = [ ### Phase 1: Foundation (Weeks 1-2) ✅ Started - [x] Create architecture document (this file) -- [ ] Set up Deno web scraper with license detection +- [ ] Set up web scraper with license detection - [ ] Implement basic CSS/DOM extraction - [ ] Create Cue schema definitions ### Phase 2: Transpiler (Weeks 3-4) - [ ] Build Haskell transpiler skeleton -- [ ] Implement schema → ReScript transformation +- [ ] Implement schema → transformation - [ ] Implement schema → WordPress PHP transformation - [ ] Add CSS generation from design tokens @@ -1257,7 +1257,7 @@ export const INDIEWEB_THEMES = [ ```bash # Using CLI tool -deno run --allow-net --allow-write \ + run --allow-net --allow-write \ ./cli/extract-theme.ts \ --url https://wordpress.org/themes/twentytwentyfour/ \ --output ./extracted/twentytwentyfour.cue @@ -1270,7 +1270,7 @@ deno run --allow-net --allow-write \ # ✓ Generated Cue schema: ./extracted/twentytwentyfour.cue ``` -### Example 2: Transpile Schema to ReScript +### Example 2: Transpile Schema to ```bash # Using Haskell transpiler @@ -1280,7 +1280,7 @@ cabal run transpiler -- \ # Output: # ✓ Validated schema -# ✓ Generated ReScript modules (8 files) +# ✓ Generated modules (8 files) # ✓ Generated WordPress templates (12 files) # ✓ Generated CSS (3,420 lines) # ✓ Theme package: ./generated/twentytwentyfour/ @@ -1316,7 +1316,7 @@ curl -X POST https://sinople.org/api/feedback/theme \ ```bash # Collect training data -deno run --allow-net --allow-write \ + run --allow-net --allow-write \ ./ml/pipeline/collect-training-data.ts \ --output ./ml/data/training-2025-11-23.json @@ -1341,7 +1341,7 @@ julia --project=. train.jl --data ../data/training-2025-11-23.json - Project vision and roadmap ### In Progress 🚧 -- Deno web scraper skeleton +- web scraper skeleton - Cue schema definitions - Basic license detection @@ -1361,7 +1361,7 @@ This is an experimental system under active development. Contributions welcome i 1. **Scraper Improvements**: Better CSS/DOM extraction algorithms 2. **Schema Refinements**: Enhanced Cue/Nix schema definitions -3. **Transpiler Features**: New ReScript code generation patterns +3. **Transpiler Features**: New code generation patterns 4. **ML Models**: Alternative approaches (transformers, GANs, etc.) 5. **Theme Catalog**: Adding more themes to the database 6. **Feedback UI**: Improving user feedback collection @@ -1384,7 +1384,7 @@ This component of the Sinople WordPress Theme is dual-licensed: ## References ### Web Scraping -- [Deno DOM](https://deno.land/x/deno_dom) +- [ DOM](https:///x/deno_dom) - [PostCSS](https://postcss.org/) - [SPDX License List](https://spdx.org/licenses/) diff --git a/sinople-theme/USAGE.md b/sinople-theme/USAGE.md index 28196db..116cf03 100644 --- a/sinople-theme/USAGE.md +++ b/sinople-theme/USAGE.md @@ -75,7 +75,7 @@ https://yoursite.com/wp-json/sinople/v1/micropub ## Development Workflow -1. Edit ReScript files in `rescript/src/` +1. Edit files in `/src/` 2. Run `npm run watch` to compile 3. Edit Rust in `wasm/semantic_processor/src/` 4. Run `./build.sh` to recompile WASM diff --git a/sinople-theme/build.sh b/sinople-theme/build.sh index 047dda7..6abfa1d 100755 --- a/sinople-theme/build.sh +++ b/sinople-theme/build.sh @@ -2,7 +2,7 @@ # # Master Build Script for Sinople Theme # -# Builds all components: WASM, ReScript, Deno, and assembles WordPress theme +# Builds all components: WASM, , Deno, and assembles WordPress theme # set -e # Exit on error @@ -36,25 +36,25 @@ else echo -e "${RED}⚠️ WASM directory not found, skipping${NC}" fi -# Step 2: Compile ReScript -echo -e "${BLUE}🔧 Step 2: Compiling ReScript...${NC}" -if [ -d "rescript" ]; then - cd rescript +# Step 2: Compile +echo -e "${BLUE}🔧 Step 2: Compiling ...${NC}" +if [ -d "" ]; then + cd # Install dependencies if needed if [ ! -d "node_modules" ]; then - echo "Installing ReScript dependencies..." + echo "Installing dependencies..." npm install fi - # Compile ReScript - npx rescript clean - npx rescript build + # Compile + npx clean + npx build - echo -e "${GREEN}✅ ReScript compilation complete${NC}" + echo -e "${GREEN}✅ compilation complete${NC}" cd .. else - echo -e "${RED}⚠️ ReScript directory not found, skipping${NC}" + echo -e "${RED}⚠️ directory not found, skipping${NC}" fi # Step 3: Bundle Deno application (if applicable) @@ -91,15 +91,15 @@ if [ -d "wasm/semantic_processor/pkg" ]; then cp wasm/semantic_processor/pkg/*.{js,wasm} wordpress/assets/wasm/ 2>/dev/null || true fi -# Copy ReScript compiled files -if [ -d "rescript/src" ]; then - echo "Copying ReScript compiled files..." - find rescript/src -name "*.res.js" -exec cp {} wordpress/assets/js/ \; 2>/dev/null || true +# Copy compiled files +if [ -d "/src" ]; then + echo "Copying compiled files..." + find /src -name "*.res.js" -exec cp {} wordpress/assets/js/ \; 2>/dev/null || true fi # Copy build outputs -if [ -d "build/rescript" ]; then - cp -r build/rescript/* wordpress/assets/js/ 2>/dev/null || true +if [ -d "build/" ]; then + cp -r build//* wordpress/assets/js/ 2>/dev/null || true fi if [ -d "build/deno" ]; then diff --git a/sinople-theme/cli/extract-theme.js b/sinople-theme/cli/extract-theme.js index 77b1682..7c943ba 100644 --- a/sinople-theme/cli/extract-theme.js +++ b/sinople-theme/cli/extract-theme.js @@ -100,7 +100,7 @@ async function main() { console.log("\n🚀 Next steps:"); console.log(" 1. Review the extracted schema"); console.log(" 2. Run transpiler: cabal run transpiler -- --schema " + args.output); - console.log(" 3. Generate ReScript theme components"); + console.log(" 3. Generate theme components"); console.log(" 4. Provide feedback to improve extraction\n"); } catch (error) { console.error(`\n❌ Error: ${error.message}\n`); diff --git a/sinople-theme/deno/README.md b/sinople-theme/deno/README.md deleted file mode 100644 index e91e49f..0000000 --- a/sinople-theme/deno/README.md +++ /dev/null @@ -1,54 +0,0 @@ - -# Sinople Deno + Fresh Integration - -This directory contains the Deno + Fresh framework integration for Sinople theme. - -## Setup - -1. Install Deno: - ```bash - curl -fsSL https://deno.land/install.sh | sh - ``` - -2. Run development server: - ```bash - deno task dev - ``` - -3. Build for production: - ```bash - deno task build - ``` - -## Structure - -- `main.ts` - Production entry point -- `dev.ts` - Development server -- `routes/` - Fresh file-based routing -- `islands/` - Interactive islands (client-side) -- `components/` - Server-side components -- `lib/` - Utility functions - -## API Routes - -- `/api/webmention` - Webmention endpoint -- `/api/micropub` - Micropub endpoint -- `/api/semantic` - Semantic graph queries -- `/api/void` - VoID dataset description - -## Fresh Islands - -Islands are interactive components that hydrate on the client: - -- `SemanticGraph.tsx` - RDF graph visualization -- `GlossAnnotation.tsx` - Inline gloss annotations -- `CharacterNetwork.tsx` - Character relationship viewer -- `SearchFilter.tsx` - Accessible search/filter - -## Integration with WordPress - -The Fresh application proxies requests to WordPress REST API -and enhances with client-side interactivity where needed. diff --git a/sinople-theme/deno/build.js b/sinople-theme/deno/build.js deleted file mode 100644 index 5afa00e..0000000 --- a/sinople-theme/deno/build.js +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Sinople Deno Build Script - * - * Bundles the Deno/Fresh application for production deployment. - * Creates optimized bundles in the build/deno/ directory. - * - * Usage: deno task build - */ - -import { ensureDir, copy, walk } from 'https://deno.land/std@0.208.0/fs/mod.ts'; -import { join, basename } from 'https://deno.land/std@0.208.0/path/mod.ts'; - -const ROOT = new URL('..', import.meta.url).pathname; -const DENO_DIR = new URL('.', import.meta.url).pathname; -const BUILD_DIR = join(ROOT, 'build', 'deno'); - -const config = { - entryPoints: [ - join(DENO_DIR, 'main.js'), - ], - outDir: BUILD_DIR, - minify: true, -}; - -async function clean() { - console.log('🧹 Cleaning build directory...'); - try { - await Deno.remove(BUILD_DIR, { recursive: true }); - } catch { - // Directory doesn't exist, that's fine - } - await ensureDir(BUILD_DIR); -} - -async function copyStaticAssets() { - console.log('📋 Copying static assets...'); - - // Copy lib/ directory if it exists - const libDir = join(DENO_DIR, 'lib'); - try { - const libInfo = await Deno.stat(libDir); - if (libInfo.isDirectory) { - await copy(libDir, join(BUILD_DIR, 'lib'), { overwrite: true }); - } - } catch { - // lib/ doesn't exist, skip - } -} - -async function bundleJavaScript() { - console.log('📦 Bundling JavaScript files...'); - - for (const entryPoint of config.entryPoints) { - const fileName = basename(entryPoint, '.js') + '.bundle.js'; - const outFile = join(config.outDir, fileName); - - console.log(` Bundling ${basename(entryPoint)}...`); - - const result = await Deno.emit(entryPoint, { - bundle: 'module', - compilerOptions: { - lib: ['dom', 'dom.iterable', 'esnext', 'deno.ns'], - jsx: 'react-jsx', - jsxImportSource: 'preact', - }, - }).catch(() => null); - - if (result) { - // Write the bundled output - const bundled = result.files['deno:///bundle.js'] || ''; - await Deno.writeTextFile(outFile, bundled); - console.log(` ✅ Created ${fileName}`); - } else { - // Fallback: just copy the file - console.log(` ⚠️ Bundle failed, copying source...`); - await Deno.copyFile(entryPoint, join(config.outDir, basename(entryPoint))); - } - } -} - -async function generateManifest() { - console.log('📝 Generating build manifest...'); - - const manifest = { - version: '1.0.0', - buildTime: new Date().toISOString(), - files: [], - }; - - for await (const entry of walk(BUILD_DIR)) { - if (entry.isFile) { - manifest.files.push(entry.path.replace(BUILD_DIR, '')); - } - } - - await Deno.writeTextFile( - join(BUILD_DIR, 'manifest.json'), - JSON.stringify(manifest, null, 2) - ); -} - -async function build() { - console.log('🚀 Building Sinople Deno Application'); - console.log('=====================================\n'); - - const start = performance.now(); - - try { - await clean(); - await copyStaticAssets(); - await bundleJavaScript(); - await generateManifest(); - - const elapsed = ((performance.now() - start) / 1000).toFixed(2); - console.log(`\n✅ Build complete in ${elapsed}s`); - console.log(`📁 Output: ${BUILD_DIR}`); - - // List output files - console.log('\nBuild artifacts:'); - for await (const entry of walk(BUILD_DIR, { maxDepth: 2 })) { - if (entry.isFile) { - const stat = await Deno.stat(entry.path); - const size = (stat.size / 1024).toFixed(1); - console.log(` ${entry.path.replace(BUILD_DIR, '.')} (${size}KB)`); - } - } - } catch (error) { - console.error('\n❌ Build failed:', error); - Deno.exit(1); - } -} - -// Run build -await build(); diff --git a/sinople-theme/deno/deno.json b/sinople-theme/deno/deno.json deleted file mode 100644 index 094f503..0000000 --- a/sinople-theme/deno/deno.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "tasks": { - "start": "deno run --allow-net --allow-read --allow-env --watch main.ts", - "build": "deno run --allow-net --allow-read --allow-write --allow-env build.ts", - "dev": "deno run --allow-net --allow-read --allow-env --watch dev.ts" - }, - "imports": { - "$fresh/": "https://deno.land/x/fresh@1.6.0/", - "preact": "https://esm.sh/preact@10.19.2", - "preact/": "https://esm.sh/preact@10.19.2/", - "preact-render-to-string": "https://esm.sh/preact-render-to-string@6.3.1", - "@preact/signals": "https://esm.sh/@preact/signals@1.2.1", - "@preact/signals-core": "https://esm.sh/@preact/signals-core@1.5.0" - }, - "compilerOptions": { - "jsx": "react-jsx", - "jsxImportSource": "preact", - "lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns", "deno.unstable"] - }, - "lint": { - "rules": { - "tags": ["recommended"] - } - }, - "fmt": { - "useTabs": false, - "lineWidth": 100, - "indentWidth": 2, - "semiColons": true, - "singleQuote": true, - "proseWrap": "preserve" - } -} diff --git a/sinople-theme/deno/dev.js b/sinople-theme/deno/dev.js deleted file mode 100644 index ba59490..0000000 --- a/sinople-theme/deno/dev.js +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Development Server for Sinople Deno + Fresh - */ - -import dev from "$fresh/dev.ts"; -import config from "./fresh.config.js"; - -await dev(import.meta.url, "./main.js", config); diff --git a/sinople-theme/deno/fresh.config.js b/sinople-theme/deno/fresh.config.js deleted file mode 100644 index 3301702..0000000 --- a/sinople-theme/deno/fresh.config.js +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -/** - * Fresh Framework Configuration - */ - -import { defineConfig } from "$fresh/server.ts"; - -export default defineConfig({ - // Fresh configuration options -}); diff --git a/sinople-theme/deno/fresh.gen.js b/sinople-theme/deno/fresh.gen.js deleted file mode 100644 index 795094a..0000000 --- a/sinople-theme/deno/fresh.gen.js +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// DO NOT EDIT. This file is generated by Fresh. -// This file SHOULD be checked into source version control. -// This file is automatically updated during development when running `dev.js`. - -import config from './fresh.config.js'; - -// NOTE: Routes and Islands are not yet implemented. -// When implementing, add routes in deno/routes/ and islands in deno/islands/ -// and regenerate this file with `deno run --allow-read --allow-write --allow-net https://deno.land/x/fresh/init.ts .` - -const manifest = { - routes: { - // Add routes here when implemented: - // './routes/index.tsx': () => import('./routes/index.tsx'), - // './routes/api/webmention.ts': () => import('./routes/api/webmention.ts'), - }, - islands: { - // Add islands here when implemented: - // './islands/SemanticGraph.tsx': () => import('./islands/SemanticGraph.tsx'), - }, - baseUrl: import.meta.url, - config, -}; - -export default manifest; diff --git a/sinople-theme/deno/lib/license-detector/mod.js b/sinople-theme/deno/lib/license-detector/mod.js deleted file mode 100644 index 7d56d88..0000000 --- a/sinople-theme/deno/lib/license-detector/mod.js +++ /dev/null @@ -1,317 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// License Detection Module -// Detects licenses from multiple sources: security.txt, LICENSE files, meta tags, WordPress headers - -// SPDX license patterns -const LICENSE_PATTERNS = { - "MIT": [ - /MIT License/i, - /Permission is hereby granted, free of charge/i, - /SPDX-License-Identifier:\s*MIT/i, - ], - "GPL-2.0-or-later": [ - /GNU General Public License.*version 2/i, - /GPL-2\.0/i, - /SPDX-License-Identifier:\s*GPL-2\.0/i, - ], - "GPL-3.0-or-later": [ - /GNU General Public License.*version 3/i, - /GPL-3\.0/i, - /SPDX-License-Identifier:\s*GPL-3\.0/i, - ], - "Apache-2.0": [ - /Apache License.*Version 2\.0/i, - /SPDX-License-Identifier:\s*Apache-2\.0/i, - ], - "CC-BY-4.0": [ - /Creative Commons Attribution 4\.0/i, - /CC BY 4\.0/i, - ], - "CC-BY-SA-4.0": [ - /Creative Commons Attribution-ShareAlike 4\.0/i, - /CC BY-SA 4\.0/i, - ], - "CC0-1.0": [ - /Creative Commons.*Public Domain/i, - /CC0 1\.0 Universal/i, - ], - "Unlicense": [ - /This is free and unencumbered software released into the public domain/i, - ], -}; - -// Licenses compatible with MIT OR Palimpsest-0.8 -const COMPATIBLE_LICENSES = new Set([ - "MIT", - "Apache-2.0", - "GPL-2.0-or-later", - "GPL-3.0-or-later", - "CC-BY-4.0", - "CC-BY-SA-4.0", - "CC0-1.0", - "Unlicense", - "BSD-2-Clause", - "BSD-3-Clause", -]); - -// Incompatible licenses (non-commercial, proprietary, etc.) -const INCOMPATIBLE_LICENSES = new Set([ - "CC-BY-NC-4.0", // Non-commercial - "CC-BY-ND-4.0", // No derivatives - "Proprietary", - "All Rights Reserved", -]); - -/** - * Detect license from a URL by checking multiple sources - */ -export async function detectLicense(url) { - const sources = []; - - // 1. Check /.well-known/security.txt (RFC 9116) - try { - const securityTxt = await fetchSecurityTxt(url); - if (securityTxt) { - sources.push({ - location: "/.well-known/security.txt", - content: securityTxt, - }); - } - } catch { - // security.txt not found or error - } - - // 2. Check common LICENSE file locations - const licenseFiles = [ - "/LICENSE", - "/LICENSE.txt", - "/LICENSE.md", - "/license.txt", - "/COPYING", - ]; - - for (const path of licenseFiles) { - try { - const content = await fetchText(new URL(path, url).toString()); - if (content) { - sources.push({ - location: path, - content, - }); - } - } catch { - // File not found - } - } - - // 3. Check HTML page for meta tags and WordPress headers - try { - const html = await fetchText(url); - if (html) { - // Check meta tags - const metaLicense = extractMetaLicense(html); - if (metaLicense) { - sources.push({ - location: "HTML meta tag", - content: metaLicense, - }); - } - - // Check WordPress theme header (in style.css) - const wpHeader = extractWordPressHeader(html); - if (wpHeader) { - sources.push({ - location: "WordPress theme header", - content: wpHeader, - }); - } - } - } catch { - // HTML fetch failed - } - - // 4. For WordPress themes, check style.css directly - try { - const styleCss = await fetchText(new URL("/style.css", url).toString()); - if (styleCss) { - const wpLicense = extractWordPressLicense(styleCss); - if (wpLicense) { - sources.push({ - location: "style.css theme header", - content: wpLicense, - }); - } - } - } catch { - // style.css not found - } - - // Analyze all sources and determine license - return analyzeSources(sources); -} - -/** - * Fetch /.well-known/security.txt - */ -async function fetchSecurityTxt(url) { - const securityUrl = new URL("/.well-known/security.txt", url).toString(); - return await fetchText(securityUrl); -} - -/** - * Fetch text content from URL - */ -async function fetchText(url) { - try { - const response = await fetch(url, { - headers: { - "User-Agent": "Sinople-Theme-Extractor/1.0 (+https://github.com/Hyperpolymath/wp-sinople-theme)", - }, - }); - - if (!response.ok) { - return null; - } - - return await response.text(); - } catch { - return null; - } -} - -/** - * Extract license from HTML meta tags - */ -function extractMetaLicense(html) { - const metaRegex = / 0) { - const confidence = matchCount / patterns.length; - detections.push({ - location: source.location, - content: source.content, - type: licenseType, - confidence, - }); - } - } - } - - if (detections.length === 0) { - return { - detected: false, - type: null, - compatible: false, - sources: sources.map(s => ({ - location: s.location, - content: s.content.substring(0, 200), // Truncate - confidence: 0.0, - })), - }; - } - - // Sort by confidence and take the highest - detections.sort((a, b) => b.confidence - a.confidence); - const bestMatch = detections[0]; - - return { - detected: true, - type: bestMatch.type, - compatible: COMPATIBLE_LICENSES.has(bestMatch.type), - sources: detections.map(d => ({ - location: d.location, - content: d.content.substring(0, 200), // Truncate for readability - confidence: d.confidence, - })), - }; -} - -/** - * Check if a license is compatible with extraction - */ -export function isLicenseCompatible(licenseType) { - if (!licenseType) return false; - return COMPATIBLE_LICENSES.has(licenseType); -} - -/** - * Format license info for human-readable output - */ -export function formatLicenseInfo(info) { - if (!info.detected) { - return "❌ No license detected\nFound sources:\n" + - info.sources.map(s => ` - ${s.location}`).join("\n"); - } - - const compatEmoji = info.compatible ? "✅" : "⚠️"; - const compatText = info.compatible - ? "Compatible with extraction" - : "Incompatible - extraction not allowed"; - - return ` -${compatEmoji} License: ${info.type} -${compatText} - -Sources (${info.sources.length}): -${info.sources.map(s => - ` - ${s.location} (confidence: ${(s.confidence * 100).toFixed(0)}%)` -).join("\n")} - `.trim(); -} diff --git a/sinople-theme/deno/lib/scraper/mod.js b/sinople-theme/deno/lib/scraper/mod.js deleted file mode 100644 index e56ed72..0000000 --- a/sinople-theme/deno/lib/scraper/mod.js +++ /dev/null @@ -1,410 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// Web Scraper Module -// Extracts design patterns, structure, and assets from websites - -import { DOMParser } from "https://deno.land/x/deno_dom@v0.1.43/deno-dom-wasm.ts"; -import { detectLicense } from "../license-detector/mod.js"; - -/** - * Main extraction function - */ -export async function extractWebsite(url) { - console.log(`🔍 Extracting website: ${url}`); - - // 1. Detect license - console.log(" 📜 Detecting license..."); - const license = await detectLicense(url); - - if (!license.compatible) { - throw new Error( - `License incompatible: ${license.type || "Unknown"}. Cannot extract.` - ); - } - - console.log(` ✅ License OK: ${license.type}`); - - // 2. Fetch HTML - console.log(" 📥 Fetching HTML..."); - const response = await fetch(url, { - headers: { - "User-Agent": "Sinople-Theme-Extractor/1.0", - }, - }); - - if (!response.ok) { - throw new Error(`Failed to fetch ${url}: ${response.status}`); - } - - const rawHTML = await response.text(); - - // 3. Parse DOM - console.log(" 🌳 Parsing DOM structure..."); - const domStructure = await analyzeDOMStructure(rawHTML); - - // 4. Extract CSS - console.log(" 🎨 Extracting CSS..."); - const rawCSS = await extractCSS(rawHTML, url); - - // 5. Extract design tokens from CSS - console.log(" 🎯 Analyzing design tokens..."); - const designTokens = await extractDesignTokens(rawCSS); - - // 6. Extract assets - console.log(" 🖼️ Cataloging assets..."); - const assets = await extractAssets(rawHTML, url); - - console.log(" ✨ Extraction complete!"); - - return { - url, - license, - domStructure, - designTokens, - assets, - rawHTML, - rawCSS, - extractedAt: new Date().toISOString(), - }; -} - -/** - * Analyze DOM structure - */ -async function analyzeDOMStructure(html) { - const doc = new DOMParser().parseFromString(html, "text/html"); - - if (!doc) { - throw new Error("Failed to parse HTML"); - } - - // Extract main structural elements - const header = doc.querySelector("header"); - const nav = doc.querySelector("nav"); - const main = doc.querySelector("main") || doc.querySelector("#main") || doc.querySelector(".main"); - const aside = doc.querySelector("aside") || doc.querySelector(".sidebar"); - const footer = doc.querySelector("footer"); - - // Extract semantic tags - const semanticTags = extractSemanticTags(doc); - - // Extract ARIA landmarks - const ariaLandmarks = extractARIALandmarks(doc); - - // Extract microformats - const microformats = extractMicroformats(doc); - - return { - hierarchy: { - header: header ? extractElement(header) : null, - navigation: nav ? extractElement(nav) : null, - main: main ? extractElement(main) : null, - sidebar: aside ? extractElement(aside) : null, - footer: footer ? extractElement(footer) : null, - }, - semanticTags, - ariaLandmarks, - microformats, - }; -} - -/** - * Extract element node recursively - */ -function extractElement(el) { - const attributes = {}; - - // Extract all attributes - for (const attr of el.attributes) { - attributes[attr.name] = attr.value; - } - - return { - tag: el.tagName.toLowerCase(), - classes: Array.from(el.classList), - id: el.id || undefined, - attributes, - children: Array.from(el.children).map(child => extractElement(child)), - textContent: el.textContent?.trim().substring(0, 100), // Truncate long text - }; -} - -/** - * Extract all semantic HTML5 tags used - */ -function extractSemanticTags(doc) { - const semanticElements = [ - "article", - "aside", - "details", - "figcaption", - "figure", - "footer", - "header", - "main", - "mark", - "nav", - "section", - "summary", - "time", - ]; - - const found = []; - - for (const tag of semanticElements) { - const elements = doc.querySelectorAll(tag); - if (elements.length > 0) { - found.push(tag); - } - } - - return found; -} - -/** - * Extract ARIA landmarks - */ -function extractARIALandmarks(doc) { - const landmarks = []; - - const elementsWithRole = doc.querySelectorAll("[role]"); - - for (const el of elementsWithRole) { - const role = el.getAttribute("role"); - const label = el.getAttribute("aria-label") || el.getAttribute("aria-labelledby") || ""; - - if (role) { - landmarks.push({ role, label }); - } - } - - return landmarks; -} - -/** - * Extract microformats (h-entry, h-card, etc.) - */ -function extractMicroformats(doc) { - const microformats = []; - - // Look for microformats2 classes (h-entry, h-card, etc.) - const mfElements = doc.querySelectorAll("[class*='h-']"); - - for (const el of mfElements) { - const classes = Array.from(el.classList); - const mfClass = classes.find(c => c.startsWith("h-")); - - if (mfClass) { - const properties = {}; - - // Extract property classes (p-name, u-url, dt-published, etc.) - const propElements = el.querySelectorAll("[class*='p-'], [class*='u-'], [class*='dt-'], [class*='e-']"); - - for (const propEl of propElements) { - const propClasses = Array.from(propEl.classList); - const propClass = propClasses.find(c => - c.startsWith("p-") || c.startsWith("u-") || c.startsWith("dt-") || c.startsWith("e-") - ); - - if (propClass) { - properties[propClass] = propEl.textContent?.trim(); - } - } - - microformats.push({ - type: mfClass, - properties, - }); - } - } - - return microformats; -} - -/** - * Extract CSS from HTML (inline, style tags, linked stylesheets) - */ -async function extractCSS(html, baseUrl) { - const cssFiles = []; - - // Parse HTML to find tags - const linkRegex = /]+rel=["']stylesheet["'][^>]*href=["']([^"']+)["']/gi; - const matches = html.matchAll(linkRegex); - - for (const match of matches) { - const href = match[1]; - const absoluteUrl = new URL(href, baseUrl).toString(); - - try { - const response = await fetch(absoluteUrl); - if (response.ok) { - const css = await response.text(); - cssFiles.push(css); - } - } catch { - // Failed to fetch CSS file - } - } - - // Extract inline