• Stars
    star
    119
  • Rank 297,930 (Top 6 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 7 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Message Machines

Build Status Documentation

Sheens logo

Welcome to Sheens

A tool for implementing workflows and state machines.

Sheens is a lightweight and flexible framework for building and executing workflows and state machines. It is written in Go and is designed to be simple to use and highly scalable. Sheens provides a simple yet powerful syntax for describing workflows and state machines, and it can be used to build everything from simple sequential workflows to complex, event-driven systems.

With Sheens, you can define workflows and state machines using a simple JSON-based syntax. You can then execute these workflows using the Sheens runtime, which provides a highly optimized execution engine for running workflows and state machines at scale.

In addition to its powerful workflow and state machine capabilities, Sheens also includes support for timers, allowing you to define timed events and trigger actions based on them. Sheens also includes a number of other features and capabilities, including support for dynamic workflow loading, automatic state machine validation, and much more.

If you're looking for a flexible and powerful tool for implementing workflows and state machines, Sheens is the perfect choice. Whether you're building a simple sequential workflow or a complex, event-driven system, Sheens provides the tools and capabilities you need to get the job done.

Messaging machines

Sheens is an automation engine that hosts message-processing state machines (also called "sheens"). These machines process and emit messages efficiently and atomically. The initial motivation was implementing IoT-oriented home automations; however, Sheens has been useful in other settings.

Sheens is easy to integrate via HTTP, WebSockets, MQTT, plain TCP, Go or C applications, or via other glue. For example, we have integrated Sheens with several internal services, AWS IoT, Home Assistant, and other frameworks.

The structure and behavior of sheens are amenable to standardization, and multiple implementations are feasible and practical. The Sheens engine is highly programmable. Sheen-oriented tools (debuggers, visualizations, monitoring, analyzers) are often easy to implement.

License

This repo is licensed under Apache License 2.0.

Demo usage

To build, first install Go.

Then:

go get github.com/Comcast/sheens/...
cd $GOPATH/src/github.com/Comcast/sheens # Or equivalent
echo '{"double":1}' | msimple -s specs/double.yaml 

A bit fancier:

mcrew -s specs -t :9000 &
cat cmd/mcrew/input.txt | nc localhost 9000
kill %%

See cmd/mcrew for more discussion, and see the rest of this README and doc/by-example.md for a start at documentation.

Applications will all use the core package (which has decent godoc). If an application wants a little help with containers of machines, then the crew package might be a good start. An application should provide its own message transport (both in and out), and an application should provide its own persistence. For simple example, see cmd/msimple, which is a very simple single-machine process. The example cmd/mcrew demonstrates some additional functionality.

Goals

This project attempts to provide automation gear that is

  1. Simple
  2. Robust and correct
  3. Debuggable, testable
  4. Efficient

IoT is a motivating application area.

Other objectives

  1. Pluggable action interpreters. Actions can be written in a language that's executed by pluggable components.
  2. Transport-agnostic. Input from and output to any sort of messaging services (e.g., HTTP, MQTT, CoAP).
  3. Pluggable persistence.
  4. Amenable to formal specification(s) (see below).
  5. Feasible alternative implementations in other languages.
  6. Modest resource requirements.

Design

A machine processes and emits messages.

  1. A machine's state consists of the name of a node and the set of bindings (and a machine specification). A machine's initial bindings are its parameters.
  2. A machine's specification defines the structure and behavior of the machine. (See specs for some example specifications.)
  3. A state transition is determined by pattern matching against either a pending message or current bindings.
  4. Actions ideally just generate messages and return new bindings. A good action has no side effects nor will it ever block on IO.
  5. A collection of machines is called a crew. A crew is typically associated with a user account (or some agent).
  6. Machines within a crew can send messages to all other machines in that crew or to a specific machine in that crew. (Intra-crew messaging is optionally provided by a nanobus via a pluggable Router.)
  7. Machines can send messages to any service if routed appropriately.
  8. Action languages are pluggable. Most examples here are based on goja, which is an ECMAScript implementation.

"Transmit the message to the receiver; hope for an answer some day."

-Talking Heads

Definitions

This section provides definitions for machines. For an example-based exposition, see this work-in-progress documentation.

Given a machine specification and some initialization parameters, we can make a machine, which can perform actions in response to messages.

A machine specification consists of a map from node names (just strings) to nodes. (See specs for some example specifications.)

A node consists of an optional action and a required branching specification that consists of a branching type, which is either message or bindings, and a set of branches to other nodes.

An action could be any function that accepts bindings and returns bindings. Ultimately, an action can (or should) only construct messages and return a new set of bindings. Every action has a timeout, which is enforced.

Each branch consists of an optional pattern, optional guard, and a required target, which is the name of a node in the machine specification.

A pattern, which can include pattern variables, can be matched against an incoming message or current bindings. See below for more about patterns. A guard is an optional procedure that generates bindings (perhaps nil) from bindings. If a guard returns no bindings, then the branch isn't followed.

A machine consists of its current state: the name of the current node, the current bindings, and a pointer to the machine's specification. A machine's initial parameters become the machine's first bindings.

A crew is a group of machines associated with some agent.

To try to be happy is to try to build a machine with no other specification than that it shall run noiselessly.

-Robert Oppenheimer

Pattern matching

Transitions from one node to another are driven by pattern matching, either against the current set of bindings or a pending message.

A pattern is a string, array, or map (perhaps with deep structure) that can be matched against an incoming message or the current bindings. A string in a pattern that starts with a ? is a pattern variable that will be bound when a message or bindinings matches the pattern.

Here's a pattern with two pattern variables (?here and ?address):

{"person": "homer",
 "likes": "?here",
 "at": {"type": "residence", "address": "?address"}}

The string ? (without anything else) is an anonymous pattern variable that matches anything and is not based on input bindings or included in output bindings.

A message matched against a pattern results in zero or more sets of variable bindings.

As an example, the pattern

{"a":{"b":"?x","c":"?y"},"d":"?y"}

matches

{"a":{"b":1,"c":2},"d":2}

with a set of bindings

[{"?x":1,"?y":2}]

When matching against a message, a map or set (array) value need not be completely specified in the pattern. This behavior is called partial matching. Examples:

Pattern {"a": 1, "b": "?x"} matches {"a": 1, "b": 2, "c": 3} even though the pattern does not contain a key "c".

Pattern {"a": 1, "b": ["?x"]} matches {"a": 1, "b": [2,3]} with bindings [{"?x": 2}, {"?x": 3}]. Note the multiple bindings.

With partial matching, backtracking can occur. Also you might get more than one set of bindings.

An array is treated as a set, which can also trigger backtracking. For example, the pattern

{"a":[{"b":"?x"}]}

matches

{"a":[{"b":1},{"b":2},{"c":3}]}

with the bindings

[{"?x":1},{"?x":2}]

For some more examples, see match/match.md, which is generated by test cases.

The utility patmatch is handy for testing patterns:

patmatch -p '{"a":[{"b":"?x"}]}' -m '{"a":[{"b":1},{"b":2},{"c":3}]}'
[{"?x":1},{"?x":2}]

Experimental optional pattern variables

If a pattern variable starts with ??, that variable (or its associated property when in a map) is optional. Examples:

patmatch -p '{"x":"??opt","y":"?y"}' -m '{"y":"Y"}'
[{"?y":"Y"}]

patmatch -p '{"x":"??opt","y":"?y"}' -m '{"y":"Y","x":"X"}'
[{"??opt":"X","?y":"Y"}]

patmatch -p '["??maybe","a","b"]' -m '["a","b","c"]'
[{"??maybe":"c"}]

patmatch -p '["??maybe","a","b"]' -m '["a","b"]'
[{}]

patmatch -p '["??maybe","a","b"]' -m '["a"]'
null

Experimental matching inequalities

As an experimental feature, pattern matching supports numeric inequalities.

The input bindings should include a binding for a variable with a name that contains either <, >, <=, >=, or != immediately after the leading ?. The input pattern can then use that variable. When matching, a value X will match that variable only if the binding Y for that variable satisfies the inequality with X and Y (in that order). In this case, the output bindings will include a new binding for a variable with the same name as the inequality variable but without the actual inequality.

(Yes, such a feature makes us stare down a slippery slope.)

For example, given input bindings {"?<n":10}, pattern {"n":"?<n"}, and message {"n":3}, the match will succeed with bindings {"?<n":10,"?n":3}.

See the matching examples for several examples. (Search for "inequality".)

Processing

A machine processes an input message by

  1. Obtaining the machine's current node based on the current node name and machine specification.

  2. If the current node has branching of type message, then the message is matched against each branch's pattern. When there's a match, the branch's guard (if any) is executed based on the bindings that resulted from the match. If the guard returns non-nil bindings, the machine's current node name is set to the branch's target, and the machine's current bindings is set to those (non-nil) bindings. When a branch doesn't have a guard, the machine proceeds directly to the branch target.

    Branches are processed in the order given.

  3. If the current node has branching of type bindings, then the procedure above is executed except that the current bindings are used in place of the input message. The process is execute until the branching are of type message, at which point the procedure above is executed.

When the machine arrives at a node that has an action, that action is executed. Action execution results in a new set of bindings, which will replace the current bindings. (An action is given the current bindings.)

A node with an action must have branching of type "bindings", so processing can immediately proceed to the node's branches. (This behavior allows an action to have side effects, but we'd rather actions not have side effects.)

Ideally, actions can only emit messages. In particular, in typical use, an action can't even make an HTTP request!

(You might not have noticed that pattern matching during branch evaluation can result in multiple sets of bindings ("bindingss"). What to do in that case? One approach: If match results in more than one set of bindings, each extra set of bindings results in the creation of a new machine! Alternately: Try each set of bindings in (the arbitrary) order, and go with the first set of bindings that works. That's what the current implementations do, I think.

Discussion

No exceptions?

Retry-like functionality is specified just as any other control flow is specified. There are almost no exceptions. (The only exception is when an internal error occurs, and, even in that case, a setting controls what happens next.

For example, the processor inject the error in bindings to allow for standard, branching-based transitions based on the error. Alternative, the machine could automatically transition to an error node. (That behavior would be the only possibility if the error occured at a location that prevented branching-based error handling.)

Simple state model

A machine's state is independent from other machines' states. Machines can run concurrently without any locking or synchronization.

A machine operates sequentially. Therefore, there are no concurrent state mutations (within a single process).

Virtuous actions have no side effects, and their processing is atomic. Such an action can generate multiple outbound messages, but the processor would only send that batch on if the action terminated without error. Using this behavior, an application can process a message using multiple machines and that entire processing can be atomic.

(Since action interpreters are pluggable, a system can of course provide dangerous action interpreters, which can allow actions to do IO and other unholy things. Yes, you could have a Bash-based action interpreter.)

No internal blocking

A virtuous machine action does not block on IO. Therefore machine performance and resource consumption is can be relatively predictable.

(Again, since action interpreters are pluggable, a system can of course provide dangerous action interpreters, which can allow actions to do IO and other unholy things.)

Future: Dispatch index

When a message is presented to a set of machines (which could contain hundreds of machines), we'll want efficient dispatch to the subset of machines that are waiting on message branching that will (likely) match the message. Efficient dispatch will likely require an index; util/index.go heads that direction. Other approaches are of course possible.

Tool-able

Machines are amenable to debugging using machine-oriented debugging tools that provide the usual operations: reset state, step through transitions, back up, set breakpoints, etc.

Since messages are message processors with exposed state, test tools (see cmd/mexpect for an example) are relatively easy to write. The core can be programmed functionality. (There is no "state" in core!)

Atomic spec updating

If you want to update a machine specification (in a way that's backward-compatible), you don't have to touch any user data. Therefore, you can give many machines a new specification with a single atomic swap (within a process). See core.Specter.

Timers and QoS

A system could have multiple timer services for different qualities of timers. For example, a nanocron could implement timers with goroutines (with various suitable limits). An external timer service could provide durable timers. Etc.

Formal methods

Though you can happily use sheens without worrying about formalities, you can get formal with sheens if you want to.

System verification

The operation of a machine is amenable to formal specification (of evolving precision) and alternate implementations. An interprising investigator could implement a sheens system and prove properties about it. We've started an experiment with Idris along these lines.

Action proofs

In the implementation in this repo, the interpreters for actions and guards are pluggable, so an application is free to provide its own interpreter(s). For example, a conventional native code sheens system, which ideally has been subject to extensive testing, could offer an action interpreter that enables and/or requires proofs of useful properties, such as being total, not making undesired bindings, or only emitting messages with certain properties.

Statistical mechanics

A sheen is not in general a finite state machine. Techincally speaking, a machine is triple of node id, current bindings, and the machine's specification, and the space of bindings is in general not finite. Therefore even holding the specification constant doesn't give a finite state. However, a sheen step does have the Markov property, which makes a wide range of analysis feasible.

For example, consider the projection of a sheen's state space to just the set of nodes defined in the sheens's specification. We now have a finite set of states. Of course, state transitions still have that Markov property. So we can (say) build and maintain simple models of state transition counts over time: count(FROM,TO) β†’ N. If there are S nodes, then that information can be represented as a vector of S*S integer components. Assume we update that data virtually at some interval to reflect a state not changing during that interval. (Of course, we can perform that computation in one go rather than performing some actual heartbeat-like activity.) We could then accumulate a distribution of those vectors over time. Finally, to finish this little example, we could watch for a 2Οƒ (or whatever) excursion, which perhaps indicates a new regime or anomaly of some sort.

Note on atomicity and errors

As we mentioned above, a virtuous action performs no I/O. Therefore, a single message (or even a batch of messages) can be processed atomically againts a set of machines. In general, the result is a structure that contains new states, which can include error states or conditions, and a set of sequences (of sequences) of messages. The caller can then decide what to do next. If the processing resulted in no system-level error conditions, then all states are updated (hopefully atomically via the application's persistence system). Only then are the output messages actually forwarded to a system that can deliver them (with the required policies/guaranties). If any system-level error condition occured, the application could retry all processing. More economically, the application could retry only the specific failure. Either way, the application need not fear side effects from the previous attempt. Of course, other approaches are possible.

Sheens in Shakespeare

KING LEAR How now! what art thou?
SHEEN A machine, sir.
KING LEAR What dost thou profess? what wouldst thou with us?
SHEEN I do profess to be no less than I seem; to serve
him truly that will put me in trust: to love him
that is honest; to converse with him that is wise,
and says little; to fear judgment; to fight when I
cannot choose; and to eat no fish.
KING LEAR What art thou?
SHEEN A very honest-hearted machine, and as poor as the king.
KING LEAR If thou be as poor for a subject as he is for a
king, thou art poor enough. What wouldst thou?
SHEEN Service.
KING LEAR Who wouldst thou serve?
SHEEN You.
KING LEAR Dost thou know me, fellow?
SHEEN No, sir; but you have that in your countenance
which I would fain call master.
KING LEAR What's that?
SHEEN Authority.
KING LEAR What services canst thou do?
SHEEN I can keep honest counsel, ride, run, mar a curious
tale in telling it, and deliver a plain message
bluntly: that which ordinary men are fit for, I am
qualified in; and the best of me is diligence.

Code of Conduct

We take our code of conduct seriously. Please abide by it.

Contributing

Please read our contributing guide for details on how to contribute to our project.

References

  1. The Actor Model
  2. Guards in OCaml
  3. AWS Step Functions and their state language
  4. Erlang's gen_statem
  5. Leslie Lamport on state machines
  6. The Rulio rules engine
  7. Little Sheens

More Repositories

1

FreeFlow

A layout engine for Android that decouples layouts from the View containers that manage scrolling and view recycling. FreeFlow makes it really easy to create custom layouts and beautiful transition animations as data and layouts change
Java
2,397
star
2

rulio

Rulio
Go
336
star
3

gots

MPEG Transport Stream handling in Go
Go
306
star
4

sirius

A distributed system library for managing application reference data
Scala
298
star
5

cmb

This project is no longer actively supported. It is made available as read-only. A highly available, horizontally scalable queuing and notification service compatible with AWS SQS and SNS
Java
278
star
6

jrugged

A Java libary of robustness design patterns
Java
266
star
7

ip4s

Defines immutable, safe data structures for describing IP addresses, multicast joins, socket addresses and similar IP & network related data types
Scala
224
star
8

mamba

Mamba is a Swift iOS, tvOS and macOS framework to parse, validate and write HTTP Live Streaming (HLS) data.
Swift
178
star
9

kube-yarn

Running YARN on Kubernetes with PetSet controller.
Makefile
166
star
10

k8sh

A simple, easily extensible shell for navigating your kubernetes clusters
Shell
155
star
11

patternlab-edition-node-webpack

The webpack wrapper around patternlab-node core, providing tasks to interact with the core library and move supporting frontend assets.
JavaScript
127
star
12

gaad

GAAD (Go Advanced Audio Decoder)
Go
126
star
13

eel

A simple proxy service to forward JSON events and transform or filter them along the way.
Go
105
star
14

Speed-testJS

JavaScript
94
star
15

traffic_control

Traffic Control CDN
92
star
16

Surf-N-Perf

Micro-library for gathering web page performance data
JavaScript
90
star
17

pulsar-client-go

A Go client library for Apache Pulsar
Go
78
star
18

graphvinci

A better schema visualizer for GraphQL APIs
JavaScript
74
star
19

MirrorTool-for-Kafka-Connect

A Kafka Source connector for Kafka Connect
Java
72
star
20

php-legal-licenses

A utility to help generate a file containing information about dependencies including the full license text.
PHP
70
star
21

caption-inspector

Caption Inspector is a reference decoder for Closed Captions (CEA-608 and CEA-708).
C
69
star
22

money

Dapper Style Distributed Tracing Instrumentation Libraries
Scala
67
star
23

compass-csslint

Easily integrate CSS Lint into your projects that use the Compass CSS Framework
Ruby
65
star
24

snowdrift

App to perform testing and validation of firewall rules
Shell
63
star
25

dialyzex

A Mix task for type-checking your Elixir project with dialyzer
Elixir
61
star
26

ssh-to

Easily manage dozens or hundreds of machines via SSH
Shell
58
star
27

ansible-sdkman

An Ansible role that installs, configures, and manages SDKMAN
Python
58
star
28

Bynar

Server remediation as a service
Rust
57
star
29

xGitGuard

AI based Secrets Detection Python Framework
Python
54
star
30

Canticle

Go
50
star
31

scte35-js

A SCTE 35 Parser for JavaScript
HTML
47
star
32

go-leaderelection

GoLea is a Go library that provides the capability for a set of distributed processes to compete for leadership for a shared resource.
Go
45
star
33

Comcast.github.io-archive

The main Open Source portal for Comcast
HTML
38
star
34

scte35-go

Golang implementation of ANSI/SCTE-35
Go
36
star
35

sitemapper-for-js

Generate XML sitemaps for JS Websites (Supports Angular, React)
JavaScript
35
star
36

zucchini

Run your cucumber-jvm tests in parallel across all your devices
Java
34
star
37

Oscar

OSCAR - OpenSource Cablemodem file AssembleR - DOCSIS, PacketCable, DPoE Configuration Editor and API Framework
Java
33
star
38

hlsparserj

Java
32
star
39

weasel

Lightweight license checker.
Go
32
star
40

Infinite-File-Curtailer

Curtail is a utility program that reads stdin and writes to a file bound by size.
C
32
star
41

DahDit

Custom Views for drawing Dotted and Dashed Lines without jumping through hoops.
Kotlin
27
star
42

resourceprovider2

Resource Management API Generator for Android
Kotlin
22
star
43

python-batch-runner

A tiny framework for building batch applications as a collection of tasks in a workflow.
Python
22
star
44

Buildenv-Tool

Go
21
star
45

blueprint

Blueprint is a compact framework for constructing mvp architecture within a scrollable, multi-view-type list UI. It uses the Android RecyclerView library, and currently only supports LinearLayouts
Kotlin
21
star
46

comcast.github.io

The main Open Source portal for Comcast
JavaScript
20
star
47

ProjectGuardRail

AI/ML applications have unique security threats. Project GuardRail is a set of security and privacy requirements that AI/ML applications should meet during their design phase that serve as guardrails against these threats. These requirements help scope the threats such applications must be protected against.
20
star
48

resourceprovider-utils

Samples and Test Utilities Library for the ResourceProvider API Generator Gradle Plugin for Android.
Java
19
star
49

xCOMPASS

This repository hosts a persona based privacy threat modeling solution called Models of Applied Privacy or MAP.
17
star
50

compass-csscss

Easily integrate csscss into your projects that use the Compass CSS Framework
Ruby
16
star
51

go-edgegrid

A Golang Akamai API client and Akamai OPEN EdgeGrid Authentication scheme authentication handler.
Go
16
star
52

cea-extractor

Parsing and display logic for CEA-608 caption data in fragmented MP4 files.
TypeScript
16
star
53

all-digital

Comcast All Digital CSS
SCSS
15
star
54

littlesheens

A Sheens implementation that has a small footprint
C
15
star
55

rdk-on-raspberrypi

Documentation for running RDK profiles ( Video, broadband, Camera ) on Raspberrypi boards
15
star
56

terraform-provider-akamai

An Akamai GTM Terraform provider
Go
14
star
57

Xooie

Important note: this project is no longer actively maintained. Xfinity Xooie - Modular, Modifiable, Responsive, Accessible
JavaScript
14
star
58

Superior-Cache-ANalyzer

A tool for inspecting the contents of Apache Traffic Server caches
Python
14
star
59

ActorServiceRegistry

Scala
14
star
60

connvitals-monitor

A persistent monitor and aggregator of network statistics
Python
13
star
61

RestfulHttpsProxy

Go
13
star
62

Priority-Operation-Processing

A workflow orchestration system where the workflow is scheduled as a unit giving resource priority once selected. Priority queuing and customizable scheduling algorithms. Customer aware for multi-tenant. A JSON DAG based blueprint defines the execution flow. Executes operations within a workflow by spinning up on-demand Kubernetes Pods (dynamic resource allocation)
Java
13
star
63

connvitals

A network analysis and statistics aggregation tool
Python
13
star
64

xml-selector

A jQuery-like interface for working with XML using CSS-style selectors
JavaScript
12
star
65

prombox

Prombox creates a sandbox environment for editing and testing Prometheus configuration on the fly
JavaScript
12
star
66

svn-to-github

Comprehensive Tool for Converting SVN to Git in Bulk
Shell
12
star
67

watchmen-ping-nightmare

A plugin for watchmen that uses nightmare and an electron browser to monitor websites
JavaScript
12
star
68

tsb

A Transitive Source Builder for managing builds across multiple repositories
Go
11
star
69

scte224structs

Utilities for modeling SCTE-224 data in Go
Go
11
star
70

cf-recycle-plugin

Cloud Foundry cli plugin for rolling restart of application instances
Go
10
star
71

redirector

Java
10
star
72

discovery

The Comcast discovery services for the open source community
Java
10
star
73

fishymetrics

Redfish API Prometheus Exporter for monitoring large scale server deployments
Go
10
star
74

libcertifier

With small, space optimized, 90KB libCertifier(), IoT devices (cameras, toasters, sensors ….) can now request and receive unique, compact (650 bytes) digital certificates (x509 v3 compliant).
C
10
star
75

compare-ini-files

Compare an arbitrary number of .ini files based on logical sections and key/value pairs.
PHP
9
star
76

flume2storm

This project is no longer actively maintained. The Flume2Storm repository contains the source code, documentation (wiki) and issue tracking system
Java
9
star
77

cts-mpx

Ruby
8
star
78

ansible-role-pypi

An ansible role for configuring a pypi-server on a systemd centos system.
Python
8
star
79

akamai-slack-reporter

A Slack slash command integration for querying your team's Akamai configuration
JavaScript
8
star
80

rapid-ip-checker

A GPU accelerated tool to compare large lists of IPv4/IPv6 addresses.
Python
8
star
81

css_lint_ruby

Nicholas C. Zakas and Nicole Sullivan's CSS Lint made available as a Ruby gem.
Ruby
8
star
82

akamai-gtm

A CLI to Akamai GTM
Go
8
star
83

DNS-over-HTTPs-translator

Go
7
star
84

tlsrpt_processor

Simple python script to process TLSRPT reports
Python
7
star
85

libstorage

rust storage server helper utilities
Rust
7
star
86

EasyConnect

Reference Development Kit that will help partners and vendors implement EasyConnect in their devices.
Java
7
star
87

dmc-sim

ns3 simulator code for Distributed Monotonic Clocks
C++
7
star
88

jovo-plugin-resume

πŸ”ˆ A plugin for resuming conversations in the Open Source Voice Layer, Jovo (https://www.jovo.tech)
TypeScript
7
star
89

Porrtal

This project was created to help developers. You can use the platform to build web applications. The project supports both React and Angular development.
TypeScript
7
star
90

cf-zdd-plugin

Go
7
star
91

vesper_legacy

Secure Telephone Identity Management in Session Initiation Protocol
Go
7
star
92

SyntaViz

A visualization interface for analyzing a (very large) corpus of natural-language queries.
Python
7
star
93

hypergard

A JavaScript client for HAL APIs with support for forms
JavaScript
7
star
94

ctex

A Mix task and helpers for running common_test suites
Elixir
7
star
95

plax

A test automation engine for messaging systems
Go
7
star
96

Ravel

Go
7
star
97

pipeclamp

Java
6
star
98

rally-rest-toolkit

Client API library for interacting with the Rally REST API
Go
6
star
99

rdkcryptoapi

Contains Cryptographic APIs used in the RDK Software Stack
C
6
star
100

polaris

Vanilla Web Components for global Header, Footer & Toast notifications for XFINITY Websites
JavaScript
6
star