v0.0.1

@0xd7ed440331369f59;

using Spk = import "/sandstorm/package.capnp";

const pkgdef :Spk.PackageDefinition = (
  id = "s3u2xgmqwznz2n3apf30sm3gw1d85y029enw5pymx734cnk5n78h",

  manifest = (
    appTitle = (defaultText = "Collections"),
    appVersion = 1,  # Increment this for every release.
    appMarketingVersion = (defaultText = "0.0.1"),

    actions = [
      (
        nounPhrase = (defaultText = "collection"),
        command = .myCommand
        # The command to run when starting for the first time. (".myCommand"
        # is just a constant defined at the bottom of the file.)
      )
    ],

    continueCommand = .myCommand,
    metadata = (
      # Data which is not needed specifically to execute the app, but is useful
      # for purposes like marketing and display.  These fields are documented at
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#add-required-metadata
      # and (in deeper detail) in the sandstorm source code, in the Metadata section of
      # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp
      icons = (
        # Various icons to represent the app in various contexts.
        #appGrid = (svg = embed "path/to/appgrid-128x128.svg"),
        #grain = (svg = embed "path/to/grain-24x24.svg"),
        #market = (svg = embed "path/to/market-150x150.svg"),
        #marketBig = (svg = embed "path/to/market-big-300x300.svg"),
      ),

      website = "https://sandstorm.io",
      codeUrl = "https://github.com/dwrensha/sandstorm-collections-app",
      license = (openSource = mit),

      categories = [productivity],
      # A list of categories/genres to which this app belongs, sorted with best fit first.
      # See the list of categories at
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#categories

      author = (
        upstreamAuthor = "David Renshaw",
        contactEmail = "david@sandstorm.io",
        # Email address to contact for any issues with this app. This includes end-user support
        # requests as well as app store administrator requests, so it is very important that this be a
        # valid address with someone paying attention to it.

        #pgpSignature = embed "path/to/pgp-signature",
        # PGP signature attesting responsibility for the app ID. This is a binary-format detached
        # signature of the following ASCII message (not including the quotes, no newlines, and
        # replacing <app-id> with the standard base-32 text format of the app's ID):
        #
        # "I am the author of the Sandstorm.io app with the following ID: <app-id>"
        #
        # You can create a signature file using `gpg` like so:
        #
        #     echo -n "I am the author of the Sandstorm.io app with the following ID: <app-id>" | gpg --sign > pgp-signature
        #
        # Further details including how to set up GPG and how to use keybase.io can be found
        # at https://docs.sandstorm.io/en/latest/developing/publishing-apps/#verify-your-identity
      ),

      #pgpKeyring = embed "path/to/pgp-keyring",
      # A keyring in GPG keyring format containing all public keys needed to verify PGP signatures in
      # this manifest (as of this writing, there is only one: `author.pgpSignature`).
      #
      # To generate a keyring containing just your public key, do:
      #
      #     gpg --export <key-id> > keyring
      #
      # Where `<key-id>` is a PGP key ID or email address associated with the key.

      #description = (defaultText = embed "path/to/description.md"),
      # The app's description in Github-flavored Markdown format, to be displayed e.g.
      # in an app store. Note that the Markdown is not permitted to contain HTML nor image tags (but
      # you can include a list of screenshots separately).

      shortDescription = (defaultText = "share with groups"),
      # A very short (one-to-three words) description of what the app does. For example,
      # "Document editor", or "Notetaking", or "Email client". This will be displayed under the app
      # title in the grid view in the app market.

      screenshots = [
        # Screenshots to use for marketing purposes.  Examples below.
        # Sizes are given in device-independent pixels, so if you took these
        # screenshots on a Retina-style high DPI screen, divide each dimension by two.

        #(width = 746, height = 795, jpeg = embed "path/to/screenshot-1.jpeg"),
        #(width = 640, height = 480, png = embed "path/to/screenshot-2.png"),
      ],
      #changeLog = (defaultText = embed "path/to/sandstorm-specific/changelog.md"),
      # Documents the history of changes in Github-flavored markdown format (with the same restrictions
      # as govern `description`). We recommend formatting this with an H1 heading for each version
      # followed by a bullet list of changes.
    ),
  ),

  sourceMap = (
    # Here we defined where to look for files to copy into your package. The
    # `spk dev` command actually figures out what files your app needs
    # automatically by running it on a FUSE filesystem. So, the mappings
    # here are only to tell it where to find files that the app wants.
    searchPath = [
      ( sourcePath = "spk" ),
      ( sourcePath = "/",    # Then search the system root directory.
        hidePaths = [ "home", "proc", "sys",
                      "etc/passwd", "etc/hosts", "etc/host.conf",
                      "etc/nsswitch.conf", "etc/resolv.conf" ]
        # You probably don't want the app pulling files from these places,
        # so we hide them. Note that /dev, /var, and /tmp are implicitly
        # hidden because Sandstorm itself provides them.
      )
    ]
  ),

  fileList = "sandstorm-files.list",
  # `spk dev` will write a list of all the files your app uses to this file.
  # You should review it later, before shipping your app.

  alwaysInclude = [],
  # Fill this list with more names of files or directories that should be
  # included in your package, even if not listed in sandstorm-files.list.
  # Use this to force-include stuff that you know you need but which may
  # not have been detected as a dependency during `spk dev`. If you list
  # a directory here, its entire contents will be included recursively.

);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/collections-server"],
  environ = [
    # Note that this defines the *entire* environment seen by your app.
    (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin"),
    (key = "SANDSTORM", value = "1"),
    # Export SANDSTORM=1 into the environment, so that apps running within Sandstorm
    # can detect if $SANDSTORM="1" at runtime, switching UI and/or backend to use
    # the app's Sandstorm-specific integration code.
  ]
);

@0xd7ed440331369f59;

using Spk = import "/sandstorm/package.capnp";

const pkgdef :Spk.PackageDefinition = (
  id = "s3u2xgmqwznz2n3apf30sm3gw1d85y029enw5pymx734cnk5n78h",

  manifest = (
    appTitle = (defaultText = "Collections"),
    appVersion = 0,  # Increment this for every release.
    appMarketingVersion = (defaultText = "0.0.0"),

    actions = [
      (
        nounPhrase = (defaultText = "collection"),
        command = .myCommand
        # The command to run when starting for the first time. (".myCommand"
        # is just a constant defined at the bottom of the file.)
      )
    ],

    continueCommand = .myCommand,
    metadata = (
      # Data which is not needed specifically to execute the app, but is useful
      # for purposes like marketing and display.  These fields are documented at
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#add-required-metadata
      # and (in deeper detail) in the sandstorm source code, in the Metadata section of
      # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp
      icons = (
        # Various icons to represent the app in various contexts.
        #appGrid = (svg = embed "path/to/appgrid-128x128.svg"),
        #grain = (svg = embed "path/to/grain-24x24.svg"),
        #market = (svg = embed "path/to/market-150x150.svg"),
        #marketBig = (svg = embed "path/to/market-big-300x300.svg"),
      ),

      website = "https://sandstorm.io",
      codeUrl = "https://github.com/dwrensha/sandstorm-collections-app",
      license = (openSource = mit),

      categories = [productivity],
      # A list of categories/genres to which this app belongs, sorted with best fit first.
      # See the list of categories at
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#categories

      author = (
        upstreamAuthor = "David Renshaw",
        contactEmail = "david@sandstorm.io",
        # Email address to contact for any issues with this app. This includes end-user support
        # requests as well as app store administrator requests, so it is very important that this be a
        # valid address with someone paying attention to it.

        #pgpSignature = embed "path/to/pgp-signature",
        # PGP signature attesting responsibility for the app ID. This is a binary-format detached
        # signature of the following ASCII message (not including the quotes, no newlines, and
        # replacing <app-id> with the standard base-32 text format of the app's ID):
        #
        # "I am the author of the Sandstorm.io app with the following ID: <app-id>"
        #
        # You can create a signature file using `gpg` like so:
        #
        #     echo -n "I am the author of the Sandstorm.io app with the following ID: <app-id>" | gpg --sign > pgp-signature
        #
        # Further details including how to set up GPG and how to use keybase.io can be found
        # at https://docs.sandstorm.io/en/latest/developing/publishing-apps/#verify-your-identity
      ),

      #pgpKeyring = embed "path/to/pgp-keyring",
      # A keyring in GPG keyring format containing all public keys needed to verify PGP signatures in
      # this manifest (as of this writing, there is only one: `author.pgpSignature`).
      #
      # To generate a keyring containing just your public key, do:
      #
      #     gpg --export <key-id> > keyring
      #
      # Where `<key-id>` is a PGP key ID or email address associated with the key.

      #description = (defaultText = embed "path/to/description.md"),
      # The app's description in Github-flavored Markdown format, to be displayed e.g.
      # in an app store. Note that the Markdown is not permitted to contain HTML nor image tags (but
      # you can include a list of screenshots separately).

      shortDescription = (defaultText = "share with groups"),
      # A very short (one-to-three words) description of what the app does. For example,
      # "Document editor", or "Notetaking", or "Email client". This will be displayed under the app
      # title in the grid view in the app market.

      screenshots = [
        # Screenshots to use for marketing purposes.  Examples below.
        # Sizes are given in device-independent pixels, so if you took these
        # screenshots on a Retina-style high DPI screen, divide each dimension by two.

        #(width = 746, height = 795, jpeg = embed "path/to/screenshot-1.jpeg"),
        #(width = 640, height = 480, png = embed "path/to/screenshot-2.png"),
      ],
      #changeLog = (defaultText = embed "path/to/sandstorm-specific/changelog.md"),
      # Documents the history of changes in Github-flavored markdown format (with the same restrictions
      # as govern `description`). We recommend formatting this with an H1 heading for each version
      # followed by a bullet list of changes.
    ),
  ),

  sourceMap = (
    # Here we defined where to look for files to copy into your package. The
    # `spk dev` command actually figures out what files your app needs
    # automatically by running it on a FUSE filesystem. So, the mappings
    # here are only to tell it where to find files that the app wants.
    searchPath = [
      ( sourcePath = "spk" ),
      ( sourcePath = "/",    # Then search the system root directory.
        hidePaths = [ "home", "proc", "sys",
                      "etc/passwd", "etc/hosts", "etc/host.conf",
                      "etc/nsswitch.conf", "etc/resolv.conf" ]
        # You probably don't want the app pulling files from these places,
        # so we hide them. Note that /dev, /var, and /tmp are implicitly
        # hidden because Sandstorm itself provides them.
      )
    ]
  ),

  fileList = "sandstorm-files.list",
  # `spk dev` will write a list of all the files your app uses to this file.
  # You should review it later, before shipping your app.

  alwaysInclude = [],
  # Fill this list with more names of files or directories that should be
  # included in your package, even if not listed in sandstorm-files.list.
  # Use this to force-include stuff that you know you need but which may
  # not have been detected as a dependency during `spk dev`. If you list
  # a directory here, its entire contents will be included recursively.

);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/collections-server"],
  environ = [
    # Note that this defines the *entire* environment seen by your app.
    (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin"),
    (key = "SANDSTORM", value = "1"),
    # Export SANDSTORM=1 into the environment, so that apps running within Sandstorm
    # can detect if $SANDSTORM="1" at runtime, switching UI and/or backend to use
    # the app's Sandstorm-specific integration code.
  ]
);


fixed naming typo

fixed naming typo

@0xca7b62e1bed2bc72;

using Cxx = import "/capnp/c++.capnp";
$Cxx.namespace("robocup2Dsim::bcprotocol");

using Metadata = import "/src/core/metadata.capnp";
using Command = import "command.capnp";

struct RequestHeader
{
    sequence @0 :Metadata.SequenceNumber;
}

struct Request
{
    header @0 :RequestHeader;
    union
    {
	init @1 :Command.InitRequest;
	reconnect @2 :Command.ReconnectRequest;
	bye @3 :Command.ByeRequest;
    }
}

struct ReplyHeader
{
    sequence @0 :Metadata.SequenceNumber;
}

struct Reply
{
    header @0 :ReplyHeader;
    union
    {
	init @1 :Command.InitReply;
	reconnect @2 :Command.ReconnectReply;
	bye @3 :Command.ByeReply;
    }
}

@0xca7b62e1bed2bc72;

using Cxx = import "/capnp/c++.capnp";
$Cxx.namespace("robocup2Dsim::bcprotocol");

using Command = import "command.capnp";

Struct RequestHeader
{
    sequence @0 :Metadata.SequenceNumber;
}

struct Request
{
    header @0 :RequestHeader
    union
    {
	init @1 :Command.InitRequest;
	reconnect @2 :Command.ReconnectRequest;
	bye @3 :Command.ByeRequest;
    }
}

struct ReplyHeader
{
    sequence @0 :Metadata.SequenceNumber;
}

struct Reply
{
    header @0 :ReplyHeader;
    union
    {
	init @1 :Command.InitReply;
	reconnect @2 :Command.ReconnectReply;
	bye @3 :Command.ByeReply;
    }
}


capnp schema compiles but is not able to import go.capnp

@0xfb2d77234707241e; # unique file ID, generated by `capnp id`
using Go = import "/home/christian/go/src/zombiezen.com/go/capnproto2/std";
$Go.package("proto");
$Go.import("rains/proto");

struct RainsMessage  {
    #RainsMessage contains the data of a message
	token           @0 :Data;
	content         @1 :List(MessageSection);
	signatures      @2 :List(Signature);
	capabilities    @3 :List(Text);
}

interface MessageSection  {
}

const noCapability :Text = "";
const tLSOverTCP :Text = "urn:x-rains:tlssrv";

interface MessageSectionWithSig extends(MessageSection, Interval) {
    #MessageSectionWithSig can be either an Assertion, Shard or Zone
	sigs            @0 () -> (sig :Signature);
	addSig          @1 (sig :Signature);
	deleteSig       @2 (int :Int32);
	deleteAllSigs   @3 ();
   #TODO CFE what is the syntax of a method without arguments
	getContext      @4 () -> (context :Text);
	getSubjectZone  @5 () -> (zone :Text);
	createStub      @6 () -> (section :MessageSectionWithSig);
	validFrom       @7 () -> (validFrom :Int64);
	validUntil      @8 () -> (validUntil :Int64);
	hash            @9 () -> (hash :Text);
}

interface Interval  {
    #Interval defines an interval over strings
	begin @0 () -> (begin :Text);
    end     @1 () -> (end :Text);
}

interface Hashable  {
    #Hashable can be implemented by objects that are not natively hashable.
	hash @0 () -> (hash :Text);
}

struct AssertionSection  {
    #AssertionSection contains information about the assertion
	subjectName @0 :Text;
	content     @1 :List(Obj);
	signatures  @2 :List(Signature);
	subjectZone @3 :Text;
	context     @4 :Text;
}

struct ShardSection  {
    #ShardSection contains information about the shard
	content     @0 :List(AssertionSection);
	signatures  @1 :List(Signature);
	subjectZone @2 :Text;
	context     @3 :Text;
	rangeFrom   @4 :Text;
	rangeTo     @5 :Text;
}

struct ZoneSection  {
    #ZoneSection contains information about the zone
	signatures  @0  :List(Signature);
	subjectZone @1  :Text;
	context     @2  :Text;
	content     @3  :List(MessageSectionWithSig);
}

struct QuerySection  {
    #QuerySection contains information about the query
	token   @0      :Data;
	name    @1      :Text;
	context @2      :Text;
	type    @3      :ObjectType;
	expires @4      :Int64; #time when this query expires represented as the number of seconds elapsed since January 1, 1970 UTC
	options @5      :List(QueryOption);
}

enum QueryOption {
	minE2ELatency            @0;
	minLastHopAnswerSize     @1;
	minInfoLeakage           @2;
	cachedAnswersOnly        @3;
	expiredAssertionsOk      @4;
	tokenTracing             @5;
	noVerificationDelegation @6;
	noProactiveCaching       @7;
}

enum ObjectType {
	oTName        @0;
	oTIP6Addr     @1;
	oTIP4Addr     @2;
	oTRedirection @3;
	oTDelegation  @4;
	oTNameset     @5;
	oTCertInfo    @6;
	oTServiceInfo @7;
	oTRegistrar   @8;
	oTRegistrant  @9;
	oTInfraKey    @10;
	oTExtraKey    @11;
}

struct SubjectAddr  {
	addressFamily @0    :Text;
	prefixLength  @1    :UInt32;
	address       @2    :Text;
}

struct AddressAssertionSection  {
    #AddressAssertionSection contains information about the address assertion
	subjectAddr @0  :SubjectAddr;
	content     @1  :List(Obj);
	signatures  @2  :List(Signature);
	context     @3  :Text;
}

struct AddressZoneSection  {
    #AddressZoneSection contains information about the address zone
	subjectAddr @0  :SubjectAddr;
	signatures  @1  :List(Signature);
	context     @2  :Text;
	content     @3  :List(AddressAssertionSection);
}

struct AddressQuerySection  {
    #AddressQuerySection contains information about the address query
	subjectAddr @0 :SubjectAddr;
	token       @1 :Data;
	context     @2 :Text;
	types       @3 :List(Int32);
	expires     @4 :Int64;
	options     @5 :List(QueryOption);
}

struct NotificationSection  {
    #NotificationSection contains information about the notification
	token @0    :Data;
	type  @1    :NotificationType;
	data  @2    :Text;
}

enum NotificationType {
	heartbeat          @0;
	capHashNotKnown    @1;
	badMessage         @2;
	rcvInconsistentMsg @3;
	noAssertionsExist  @4;
	msgTooLarge        @5;
	unspecServerErr    @6;
	serverNotCapable   @7;
	noAssertionAvail   @8;
}

struct Signature  {
    #Signature on a Rains message or section
	keySpace   @0 :KeySpaceID;
	algorithm  @1 :SignatureAlgorithmType;
	validSince @2 :Int64;
	validUntil @3 :Int64;
	data       @4 :Data;
}

enum KeySpaceID {
#KeySpaceID identifies a key space
	rainsKeySpace @0;
}

enum SignatureAlgorithmType {
#SignatureAlgorithmType specifies a signature algorithm type
	ed25519  @0;
	ed448    @1;
	ecdsa256 @2;
	ecdsa384 @3;
}

enum HashAlgorithmType {
#HashAlgorithmType specifies a hash algorithm type
	noHashAlgo @0;
	sha256     @1;
	sha384     @2;
	sha512     @3;
}

struct PublicKey  {
    #PublicKey contains information about a public key
	type       @0 :SignatureAlgorithmType;
	key        @1 :Data;
	validFrom  @2 :Int64;
	validUntil @3 :Int64;
}

struct CertificateObject  {
    #CertificateObject contains certificate information
	type     @0 :ProtocolType;
	usage    @1 :CertificateUsage;
	hashAlgo @2 :HashAlgorithmType;
	data     @3 :Data;
}

enum ProtocolType {
	pTUnspecified @0;
	pTTLS         @1;
}

enum CertificateUsage {
	cUTrustAnchor @0;
	cUEndEntity   @1;
}

struct ServiceInfo  {
    #ServiceInfo contains information how to access a named service
	name     @0 :Text;
	port     @1 :UInt16;
	priority @2 :UInt32;
}

struct Obj  {
    #Object is a container for different values determined by the given type.
	type  @0    :ObjectType;
	value @1    :Data;
}

@0xfb2d77234707241e; # unique file ID, generated by `capnp id`
using Go = import "go.capnp";
$Go.package("proto");
$Go.import("rains/proto");

struct RainsMessage  {
    #RainsMessage contains the data of a message
	token           @0 :Data;
	content         @1 :List(MessageSection);
	signatures      @2 :List(Signature);
	capabilities    @3 :List(Text);
}

interface MessageSection  {
}

const noCapability :Text = "";
const tLSOverTCP :Text = "urn:x-rains:tlssrv";

interface MessageSectionWithSig extends(MessageSection, Interval) {
    #MessageSectionWithSig can be either an Assertion, Shard or Zone
	sigs            @0 () -> (sig :Signature);
	addSig          @1 (sig :Signature);
	deleteSig       @2 (int :Int32);
	deleteAllSigs   @3 ();
   #TODO CFE what is the syntax of a method without arguments
	getContext      @4 () -> (context :Text);
	getSubjectZone  @5 () -> (zone :Text);
	createStub      @6 () -> (section :MessageSectionWithSig);
	validFrom       @7 () -> (validFrom :Int64);
	validUntil      @8 () -> (validUntil :Int64);
	hash            @9 () -> (hash :Text);
}

interface Interval  {
    #Interval defines an interval over strings
	begin @0 () -> (begin :Text);
    end     @1 () -> (end :Text);
}

interface Hashable  {
    #Hashable can be implemented by objects that are not natively hashable.
	hash @0 () -> (hash :Text);
}

struct AssertionSection  {
    #AssertionSection contains information about the assertion
	subjectName @0 :Text;
	content     @1 :List(Obj);
	signatures  @2 :List(Signature);
	subjectZone @3 :Text;
	context     @4 :Text;
}

struct ShardSection  {
    #ShardSection contains information about the shard
	content     @0 :List(AssertionSection);
	signatures  @1 :List(Signature);
	subjectZone @2 :Text;
	context     @3 :Text;
	rangeFrom   @4 :Text;
	rangeTo     @5 :Text;
}

struct ZoneSection  {
    #ZoneSection contains information about the zone
	signatures  @0  :List(Signature);
	subjectZone @1  :Text;
	context     @2  :Text;
	content     @3  :List(MessageSectionWithSig);
}

struct QuerySection  {
    #QuerySection contains information about the query
	token   @0      :Data;
	name    @1      :Text;
	context @2      :Text;
	type    @3      :ObjectType;
	expires @4      :Int64; #time when this query expires represented as the number of seconds elapsed since January 1, 1970 UTC
	options @5      :List(QueryOption);
}

enum QueryOption {
	minE2ELatency            @0;
	minLastHopAnswerSize     @1;
	minInfoLeakage           @2;
	cachedAnswersOnly        @3;
	expiredAssertionsOk      @4;
	tokenTracing             @5;
	noVerificationDelegation @6;
	noProactiveCaching       @7;
}

enum ObjectType {
	oTName        @0;
	oTIP6Addr     @1;
	oTIP4Addr     @2;
	oTRedirection @3;
	oTDelegation  @4;
	oTNameset     @5;
	oTCertInfo    @6;
	oTServiceInfo @7;
	oTRegistrar   @8;
	oTRegistrant  @9;
	oTInfraKey    @10;
	oTExtraKey    @11;
}

struct SubjectAddr  {
	addressFamily @0    :Text;
	prefixLength  @1    :UInt32;
	address       @2    :Text;
}

struct AddressAssertionSection  {
    #AddressAssertionSection contains information about the address assertion
	subjectAddr @0  :SubjectAddr;
	content     @1  :List(Obj);
	signatures  @2  :List(Signature);
	context     @3  :Text;
}

struct AddressZoneSection  {
    #AddressZoneSection contains information about the address zone
	subjectAddr @0  :SubjectAddr;
	signatures  @1  :List(Signature);
	context     @2  :Text;
	content     @3  :List(AddressAssertionSection);
}

struct AddressQuerySection  {
    #AddressQuerySection contains information about the address query
	subjectAddr @0 :SubjectAddr;
	token       @1 :Data;
	context     @2 :Text;
	types       @3 :List(Int32);
	expires     @4 :Int64;
	options     @5 :List(QueryOption);
}

struct NotificationSection  {
    #NotificationSection contains information about the notification
	token @0    :Data;
	type  @1    :NotificationType;
	data  @2    :Text;
}

enum NotificationType {
	heartbeat          @0;
	capHashNotKnown    @1;
	badMessage         @2;
	rcvInconsistentMsg @3;
	noAssertionsExist  @4;
	msgTooLarge        @5;
	unspecServerErr    @6;
	serverNotCapable   @7;
	noAssertionAvail   @8;
}

struct Signature  {
    #Signature on a Rains message or section
	keySpace   @0 :KeySpaceID;
	algorithm  @1 :SignatureAlgorithmType;
	validSince @2 :Int64;
	validUntil @3 :Int64;
	data       @4 :Data;
}

enum KeySpaceID {
#KeySpaceID identifies a key space
	rainsKeySpace @0;
}

enum SignatureAlgorithmType {
#SignatureAlgorithmType specifies a signature algorithm type
	ed25519  @0;
	ed448    @1;
	ecdsa256 @2;
	ecdsa384 @3;
}

enum HashAlgorithmType {
#HashAlgorithmType specifies a hash algorithm type
	noHashAlgo @0;
	sha256     @1;
	sha384     @2;
	sha512     @3;
}

struct PublicKey  {
    #PublicKey contains information about a public key
	type       @0 :SignatureAlgorithmType;
	key        @1 :Data;
	validFrom  @2 :Int64;
	validUntil @3 :Int64;
}

struct CertificateObject  {
    #CertificateObject contains certificate information
	type     @0 :ProtocolType;
	usage    @1 :CertificateUsage;
	hashAlgo @2 :HashAlgorithmType;
	data     @3 :Data;
}

enum ProtocolType {
	pTUnspecified @0;
	pTTLS         @1;
}

enum CertificateUsage {
	cUTrustAnchor @0;
	cUEndEntity   @1;
}

struct ServiceInfo  {
    #ServiceInfo contains information how to access a named service
	name     @0 :Text;
	port     @1 :UInt16;
	priority @2 :UInt32;
}

struct Obj  {
    #Object is a container for different values determined by the given type.
	type  @0    :ObjectType;
	value @1    :Data;
}


catalog.capnp: give safe defaults for unions

using Cxx = import "/third_party/capnproto/c++/src/capnp/c++.capnp";
using Go = import "/third_party/golang/capnproto/std/go.capnp";

@0x88881ae7af33bcb5;
$Cxx.namespace("mcm");
$Go.package("catalog");
$Go.import("github.com/zombiezen/mcm/catalog");

struct Catalog {
  # The root struct in a catalog file.

  resources @0 :List(Resource);
}

using ResourceId = UInt64;

struct Resource {
  id @0 :ResourceId $Go.name("ID");
  # The resource's identifier, used for dependencies.
  # The identifier should be unique within a catalog.

  comment @1 :Text;
  # An optional human-readable description of the resource for use in
  # error and progress messages.

  dependencies @2 :List(ResourceId);
  # Resources that must be applied before this resource can be applied.

  union {
    noop @3 :Void;
    # Does nothing.  Mainly to give the resource a safe default.

    file @4 :File;
    exec @5 :Exec;
  }
}

struct File @0x8dc4ac52b2962163 {
  # An entry on the filesystem.

  path @0 :Text;
  # An absolute OS-specific file path.

  union {
    plain :group {
      content @1 :Data;
      # Byte content of the file.  If null, then file content is
      # untouched by the executor, but it is an error if the file does
      # not exist.

      mode @2 :Mode;
    }
    directory :group {
      mode @3 :Mode;
    }

    absent @4 :Void;
  }

  struct Mode {
    user @0 :UserRef;
    group @1 :GroupRef;
  }
}

struct UserRef {
  # A reference to a OS user.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct GroupRef {
  # A reference to an OS group.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct Exec @0x984c97311006f1ca {
  # An execution of an arbitrary program.

  struct Command {
    # An individual program invocation.

    union {
      argv @0 :List(Text);
      # A list of arguments as passed to exec.
      # There must be at least one argument, which must be an absolute
      # path to the executable.

      bash @1 :Text;
      # A script as passed to bash.
    }

    struct EnvVar {
      # A single environment variable.

      name @0 :Text;
      value @1 :Text;
    }

    environment @2 :List(EnvVar);
    # The subprocess's environment.
    # An empty or null list is an empty environment.

    workingDirectory @3 :Text;
    # The subprocess's working directory.
    # An empty or null string is the root.
  }

  command @0 :Command;
  # Command to run if the condition is met.

  condition :union {
    always @1 :Void;
    # Command will always be run.  Used if the command is idempotent.
    onlyIf @2 :Command;
    # Command will be run only if another command returns a successful exit code.
    # It is assumed that this command does not do anything destructive and may be run multiple times.
    unless @3 :Command;
    # Command will be run only if another command returns a failure exit code.
    # It is assumed that this command does not do anything destructive and may be run multiple times.
    fileAbsent @4 :Text;
    # Command will be run only if the OS file path does not exist.
  }
}

using Cxx = import "/third_party/capnproto/c++/src/capnp/c++.capnp";
using Go = import "/third_party/golang/capnproto/std/go.capnp";

@0x88881ae7af33bcb5;
$Cxx.namespace("mcm");
$Go.package("catalog");
$Go.import("github.com/zombiezen/mcm/catalog");

struct Catalog {
  # The root struct in a catalog file.

  resources @0 :List(Resource);
}

using ResourceId = UInt64;

struct Resource {
  id @0 :ResourceId $Go.name("ID");
  # The resource's identifier, used for dependencies.
  # The identifier should be unique within a catalog.

  comment @3 :Text;
  # An optional human-readable description of the resource for use in
  # error and progress messages.

  dependencies @1 :List(ResourceId);
  # Resources that must be applied before this resource can be applied.

  union {
    file @2 :File;
    exec @4 :Exec;
  }
}

struct File @0x8dc4ac52b2962163 {
  # An entry on the filesystem.

  path @0 :Text;
  # An absolute OS-specific file path.

  union {
    absent @1 :Void;
    plain :group {
      content @2 :Data;
      # Byte content of the file.  If null, then file content is
      # untouched by the capo, but it is an error if the file does not
      # exist.

      mode @3 :Mode;
    }
    directory :group {
      mode @4 :Mode;
    }
  }

  struct Mode {
    user @0 :UserRef;
    group @1 :GroupRef;
  }
}

struct UserRef {
  # A reference to a OS user.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct GroupRef {
  # A reference to an OS group.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct Exec @0x984c97311006f1ca {
  # An execution of an arbitrary program.

  struct Command {
    # An individual program invocation.

    union {
      argv @0 :List(Text);
      # A list of arguments as passed to exec.
      # There must be at least one argument, which must be an absolute
      # path to the executable.

      bash @1 :Text;
      # A script as passed to bash.
    }

    struct EnvVar {
      # A single environment variable.

      name @0 :Text;
      value @1 :Text;
    }

    environment @2 :List(EnvVar);
    # The subprocess's environment.
    # An empty or null list is an empty environment.

    workingDirectory @3 :Text;
    # The subprocess's working directory.
    # An empty or null string is the root.
  }

  command @0 :Command;
  # Command to run if the condition is met.

  condition :union {
    always @1 :Void;
    # Command will always be run.  Used if the command is idempotent.
    onlyIf @2 :Command;
    # Command will be run only if another command returns a successful exit code.
    # It is assumed that this command does not do anything destructive and may be run multiple times.
    unless @3 :Command;
    # Command will be run only if another command returns a failure exit code.
    # It is assumed that this command does not do anything destructive and may be run multiple times.
    fileAbsent @4 :Text;
    # Command will be run only if the OS file path does not exist.
  }
}


Use absolute capnp import path

Use absolute capnp import path

@0xb639caa166140b0f;

using import "/nupic/encoders/scalar.capnp".ScalarEncoderProto;

# Next ID: 5
struct CategoryEncoderProto {

  # Next ID: 2
  struct CategoryMapping {
    index @0 :UInt32;
    category @1 :Text;
  }

  width @0 :UInt32;
  indexToCategory @1 :List(CategoryMapping);
  name @2 :Text;
  verbosity @3 :UInt8;
  encoder @4 :ScalarEncoderProto;
}

@0xb639caa166140b0f;

using import "scalar.capnp".ScalarEncoderProto;

# Next ID: 5
struct CategoryEncoderProto {

  # Next ID: 2
  struct CategoryMapping {
    index @0 :UInt32;
    category @1 :Text;
  }

  width @0 :UInt32;
  indexToCategory @1 :List(CategoryMapping);
  name @2 :Text;
  verbosity @3 :UInt8;
  encoder @4 :ScalarEncoderProto;
}


Clarify documentation re: filename arguments.

Thanks to @kentonv for pointing out that this was ambiguous.

@0xe91f231103c0780e;
# This file specifies a schema that sandstorm grains may use to share files
# and directories with one another.
#
# We follow the suggested conventions for doing requests/offers. Any of the
# interfaces in this file may be requested or offered; use the interface id
# as the tag, and leave the value null.
#
# NOTE: this is *unstable*. Backwards-incompatible changes may be made to this
# schema until we settle on a final-ish design.

# General notes:
#
# * All file names that appear in the API are *single* path segments --
#   implementations of these interfaces must not interpret multi-part paths,
#   and must throw exceptions when given filenames containing slashes.
# * The filenames "", "." and ".." are illegal, and implementations must
#   throw an exception if given one of these. Note that ".." in particular
#   is very capability-unfriendly; traversing to a parent directory is very
#   purposfully not facilitated by the API.

using Util = import "/util.capnp";

# Note to non go users: you can just delete this if you don't want to
# install the go plugin:
using Go = import "/go.capnp";
$Go.package("filesystem");
$Go.import("zenhack.net/go/sandstorm-filesystem/filesystem");

interface Node @0x955400781a01b061 {
  # A node in the filesystem. This is either a file or a directory.

  stat @0 () -> (info :StatInfo);
  # Report information about the node.
}

struct StatInfo {
  union {
    dir @0 :Void;
    file :group {
      size @1 :Int64;
    }
  }
  executable @2 :Bool;
  writable @3 :Bool;
}

interface Directory @0xce3039544779e0fc extends(Node) {
  # A (possibly read-only) directory.

  list @0 (stream :Entry.Stream);
  # List the contents of the directory. Entries are pushed into `stream`.
  #
  # `list` will not return until all of the entries have been pushed into
  # `stream` (or an error has occurred).

  struct Entry {
    # Information about a child of a directory.
    name @0 :Text;
    info @1 :StatInfo;

    interface Stream {
      # A stream of directories, for use with `list`, above.
      push @0 (entries :List(Entry));
      done @1 ();
    }
  }

  walk @1 (name :Text) -> (node :Node);
  # Open a file in this directory.
}

interface RwDirectory @0xdffe2836f5c5dffc extends(Directory) {
  # A directory, with write access.

  create @0 (name :Text, executable :Bool) -> (file :RwFile);
  # Create a file in the current directory.

  mkdir @1 (name :Text) -> (dir :RwDirectory);
  # Create a sub-directory in the current directory.

  delete @2 (name :Text);
  # Delete the node in this directory named `name`. If it is a directory,
  # it must be empty.
}

interface File @0xaa5b133d60884bbd extends(Node) {
  # A regular file

  read @0 (startAt :Int64, amount :UInt64, sink :Util.ByteStream);
  # Read `amount` bytes from the file into `sink`, starting at position
  # `startAt`. As a special case, if `amount` is 0, data will be read
  # until the end of the file is reached.
  #
  # If there are fewer than `amount` bytes, available, data will be read
  # until the end of the file.
  #
  # `read` will not return until all of the data has been written into
  # `sink` (or an error has occurred).
}

interface RwFile @0xb4810121539f6e53 extends(File) {
  # A file, with write access.

  write @0 (startAt :Int64) -> (sink :Util.ByteStream);
  # Return a ByteStream that can be used to write data to the file.
  # Writing starts at offset `startAt`. `-1` denotes the end of the file.

  truncate @1 (size :UInt64);
  # Truncate the file to `size` bytes.

  setExec @2 (exec :Bool);
  # Set the executable bit to `exec`.
}

# vim: set ts=2 sw=2 et :

@0xe91f231103c0780e;
# This file specifies a schema that sandstorm grains may use to share files
# and directories with one another.
#
# We follow the suggested conventions for doing requests/offers. Any of the
# interfaces in this file may be requested or offered; use the interface id
# as the tag, and leave the value null.
#
# NOTE: this is *unstable*. Backwards-incompatible changes may be made to this
# schema until we settle on a final-ish design.

using Util = import "/util.capnp";

# Note to non go users: you can just delete this if you don't want to
# install the go plugin:
using Go = import "/go.capnp";
$Go.package("filesystem");
$Go.import("zenhack.net/go/sandstorm-filesystem/filesystem");

interface Node @0x955400781a01b061 {
  # A node in the filesystem. This is either a file or a directory.

  stat @0 () -> (info :StatInfo);
  # Report information about the node.
}

struct StatInfo {
  union {
    dir @0 :Void;
    file :group {
      size @1 :Int64;
    }
  }
  executable @2 :Bool;
  writable @3 :Bool;
}

interface Directory @0xce3039544779e0fc extends(Node) {
  # A (possibly read-only) directory.

  list @0 (stream :Entry.Stream);
  # List the contents of the directory. Entries are pushed into `stream`.
  #
  # `list` will not return until all of the entries have been pushed into
  # `stream` (or an error has occurred).

  struct Entry {
    # Information about a child of a directory.
    name @0 :Text;
    info @1 :StatInfo;

    interface Stream {
      # A stream of directories, for use with `list`, above.
      push @0 (entries :List(Entry));
      done @1 ();
    }
  }

  walk @1 (name :Text) -> (node :Node);
  # Open a file in this directory.
}

interface RwDirectory @0xdffe2836f5c5dffc extends(Directory) {
  # A directory, with write access.

  create @0 (name :Text, executable :Bool) -> (file :RwFile);
  # Create a file in the current directory.

  mkdir @1 (name :Text) -> (dir :RwDirectory);
  # Create a sub-directory in the current directory.

  delete @2 (name :Text);
  # Delete the node in this directory named `name`. If it is a directory,
  # it must be empty.
}

interface File @0xaa5b133d60884bbd extends(Node) {
  # A regular file

  read @0 (startAt :Int64, amount :UInt64, sink :Util.ByteStream);
  # Read `amount` bytes from the file into `sink`, starting at position
  # `startAt`. As a special case, if `amount` is 0, data will be read
  # until the end of the file is reached.
  #
  # If there are fewer than `amount` bytes, available, data will be read
  # until the end of the file.
  #
  # `read` will not return until all of the data has been written into
  # `sink` (or an error has occurred).
}

interface RwFile @0xb4810121539f6e53 extends(File) {
  # A file, with write access.

  write @0 (startAt :Int64) -> (sink :Util.ByteStream);
  # Return a ByteStream that can be used to write data to the file.
  # Writing starts at offset `startAt`. `-1` denotes the end of the file.

  truncate @1 (size :UInt64);
  # Truncate the file to `size` bytes.

  setExec @2 (exec :Bool);
  # Set the executable bit to `exec`.
}

# vim: set ts=2 sw=2 et :


catalog: add Exec.ifDepsChanged condition

# Copyright 2016 The Minimal Configuration Manager Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

using Cxx = import "/third_party/capnproto/c++/src/capnp/c++.capnp";
using Go = import "/third_party/golang/capnproto/std/go.capnp";

@0x88881ae7af33bcb5;
$Cxx.namespace("mcm");
$Go.package("catalog");
$Go.import("github.com/zombiezen/mcm/catalog");

struct Catalog {
  # The root struct in a catalog file.

  resources @0 :List(Resource);
}

using ResourceId = UInt64;

struct Resource {
  id @0 :ResourceId $Go.name("ID");
  # The resource's identifier, used for dependencies.
  # The identifier should be unique within a catalog.

  comment @1 :Text;
  # An optional human-readable description of the resource for use in
  # error and progress messages.

  dependencies @2 :List(ResourceId);
  # Resources that must be applied before this resource can be applied.

  union {
    noop @3 :Void;
    # Does nothing.  Mainly to give the resource a safe default.

    file @4 :File;
    exec @5 :Exec;
  }
}

struct File @0x8dc4ac52b2962163 {
  # An entry on the filesystem.

  path @0 :Text;
  # An absolute OS-specific file path.

  union {
    plain :group {
      content @1 :Data;
      # Byte content of the file.  If null, then file content is
      # untouched by the executor, but it is an error if the file does
      # not exist.

      mode @2 :Mode;
    }
    directory :group {
      mode @3 :Mode;
    }
    symlink :group {
      target @5 :Text;
      # Where the link should point to.  This may be an absolute path or
      # a path relative to the link.
    }

    absent @4 :Void;
  }

  struct Mode {
    user @0 :UserRef;
    group @1 :GroupRef;
  }
}

struct UserRef {
  # A reference to a OS user.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct GroupRef {
  # A reference to an OS group.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct Exec @0x984c97311006f1ca {
  # An execution of an arbitrary program.

  struct Command {
    # An individual program invocation.

    union {
      argv @0 :List(Text);
      # A list of arguments as passed to exec.
      # There must be at least one argument, which must be an absolute
      # path to the executable.

      bash @1 :Text;
      # A script as passed to bash.
    }

    struct EnvVar {
      # A single environment variable.

      name @0 :Text;
      value @1 :Text;
    }

    environment @2 :List(EnvVar);
    # The subprocess's environment.
    # An empty or null list is an empty environment.

    workingDirectory @3 :Text;
    # The subprocess's working directory.
    # An empty or null string is the root.
  }

  command @0 :Command;
  # Command to run if the condition is met.

  condition :union {
    always @1 :Void;
    # Command will always be run.  Used if the command is idempotent.
    onlyIf @2 :Command;
    # Command will be run only if another command returns a successful
    # exit code.  It is assumed that this command does not do anything
    # destructive and may be run multiple times.
    unless @3 :Command;
    # Command will be run only if another command returns a failure exit
    # code.  It is assumed that this command does not do anything
    # destructive and may be run multiple times.
    fileAbsent @4 :Text;
    # Command will be run only if the OS file path does not exist.
    ifDepsChanged @5 :List(ResourceId);
    # Command will be run only if one of the resources listed made a
    # change to the system during application.  It is an error for the
    # list to be empty or for the list to contain IDs that are not in
    # the resource's dependencies list.
  }
}

# Copyright 2016 The Minimal Configuration Manager Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

using Cxx = import "/third_party/capnproto/c++/src/capnp/c++.capnp";
using Go = import "/third_party/golang/capnproto/std/go.capnp";

@0x88881ae7af33bcb5;
$Cxx.namespace("mcm");
$Go.package("catalog");
$Go.import("github.com/zombiezen/mcm/catalog");

struct Catalog {
  # The root struct in a catalog file.

  resources @0 :List(Resource);
}

using ResourceId = UInt64;

struct Resource {
  id @0 :ResourceId $Go.name("ID");
  # The resource's identifier, used for dependencies.
  # The identifier should be unique within a catalog.

  comment @1 :Text;
  # An optional human-readable description of the resource for use in
  # error and progress messages.

  dependencies @2 :List(ResourceId);
  # Resources that must be applied before this resource can be applied.

  union {
    noop @3 :Void;
    # Does nothing.  Mainly to give the resource a safe default.

    file @4 :File;
    exec @5 :Exec;
  }
}

struct File @0x8dc4ac52b2962163 {
  # An entry on the filesystem.

  path @0 :Text;
  # An absolute OS-specific file path.

  union {
    plain :group {
      content @1 :Data;
      # Byte content of the file.  If null, then file content is
      # untouched by the executor, but it is an error if the file does
      # not exist.

      mode @2 :Mode;
    }
    directory :group {
      mode @3 :Mode;
    }
    symlink :group {
      target @5 :Text;
      # Where the link should point to.  This may be an absolute path or
      # a path relative to the link.
    }

    absent @4 :Void;
  }

  struct Mode {
    user @0 :UserRef;
    group @1 :GroupRef;
  }
}

struct UserRef {
  # A reference to a OS user.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct GroupRef {
  # A reference to an OS group.

  union {
    id @0 :Int32;
    name @1 :Text;
  }
}

struct Exec @0x984c97311006f1ca {
  # An execution of an arbitrary program.

  struct Command {
    # An individual program invocation.

    union {
      argv @0 :List(Text);
      # A list of arguments as passed to exec.
      # There must be at least one argument, which must be an absolute
      # path to the executable.

      bash @1 :Text;
      # A script as passed to bash.
    }

    struct EnvVar {
      # A single environment variable.

      name @0 :Text;
      value @1 :Text;
    }

    environment @2 :List(EnvVar);
    # The subprocess's environment.
    # An empty or null list is an empty environment.

    workingDirectory @3 :Text;
    # The subprocess's working directory.
    # An empty or null string is the root.
  }

  command @0 :Command;
  # Command to run if the condition is met.

  condition :union {
    always @1 :Void;
    # Command will always be run.  Used if the command is idempotent.
    onlyIf @2 :Command;
    # Command will be run only if another command returns a successful exit code.
    # It is assumed that this command does not do anything destructive and may be run multiple times.
    unless @3 :Command;
    # Command will be run only if another command returns a failure exit code.
    # It is assumed that this command does not do anything destructive and may be run multiple times.
    fileAbsent @4 :Text;
    # Command will be run only if the OS file path does not exist.
  }
}


generic import, satisfies the compiler

generic import, satisfies the compiler

using Go = import "go.capnp";

$Go.package("capn_test");
$Go.import("go-capnproto/example");

@0x832bcc6686a26d56;

struct Zdate {
  year  @0   :Int16;
  month @1   :UInt8;
  day   @2   :UInt8;
}

struct Zdata {
  data @0 :Data;
}

enum Airport {
  none @0;
  jfk @1;
  lax @2;
  sfo @3;
  luv @4;
  dfw @5;
  test @6;
  # test must be last because we use it to count
  # the number of elements in the Airport enum.
}

struct PlaneBase {
  name       @0: Text;
  homes      @1: List(Airport);
  rating     @2: Int64;
  canFly     @3: Bool;
  capacity   @4: Int64;
  maxSpeed   @5: Float64;
}

struct B737 {
  base @0: PlaneBase;
}

struct A320 {
  base @0: PlaneBase;
}

struct F16 {
  base @0: PlaneBase;
}

# need a struct with at least two pointers to catch certain bugs
struct Regression {
  base     @0: PlaneBase;
  b0       @1: Float64; # intercept
  beta     @2: List(Float64);
  planes   @3: List(Aircraft);
  ymu      @4: Float64; # y-mean in original space
  ysd      @5: Float64; # y-standard deviation in original space
}

struct Aircraft {
  #  so we can restrict
  #  and specify a Plane is required in
  #  certain places.

  union {
    void      @0: Void; # @0 will be the default, so always make @0 a Void.
    b737      @1: B737;
    a320      @2: A320;
    f16       @3: F16;
  }
}

struct Z {
  # Z must contain all types, as this is our
  # runtime type identification. It is a thin shim.

  union {
    void              @0: Void; # always first in any union.
    zz                @1: Z;    # any. fyi, this can't be 'z' alone.

    f64               @2: Float64;
    f32               @3: Float32;

    i64               @4: Int64;
    i32               @5: Int32;
    i16               @6: Int16;
    i8                @7: Int8;

    u64               @8:  UInt64;
    u32               @9:  UInt32;
    u16               @10: UInt16;
    u8                @11: UInt8;

    bool              @12: Bool;
    text              @13: Text;
    blob              @14: Data;

    f64vec            @15: List(Float64);
    f32vec            @16: List(Float32);

    i64vec            @17: List(Int64);
    i32vec            @18: List(Int32);
    i16vec            @19: List(Int16);
    i8vec             @20: List(Int8);

    u64vec            @21: List(UInt64);
    u32vec            @22: List(UInt32);
    u16vec            @23: List(UInt16);
    u8vec             @24: List(UInt8);

    zvec              @25: List(Z);
    zvecvec           @26: List(List(Z));

    zdate             @27: Zdate;
    zdata             @28: Zdata;

    aircraftvec       @29: List(Aircraft);
    aircraft          @30: Aircraft;
    regression        @31: Regression;
    planebase         @32: PlaneBase;
  }
}

using Go = import "go.capnp";

$Go.package("capn_test");
$Go.import("capn_test");

@0x832bcc6686a26d56;

struct Zdate {
  year  @0   :Int16;
  month @1   :UInt8;
  day   @2   :UInt8;
}

struct Zdata {
  data @0 :Data;
}

enum Airport {
  none @0;
  jfk @1;
  lax @2;
  sfo @3;
  luv @4;
  dfw @5;
  test @6;
  # test loc must be last because we use it to count
  # the number of elements in the Airport enum!!
}

struct PlaneBase {
  name       @0: Text;
  homes      @1: List(Airport);
  rating     @2: Int64;
  canFly     @3: Bool;
  capacity   @4: Int64;
  maxSpeed   @5: Float64;
}

struct B737 {
  base @0: PlaneBase;
}

struct A320 {
  base @0: PlaneBase;
}

struct F16 {
  base @0: PlaneBase;
}

# need a struct with at least two pointers to catch certain bugs
struct Regression {
  base     @0: PlaneBase;
  b0       @1: Float64; # intercept
  beta     @2: List(Float64);
  planes   @3: List(Aircraft);
  ymu      @4: Float64; # y-mean in original space
  ysd      @5: Float64; # y-standard deviation in original space
}

struct Aircraft {
  #  so we can restrict
  #  and specify a Plane is required in
  #  certain places.

  union {
    void      @0: Void; # @0 will be the default, so always make @0 a Void.
    b737      @1: B737;
    a320      @2: A320;
    f16       @3: F16;
  }
}

struct Z {
  # Z must contain all types, as this is our
  # runtime type identification. It is a thin shim.

  union {
    void              @0: Void; # always first in any union.
    zz                @1: Z;    # any. fyi, this can't be 'z' alone.

    f64               @2: Float64;
    f32               @3: Float32;

    i64               @4: Int64;
    i32               @5: Int32;
    i16               @6: Int16;
    i8                @7: Int8;

    u64               @8:  UInt64;
    u32               @9:  UInt32;
    u16               @10: UInt16;
    u8                @11: UInt8;

    bool              @12: Bool;
    text              @13: Text;
    blob              @14: Data;

    f64vec            @15: List(Float64);
    f32vec            @16: List(Float32);

    i64vec            @17: List(Int64);
    i32vec            @18: List(Int32);
    i16vec            @19: List(Int16);
    i8vec             @20: List(Int8);

    u64vec            @21: List(UInt64);
    u32vec            @22: List(UInt32);
    u16vec            @23: List(UInt16);
    u8vec             @24: List(UInt8);

    zvec              @25: List(Z);
    zvecvec           @26: List(List(Z));

    zdate             @27: Zdate;
    zdata             @28: Zdata;

    aircraftvec       @29: List(Aircraft);
    aircraft          @30: Aircraft;
    regression        @31: Regression;
    planebase         @32: PlaneBase;
  }
}


Problem: travis failed deliberately, but this is obviously incorrect

Solution: finally make it pass

@0xda7d72d8f4b3c0c1;

using Test = import "../../src/schema/test.capnp";
using Op = import "../../src/schema/opcodes.capnp";
using Hierarchy = import "../../src/schema/hierarchy.capnp";

const all: Hierarchy.Tests = (
  name = "add",
  tests = [ .add1, .add2 ]
);

const add1: Test.InputOutput = (
  name = "add1",
  inputOutput = (
    input = (
      gas = 314159,
      code = [ Op.STOP, Op.STOP ],
      data = [ Op.STOP, Op.STOP ]
    ),
    output = (
      gas = 314159,
      code = [ Op.ADD, Op.LT, Op.GT, Op.GT ]
    )
  ),
  expectedOutput = (
    gas = 314159,
    code = [ Op.ADD, Op.LT, Op.GT, Op.GT ]
  )
);

const add2: Test.InputOutput = (
  name = "add2",
  inputOutput = (
    input = (
      gas = 314159,
      code = [ Op.STOP, Op.STOP ],
      data = [ Op.STOP, Op.STOP ]
    ),
    output = (
      gas = 314159,
      code = [ Op.STOP, Op.STOP ]
    )
  ),
  expectedOutput = (
    gas = 314159,
    code = [ Op.STOP, Op.STOP]
  )
);

@0xda7d72d8f4b3c0c1;

using Test = import "../../src/schema/test.capnp";
using Op = import "../../src/schema/opcodes.capnp";
using Hierarchy = import "../../src/schema/hierarchy.capnp";

const all: Hierarchy.Tests = (
  name = "add",
  tests = [ .add1, .add2 ]
);

const add1: Test.InputOutput = (
  name = "add1",
  inputOutput = (
    input = (
      gas = 314159,
      code = [ Op.STOP, Op.STOP ],
      data = [ Op.STOP, Op.STOP ]
    ),
    output = (
      gas = 314159,
      code = [ Op.ADD, Op.LT, Op.GT, Op.GT ]
    )
  ),
  expectedOutput = (
    gas = 314159,
    code = [ Op.ADD, Op.LT, Op.GT, Op.GT ]
  )
);

const add2: Test.InputOutput = (
  name = "add2",
  inputOutput = (
    input = (
      gas = 314159,
      code = [ Op.STOP, Op.STOP ],
      data = [ Op.STOP, Op.STOP ]
    ),
    output = (
      gas = 314159,
      code = [ Op.STOP, Op.STOP ]
    )
  ),
  expectedOutput = (
    gas = 314158,
    code = [ Op.STOP, Op.GT]
  )
);


adding visual & communication structs to the BotTransmission union

@0xca7b62e1bed2bc72;

using Cxx = import "/capnp/c++.capnp";
$Cxx.namespace("robocup2Dsim::bcprotocol");

using Control = import "control.capnp";
using Error = import "/core/error.capnp";
using Info = import "info.capnp";
using Sensor = import "sensor.capnp";

struct BotTransmission
{
    union
    {
	catch @0 :Control.CatchAction;
	dash @1 :Control.DashAction;
	kick @2 :Control.KickAction;
	turnBody @3 :Control.TurnBodyAction;
	turnHead @4 :Control.TurnHeadAction;
	scoreQuery @5 :Info.ScoreQuery;
	timeQuery @6 :Info.TimeQuery;
    }
}

struct ClientTransmission
{
    union
    {
	unknownMsg @0 :Error.UnknownMsgError;
	malformedMsg @1 :Error.MalformedMsgError;
	scoreResult @2 :Info.ScoreResult;
	timeResult @3 :Info.TimeResult;
	communication @4 :Sensor.Communication;
	visual @5 :Sensor.Visual;
    }
}

@0xca7b62e1bed2bc72;

using Cxx = import "/capnp/c++.capnp";
$Cxx.namespace("robocup2Dsim::bcprotocol");

using Control = import "control.capnp";
using Error = import "/core/error.capnp";
using Info = import "info.capnp";

struct BotTransmission
{
    union
    {
	catch @0 :Control.CatchAction;
	dash @1 :Control.DashAction;
	kick @2 :Control.KickAction;
	turnBody @3 :Control.TurnBodyAction;
	turnHead @4 :Control.TurnHeadAction;
	scoreQuery @5 :Info.ScoreQuery;
	timeQuery @6 :Info.TimeQuery;
    }
}

struct ClientTransmission
{
    union
    {
	unknownMsg @0 :Error.UnknownMsgError;
	malformedMsg @1 :Error.MalformedMsgError;
	scoreResult @2 :Info.ScoreResult;
	timeResult @3 :Info.TimeResult;
    }
}


New version in Sandstorm file.

New version in Sandstorm file.

@0xb0032512fca90cd9;

using Spk = import "/sandstorm/package.capnp";
# This imports:
#   $SANDSTORM_HOME/latest/usr/include/sandstorm/package.capnp
# Check out that file to see the full, documented package definition format.

const pkgdef :Spk.PackageDefinition = (
  # The package definition. Note that the spk tool looks specifically for the
  # "pkgdef" constant.

  id = "uws252ya9mep4t77tevn85333xzsgrpgth8q4y1rhknn1hammw70",
  # Your app ID is actually its public key. The private key was placed in
  # your keyring. All updates must be signed with the same key.

  manifest = (
    appTitle = (defaultText = "Firefly III"),
    appVersion = 8,
    appMarketingVersion = (defaultText = "4.7.0"),

    actions = [
      # Define your "new document" handlers here.
      ( nounPhrase = (defaultText = "administration"),
        command = .myCommand
        # The command to run when starting for the first time. (".myCommand"
        # is just a constant defined at the bottom of the file.)
      )
    ],

    continueCommand = .myCommand,
    # This is the command called to start your app back up after it has been
    # shut down for inactivity. Here we're using the same command as for
    # starting a new instance, but you could use different commands for each
    # case.

    metadata = (
         icons = (
        appGrid = (png = (dpi1x = embed "app-graphics/firefly-iii-128.png")),
        grain = (png = (dpi1x = embed "app-graphics/firefly-iii-24.png",
                        dpi2x = embed "app-graphics/firefly-iii-48.png")),
        market = (png = (dpi1x = embed "app-graphics/firefly-iii-150.png"))
      ),

      website = "https://firefly-iii.org/",
      codeUrl = "https://github.com/firefly-iii/firefly-iii",
      license = (openSource = gpl3),
      # The license this package is distributed under.  See
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#license

      categories = [productivity],
      # A list of categories/genres to which this app belongs, sorted with best fit first.
      # See the list of categories at
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#categories

      author = (
        contactEmail = "thegrumpydictator@gmail.com",
        pgpSignature = embed "pgp-signature",
      ),

      pgpKeyring = embed "pgp-keyring",
      description = (defaultText = embed "description.md"),
      shortDescription = (defaultText = "Financial management"),
      screenshots = [
        # Screenshots to use for marketing purposes.  Examples below.
        # Sizes are given in device-independent pixels, so if you took these
        # screenshots on a Retina-style high DPI screen, divide each dimension by two.

        (width = 1291, height = 800, png = embed "screenshots/screenshot-1.png"),
        (width = 1291, height = 800, png = embed "screenshots/screenshot-2.png"),
        (width = 1291, height = 800, png = embed "screenshots/screenshot-3.png"),

      ],
      changeLog = (defaultText = embed "changelog.md"),
    ),
  ),

  sourceMap = (
    # Here we defined where to look for files to copy into your package. The
    # `spk dev` command actually figures out what files your app needs
    # automatically by running it on a FUSE filesystem. So, the mappings
    # here are only to tell it where to find files that the app wants.
    searchPath = [
      ( sourcePath = "." ),  # Search this directory first.
      ( sourcePath = "/",    # Then search the system root directory.
        hidePaths = [ "home", "proc", "sys",
                      "etc/passwd", "etc/hosts", "etc/host.conf",
                      "etc/nsswitch.conf", "etc/resolv.conf" ]
        # You probably don't want the app pulling files from these places,
        # so we hide them. Note that /dev, /var, and /tmp are implicitly
        # hidden because Sandstorm itself provides them.
      )
    ]
  ),

  fileList = "sandstorm-files.list",
  # `spk dev` will write a list of all the files your app uses to this file.
  # You should review it later, before shipping your app.

  alwaysInclude = ["opt/app/app","opt/app/bootstrap","opt/app/config","opt/app/database","opt/app/public","opt/app/resources","opt/app/routes","opt/app/vendor"],
  # Fill this list with more names of files or directories that should be
  # included in your package, even if not listed in sandstorm-files.list.
  # Use this to force-include stuff that you know you need but which may
  # not have been detected as a dependency during `spk dev`. If you list
  # a directory here, its entire contents will be included recursively.

  #bridgeConfig = (
  #  # Used for integrating permissions and roles into the Sandstorm shell
  #  # and for sandstorm-http-bridge to pass to your app.
  #  # Uncomment this block and adjust the permissions and roles to make
  #  # sense for your app.
  #  # For more information, see high-level documentation at
  #  # https://docs.sandstorm.io/en/latest/developing/auth/
  #  # and advanced details in the "BridgeConfig" section of
  #  # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp
  #  viewInfo = (
  #    # For details on the viewInfo field, consult "ViewInfo" in
  #    # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp
  #
  #    permissions = [
  #    # Permissions which a user may or may not possess.  A user's current
  #    # permissions are passed to the app as a comma-separated list of `name`
  #    # fields in the X-Sandstorm-Permissions header with each request.
  #    #
  #    # IMPORTANT: only ever append to this list!  Reordering or removing fields
  #    # will change behavior and permissions for existing grains!  To deprecate a
  #    # permission, or for more information, see "PermissionDef" in
  #    # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp
  #      (
  #        name = "editor",
  #        # Name of the permission, used as an identifier for the permission in cases where string
  #        # names are preferred.  Used in sandstorm-http-bridge's X-Sandstorm-Permissions HTTP header.
  #
  #        title = (defaultText = "editor"),
  #        # Display name of the permission, e.g. to display in a checklist of permissions
  #        # that may be assigned when sharing.
  #
  #        description = (defaultText = "grants ability to modify data"),
  #        # Prose describing what this role means, suitable for a tool tip or similar help text.
  #      ),
  #    ],
  #    roles = [
  #      # Roles are logical collections of permissions.  For instance, your app may have
  #      # a "viewer" role and an "editor" role
  #      (
  #        title = (defaultText = "editor"),
  #        # Name of the role.  Shown in the Sandstorm UI to indicate which users have which roles.
  #
  #        permissions  = [true],
  #        # An array indicating which permissions this role carries.
  #        # It should be the same length as the permissions array in
  #        # viewInfo, and the order of the lists must match.
  #
  #        verbPhrase = (defaultText = "can make changes to the document"),
  #        # Brief explanatory text to show in the sharing UI indicating
  #        # what a user assigned this role will be able to do with the grain.
  #
  #        description = (defaultText = "editors may view all site data and change settings."),
  #        # Prose describing what this role means, suitable for a tool tip or similar help text.
  #      ),
  #      (
  #        title = (defaultText = "viewer"),
  #        permissions  = [false],
  #        verbPhrase = (defaultText = "can view the document"),
  #        description = (defaultText = "viewers may view what other users have written."),
  #      ),
  #    ],
  #  ),
  #  #apiPath = "/api",
  #  # Apps can export an API to the world.  The API is to be used primarily by Javascript
  #  # code and native apps, so it can't serve out regular HTML to browsers.  If a request
  #  # comes in to your app's API, sandstorm-http-bridge will prefix the request's path with
  #  # this string, if specified.
  #),
);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/sandstorm-http-bridge", "8000", "--", "/bin/bash", "/opt/app/.sandstorm/launcher.sh"],
  environ = [
    # Note that this defines the *entire* environment seen by your app.
    (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin"),
    (key = "SANDSTORM", value = "1"),
    # Export SANDSTORM=1 into the environment, so that apps running within Sandstorm
    # can detect if $SANDSTORM="1" at runtime, switching UI and/or backend to use
    # the app's Sandstorm-specific integration code.
  ]
);

@0xb0032512fca90cd9;

using Spk = import "/sandstorm/package.capnp";
# This imports:
#   $SANDSTORM_HOME/latest/usr/include/sandstorm/package.capnp
# Check out that file to see the full, documented package definition format.

const pkgdef :Spk.PackageDefinition = (
  # The package definition. Note that the spk tool looks specifically for the
  # "pkgdef" constant.

  id = "uws252ya9mep4t77tevn85333xzsgrpgth8q4y1rhknn1hammw70",
  # Your app ID is actually its public key. The private key was placed in
  # your keyring. All updates must be signed with the same key.

  manifest = (
    appTitle = (defaultText = "Firefly III"),
    appVersion = 7,
    appMarketingVersion = (defaultText = "4.6.13"),

    actions = [
      # Define your "new document" handlers here.
      ( nounPhrase = (defaultText = "administration"),
        command = .myCommand
        # The command to run when starting for the first time. (".myCommand"
        # is just a constant defined at the bottom of the file.)
      )
    ],

    continueCommand = .myCommand,
    # This is the command called to start your app back up after it has been
    # shut down for inactivity. Here we're using the same command as for
    # starting a new instance, but you could use different commands for each
    # case.

    metadata = (
         icons = (
        appGrid = (png = (dpi1x = embed "app-graphics/firefly-iii-128.png")),
        grain = (png = (dpi1x = embed "app-graphics/firefly-iii-24.png",
                        dpi2x = embed "app-graphics/firefly-iii-48.png")),
        market = (png = (dpi1x = embed "app-graphics/firefly-iii-150.png"))
      ),

      website = "https://firefly-iii.org/",
      codeUrl = "https://github.com/firefly-iii/firefly-iii",
      license = (openSource = gpl3),
      # The license this package is distributed under.  See
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#license

      categories = [productivity],
      # A list of categories/genres to which this app belongs, sorted with best fit first.
      # See the list of categories at
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#categories

      author = (
        contactEmail = "thegrumpydictator@gmail.com",
        pgpSignature = embed "pgp-signature",
      ),

      pgpKeyring = embed "pgp-keyring",
      description = (defaultText = embed "description.md"),
      shortDescription = (defaultText = "Financial management"),
      screenshots = [
        # Screenshots to use for marketing purposes.  Examples below.
        # Sizes are given in device-independent pixels, so if you took these
        # screenshots on a Retina-style high DPI screen, divide each dimension by two.

        (width = 1291, height = 800, png = embed "screenshots/screenshot-1.png"),
        (width = 1291, height = 800, png = embed "screenshots/screenshot-2.png"),
        (width = 1291, height = 800, png = embed "screenshots/screenshot-3.png"),

      ],
      changeLog = (defaultText = embed "changelog.md"),
    ),
  ),

  sourceMap = (
    # Here we defined where to look for files to copy into your package. The
    # `spk dev` command actually figures out what files your app needs
    # automatically by running it on a FUSE filesystem. So, the mappings
    # here are only to tell it where to find files that the app wants.
    searchPath = [
      ( sourcePath = "." ),  # Search this directory first.
      ( sourcePath = "/",    # Then search the system root directory.
        hidePaths = [ "home", "proc", "sys",
                      "etc/passwd", "etc/hosts", "etc/host.conf",
                      "etc/nsswitch.conf", "etc/resolv.conf" ]
        # You probably don't want the app pulling files from these places,
        # so we hide them. Note that /dev, /var, and /tmp are implicitly
        # hidden because Sandstorm itself provides them.
      )
    ]
  ),

  fileList = "sandstorm-files.list",
  # `spk dev` will write a list of all the files your app uses to this file.
  # You should review it later, before shipping your app.

  alwaysInclude = ["opt/app/app","opt/app/bootstrap","opt/app/config","opt/app/database","opt/app/public","opt/app/resources","opt/app/routes","opt/app/vendor"],
  # Fill this list with more names of files or directories that should be
  # included in your package, even if not listed in sandstorm-files.list.
  # Use this to force-include stuff that you know you need but which may
  # not have been detected as a dependency during `spk dev`. If you list
  # a directory here, its entire contents will be included recursively.

  #bridgeConfig = (
  #  # Used for integrating permissions and roles into the Sandstorm shell
  #  # and for sandstorm-http-bridge to pass to your app.
  #  # Uncomment this block and adjust the permissions and roles to make
  #  # sense for your app.
  #  # For more information, see high-level documentation at
  #  # https://docs.sandstorm.io/en/latest/developing/auth/
  #  # and advanced details in the "BridgeConfig" section of
  #  # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp
  #  viewInfo = (
  #    # For details on the viewInfo field, consult "ViewInfo" in
  #    # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp
  #
  #    permissions = [
  #    # Permissions which a user may or may not possess.  A user's current
  #    # permissions are passed to the app as a comma-separated list of `name`
  #    # fields in the X-Sandstorm-Permissions header with each request.
  #    #
  #    # IMPORTANT: only ever append to this list!  Reordering or removing fields
  #    # will change behavior and permissions for existing grains!  To deprecate a
  #    # permission, or for more information, see "PermissionDef" in
  #    # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp
  #      (
  #        name = "editor",
  #        # Name of the permission, used as an identifier for the permission in cases where string
  #        # names are preferred.  Used in sandstorm-http-bridge's X-Sandstorm-Permissions HTTP header.
  #
  #        title = (defaultText = "editor"),
  #        # Display name of the permission, e.g. to display in a checklist of permissions
  #        # that may be assigned when sharing.
  #
  #        description = (defaultText = "grants ability to modify data"),
  #        # Prose describing what this role means, suitable for a tool tip or similar help text.
  #      ),
  #    ],
  #    roles = [
  #      # Roles are logical collections of permissions.  For instance, your app may have
  #      # a "viewer" role and an "editor" role
  #      (
  #        title = (defaultText = "editor"),
  #        # Name of the role.  Shown in the Sandstorm UI to indicate which users have which roles.
  #
  #        permissions  = [true],
  #        # An array indicating which permissions this role carries.
  #        # It should be the same length as the permissions array in
  #        # viewInfo, and the order of the lists must match.
  #
  #        verbPhrase = (defaultText = "can make changes to the document"),
  #        # Brief explanatory text to show in the sharing UI indicating
  #        # what a user assigned this role will be able to do with the grain.
  #
  #        description = (defaultText = "editors may view all site data and change settings."),
  #        # Prose describing what this role means, suitable for a tool tip or similar help text.
  #      ),
  #      (
  #        title = (defaultText = "viewer"),
  #        permissions  = [false],
  #        verbPhrase = (defaultText = "can view the document"),
  #        description = (defaultText = "viewers may view what other users have written."),
  #      ),
  #    ],
  #  ),
  #  #apiPath = "/api",
  #  # Apps can export an API to the world.  The API is to be used primarily by Javascript
  #  # code and native apps, so it can't serve out regular HTML to browsers.  If a request
  #  # comes in to your app's API, sandstorm-http-bridge will prefix the request's path with
  #  # this string, if specified.
  #),
);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/sandstorm-http-bridge", "8000", "--", "/bin/bash", "/opt/app/.sandstorm/launcher.sh"],
  environ = [
    # Note that this defines the *entire* environment seen by your app.
    (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin"),
    (key = "SANDSTORM", value = "1"),
    # Export SANDSTORM=1 into the environment, so that apps running within Sandstorm
    # can detect if $SANDSTORM="1" at runtime, switching UI and/or backend to use
    # the app's Sandstorm-specific integration code.
  ]
);


Schema: add a bit more to the docs

Schema: add a bit more to the docs

@0xe91f231103c0780e;
# This file specifies a schema that sandstorm grains may use to share files
# and directories with one another.
#
# We follow the suggested conventions for doing requests/offers. Any of the
# interfaces in this file may be requested or offered; use the interface id
# as the tag, and leave the value null.
#
# NOTE: this is *unstable*. Backwards-incompatible changes may be made to this
# schema until we settle on a final-ish design.

using Util = import "/util.capnp";

# Note to non go users: you can just delete this if you don't want to
# install the go plugin:
using Go = import "/go.capnp";
$Go.package("filesystem");
$Go.import("zenhack.net/go/sandstorm-filesystem");

interface Node @0x955400781a01b061 {
  # A node in the filesystem. This is either a file or a directory.

  stat @0 () -> (info :StatInfo);
  # Report information about the node.
}

struct StatInfo {
  union {
    dir @0 :Void;
    file :group {
      size @1 :Int64;
    }
  }
  executable @2 :Bool;
  writable @3 :Bool;
}

interface Directory @0xce3039544779e0fc extends(Node) {
  # A (possibly read-only) directory.

  list @0 (stream :Entry.Stream) -> (cancel :Util.Handle);
  # List the contents of the directory. Entries are pushed into `stream`.
  # The returned handle may be dropped to request canceling the stream.

  struct Entry {
    # Information about a child of a directory.
    name @0 :Text;
    info @1 :StatInfo;

    interface Stream {
      # A stream of directories, for use with `list`, above.
      push @0 (entries :List(Entry));
      done @1 ();
    }
  }

  walk @1 (name :Text) -> (node :Node);
  # Open a file in this directory.
}

interface RwDirectory @0xdffe2836f5c5dffc extends(Directory) {
  # A directory, with write access.

  create @0 (name :Text, executable :Bool) -> (file :RwFile);
  # Create a file in the current directory.

  mkdir @1 (name :Text) -> (dir :RwDirectory);
  # Create a sub-directory in the current directory.

  delete @2 (name :Text);
  # Delete the node in this directory named `name`. If it is a directory,
  # it must be empty.
}

interface File @0xaa5b133d60884bbd extends(Node) {
  # A regular file

  read @0 (startAt :Int64, amount :UInt64, sink :Util.ByteStream)
    -> (cancel :Util.Handle);
  # Read `amount` bytes from the file into `sink`, starting at position
  # `startAt`. As a special case, if `amount` is 0, data will be read
  # until the end of the file is reached.
  #
  # If there are fewer than `amount` bytes, available, data will be read
  # until the end of the file.
  #
  # Dropping the returned handle can be used to request that the transfer
  # be canceled.
  #
  # `read` will not return until all of the data has been written into
  # `sink` (or an error has occurred).
}

interface RwFile @0xb4810121539f6e53 extends(File) {
  # A file, with write access.

  write @0 (startAt :Int64, cancel :Util.Handle)
    -> (sink :Util.ByteStream);
  # Return a ByteStream that can be used to write data to the file.
  # Writing starts at offset `startAt`. `-1` denotes the end of the file.
  # `cancel` may be used be the callee to request that streaming be stopped.

  truncate @1 (size :UInt64);
  # Truncate the file to `size` bytes.

  setExec @2 (exec :Bool);
  # Set the executable bit to `exec`.
}

# vim: set ts=2 sw=2 et :

@0xe91f231103c0780e;
# This file specifies a schema that sandstorm grains may use to share files
# and directories with one another.
#
# We follow the suggested conventions for doing requests/offers. Any of the
# interfaces in this file may be requested or offered; use the interface id
# as the tag, and leave the value null.
#
# NOTE: this is *unstable*. Backwards-incompatible changes may be made to this
# schema until we settle on a final-ish design.

using Util = import "/util.capnp";

# Note to non go users: you can just delete this if you don't want to
# install the go plugin:
using Go = import "/go.capnp";
$Go.package("filesystem");
$Go.import("zenhack.net/go/sandstorm-filesystem");

interface Node @0x955400781a01b061 {
  # A node in the filesystem. This is either a file or a directory.

  stat @0 () -> (info :StatInfo);
  # Report information about the node.
}

struct StatInfo {
  union {
    dir @0 :Void;
    file :group {
      size @1 :Int64;
    }
  }
  executable @2 :Bool;
  writable @3 :Bool;
}

interface Directory @0xce3039544779e0fc extends(Node) {
  # A (possibly read-only) directory.

  list @0 (stream :Entry.Stream) -> (cancel :Util.Handle);
  # List the contents of the directory. Entries are pushed into `stream`.
  # The returned handle may be dropped to request canceling the stream.

  struct Entry {
    # Information about a child of a directory.
    name @0 :Text;
    info @1 :StatInfo;

    interface Stream {
      # A stream of directories, for use with `list`, above.
      push @0 (entries :List(Entry));
      done @1 ();
    }
  }

  walk @1 (name :Text) -> (node :Node);
  # Open a file in this directory.
}

interface RwDirectory @0xdffe2836f5c5dffc extends(Directory) {
  # A directory, with write access.

  create @0 (name :Text, executable :Bool) -> (file :RwFile);
  # Create a file in the current directory.

  mkdir @1 (name :Text) -> (dir :RwDirectory);
  # Create a sub-directory in the current directory.

  delete @2 (name :Text);
  # Delete the node in this directory named `name`. If it is a directory,
  # it must be empty.
}

interface File @0xaa5b133d60884bbd extends(Node) {
  # A regular file

  read @0 (startAt :Int64, amount :UInt64, sink :Util.ByteStream)
    -> (cancel :Util.Handle);
  # Read `amount` bytes from the file into `sink`, starting at position
  # `startAt`. As a special case, if `amount` is 0, data will be read
  # until the end of the file is reached.
  #
  # If there are fewer than `amount` bytes, available, data will be read
  # until the end of the file.
  #
  # Dropping the returned handle can be used to request that the transfer
  # be canceled.
}

interface RwFile @0xb4810121539f6e53 extends(File) {
  # A file, with write access.

  write @0 (startAt :Int64, cancel :Util.Handle)
    -> (sink :Util.ByteStream);
  # Return a ByteStream that can be used to write data to the file.
  # Writing starts at offset `startAt`. `-1` denotes the end of the file.

  truncate @1 (size :UInt64);
  # Truncate the file to `size` bytes.

  setExec @2 (exec :Bool);
  # Set the executable bit to `exec`.
}

# vim: set ts=2 sw=2 et :


add short description

add short description

(and bump to 1.0.4)

# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

@0xf432f4735ec7ac78;

using Spk = import "/sandstorm/package.capnp";
# This imports:
#   $SANDSTORM_HOME/latest/usr/include/sandstorm/package.capnp
# Check out that file to see the full, documented package definition format.

const pkgdef :Spk.PackageDefinition = (
  # The package definition. Note that the spk tool looks specifically for the
  # "pkgdef" constant.

  id = "nn7axgy3y8kvd0m1mtk3cwca34t916p5d7m4j1j2e874nuz3t8y0",
  # Your app ID is actually its public key. The private key was placed in
  # your keyring. All updates must be signed with the same key.

  manifest = (
    appTitle = (defaultText = "FileDrop"),

    appVersion = 5,  # Increment this for every release.

    appMarketingVersion = (defaultText = "1.0.4"),
    # Human-readable representation of appVersion. Should match the way you
    # identify versions of your app in documentation and marketing.

    actions = [
      ( title = (defaultText = "New Drop"),
        nounPhrase = (defaultText = "drop"),
        command = .myCommand
      )
    ],

    continueCommand = .myCommand,
    # This is the command called to start your app back up after it has been
    # shut down for inactivity. Here we're using the same command as for
    # starting a new instance, but you could use different commands for each
    # case.

    metadata = (
      icons = (
        appGrid = (svg = embed "icons/icon-128.svg"),
        grain = (svg = embed "icons/icon-24.svg"),
        market = (svg = embed "icons/icon-150.svg"),
        marketBig = (svg = embed "icons/icon-300.svg"),
      ),
      website = "https://github.com/zombiezen/filedrop/",
      codeUrl = "https://github.com/zombiezen/filedrop/",
      license = (openSource = apache2, notices = (defaultText = embed "LICENSE.all")),
      categories = [productivity],
      author = (
        contactEmail = "ross@zombiezen.com",
        pgpSignature = embed "pgp-signature"
      ),
      pgpKeyring = embed "keyring",
      description = (defaultText = embed "description.md"),
      shortDescription = (defaultText = "Drag-n-drop file sharing"),
      screenshots = [(width = 1165, height = 780, png = embed "screenshot.png")],
      changeLog = (defaultText = embed "changelog.md")
    )
  ),

  sourceMap = (
    searchPath = [
      ( sourcePath = "LICENSE.all",
        packagePath = "LICENSE" ),
      ( sourcePath = ".",
        packagePath = "filedrop",
        hidePaths = [".git"]
      ),
      ( sourcePath = "/",
        hidePaths = [ "home", "proc", "sys",
                      "etc/passwd", "etc/hosts", "etc/host.conf",
                      "etc/nsswitch.conf", "etc/resolv.conf",
                      "etc/ld.so.cache" ]
      )
    ]
  ),

  fileList = "sandstorm-files.list",
  # `spk dev` will write a list of all the files your app uses to this file.
  # You should review it later, before shipping your app.

  alwaysInclude = ["LICENSE", "filedrop/third_party/roboto"],
  # Fill this list with more names of files or directories that should be
  # included in your package, even if not listed in sandstorm-files.list.
  # Use this to force-include stuff that you know you need but which may
  # not have been detected as a dependency during `spk dev`. If you list
  # a directory here, its entire contents will be included recursively.

  bridgeConfig = (
    viewInfo = (
      permissions = [
        ( name = "read",
          title = (defaultText = "View Files")
        ),
        # TODO(light): break this apart into creating vs. modifying
        ( name = "write",
          title = (defaultText = "Edit Files")
        ),
        ( name = "delete",
          title = (defaultText = "Delete Files")
        )
      ],
      roles = [
        ( title = (defaultText = "viewer"),
          verbPhrase = (defaultText = "can view"),
          permissions = [true, false, false]
        ),
        ( title = (defaultText = "editor"),
          verbPhrase = (defaultText = "can edit"),
          permissions = [true, true, true]
        )
      ]
    )
  )
);

const myCommand :Spk.Manifest.Command = (
  argv = ["/sandstorm-http-bridge", "8080", "--",
          "/filedrop/filedrop",
          "-address=[::]:8080",
          "-storage=/var/files",
          "-datadir=/filedrop",
          "-sandstorm_acls"],
  environ = [
    (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin")
  ]
);

# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

@0xf432f4735ec7ac78;

using Spk = import "/sandstorm/package.capnp";
# This imports:
#   $SANDSTORM_HOME/latest/usr/include/sandstorm/package.capnp
# Check out that file to see the full, documented package definition format.

const pkgdef :Spk.PackageDefinition = (
  # The package definition. Note that the spk tool looks specifically for the
  # "pkgdef" constant.

  id = "nn7axgy3y8kvd0m1mtk3cwca34t916p5d7m4j1j2e874nuz3t8y0",
  # Your app ID is actually its public key. The private key was placed in
  # your keyring. All updates must be signed with the same key.

  manifest = (
    appTitle = (defaultText = "FileDrop"),

    appVersion = 4,  # Increment this for every release.

    appMarketingVersion = (defaultText = "1.0.3"),
    # Human-readable representation of appVersion. Should match the way you
    # identify versions of your app in documentation and marketing.

    actions = [
      ( title = (defaultText = "New Drop"),
        nounPhrase = (defaultText = "drop"),
        command = .myCommand
      )
    ],

    continueCommand = .myCommand,
    # This is the command called to start your app back up after it has been
    # shut down for inactivity. Here we're using the same command as for
    # starting a new instance, but you could use different commands for each
    # case.

    metadata = (
      icons = (
        appGrid = (svg = embed "icons/icon-128.svg"),
        grain = (svg = embed "icons/icon-24.svg"),
        market = (svg = embed "icons/icon-150.svg"),
        marketBig = (svg = embed "icons/icon-300.svg"),
      ),
      website = "https://github.com/zombiezen/filedrop/",
      codeUrl = "https://github.com/zombiezen/filedrop/",
      license = (openSource = apache2, notices = (defaultText = embed "LICENSE.all")),
      categories = [productivity],
      author = (
        contactEmail = "ross@zombiezen.com",
        pgpSignature = embed "pgp-signature"
      ),
      pgpKeyring = embed "keyring",
      description = (defaultText = embed "description.md"),
      screenshots = [(width = 1165, height = 780, png = embed "screenshot.png")],
      changeLog = (defaultText = embed "changelog.md")
    )
  ),

  sourceMap = (
    searchPath = [
      ( sourcePath = "LICENSE.all",
        packagePath = "LICENSE" ),
      ( sourcePath = ".",
        packagePath = "filedrop",
        hidePaths = [".git"]
      ),
      ( sourcePath = "/",
        hidePaths = [ "home", "proc", "sys",
                      "etc/passwd", "etc/hosts", "etc/host.conf",
                      "etc/nsswitch.conf", "etc/resolv.conf",
                      "etc/ld.so.cache" ]
      )
    ]
  ),

  fileList = "sandstorm-files.list",
  # `spk dev` will write a list of all the files your app uses to this file.
  # You should review it later, before shipping your app.

  alwaysInclude = ["LICENSE", "filedrop/third_party/roboto"],
  # Fill this list with more names of files or directories that should be
  # included in your package, even if not listed in sandstorm-files.list.
  # Use this to force-include stuff that you know you need but which may
  # not have been detected as a dependency during `spk dev`. If you list
  # a directory here, its entire contents will be included recursively.

  bridgeConfig = (
    viewInfo = (
      permissions = [
        ( name = "read",
          title = (defaultText = "View Files")
        ),
        # TODO(light): break this apart into creating vs. modifying
        ( name = "write",
          title = (defaultText = "Edit Files")
        ),
        ( name = "delete",
          title = (defaultText = "Delete Files")
        )
      ],
      roles = [
        ( title = (defaultText = "viewer"),
          verbPhrase = (defaultText = "can view"),
          permissions = [true, false, false]
        ),
        ( title = (defaultText = "editor"),
          verbPhrase = (defaultText = "can edit"),
          permissions = [true, true, true]
        )
      ]
    )
  )
);

const myCommand :Spk.Manifest.Command = (
  argv = ["/sandstorm-http-bridge", "8080", "--",
          "/filedrop/filedrop",
          "-address=[::]:8080",
          "-storage=/var/files",
          "-datadir=/filedrop",
          "-sandstorm_acls"],
  environ = [
    (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin")
  ]
);


Add explicit interface tags and note the convention

@0xe91f231103c0780e;

using Go = import "/go.capnp";
using Util = import "/util.capnp";

$Go.package("filesystem");
$Go.import("zenhack.net/go/sandstorm-filesystem");

# This file specifies a schema that sandstorm grains may use to share files
# and directories with one another.
#
# We follow the suggested conventions for doing requests/offers. Any of the
# interfaces in this file may be requested or offered; use the interface id
# as the tag, and leave the value null.
#
# NOTE: this is *unstable*. Backwards-incompatible changes may be made to this
# schema until we settle on a final-ish design.

interface Node @0x955400781a01b061 {
  # A node in the filesystem. This is either a file or a directory.

  type @0 () -> (type :Type);
  # Report the type of the node.

  enum Type {
    dir @0;
    file @1;
  }

  canWrite @1 () -> (canWrite :Bool);
  # Report whether the node is writable. If it is, it must implement
  # one of the Rw* interfaces below.
}

interface Directory @0xce3039544779e0fc extends(Node) {
  # A (possibly read-only) directory.

  list @0 () -> (list: List(Entry));
  # List the contents of the directory. TODO: we probably want some way
  # to do pagination/otherwise not have to transfer all of the entries at
  # once.

  struct Entry {
    # A child of a directory.
    name @0 :Text;
    file @1 :Node;
  }

  open @1 (name :Text) -> (node :Node);
  # Open a file in this directory.
}

interface RwDirectory @0xdffe2836f5c5dffc extends(Directory) {
  # A directory, with write access.

  create @0 (name :Text, type :Node.Type) -> (node :Node);
  # Create a node named `name` within the directory. `type`
  # indicates what type of node to create. The returned `node`
  # always implements the writable variant of that type.

  delete @1 (name :Text);
  # Delete the node in this directory named `name`.
}

interface File @0xaa5b133d60884bbd extends(Node) {
  # A regular file

  size @0 () -> (size: UInt64);
  # Return the size of the file.

  read @1 (startAt :UInt64, amount :UInt64, sink :Util.ByteStream) ->
    (handle :Util.Handle);
  # Read `amount` bytes from the file into `sink`, starting at position
  # `startAt`. As a special case, if `amount` is 0, data will be read
  # until the end of the file is reached.
  #
  # Dropping the returned handle can be used to request that the transfer
  # be canceled.
}

interface RwFile @0xb4810121539f6e53 extends(File) {
  # A file, with write access.

  write @0 (startAt :UInt64) -> (sink :Util.ByteStream);
  # Return a ByteStream that can be used to write data to the file.
  # Writing starts at offset `startAt`.

  truncate @1 (size :UInt64);
  # Truncate the file to `size` bytes.
}

@0xe91f231103c0780e;

using Go = import "/go.capnp";
using Util = import "/util.capnp";

$Go.package("filesystem");
$Go.import("zenhack.net/go/sandstorm-filesystem");

# This file specifies a schema that sandstorm grains may use to share files
# and directories with one another.
#
# NOTE: this is *unstable*. Backwards-incompatible changes may be made to this
# schema until we settle on a final-ish design.
#
# TODO: document how one does a powerbox offer/request with these.

interface Node {
  # A node in the filesystem. This is either a file or a directory.

  type @0 () -> (type :Type);
  # Report the type of the node.

  enum Type {
    dir @0;
    file @1;
  }

  canWrite @1 () -> (canWrite :Bool);
  # Report whether the node is writable. If it is, it must implement
  # one of the Rw* interfaces below.
}

interface Directory extends(Node) {
  # A (possibly read-only) directory.

  list @0 () -> (list: List(Entry));
  # List the contents of the directory. TODO: we probably want some way
  # to do pagination/otherwise not have to transfer all of the entries at
  # once.

  struct Entry {
    # A child of a directory.
    name @0 :Text;
    file @1 :Node;
  }

  open @1 (name :Text) -> (node :Node);
  # Open a file in this directory.
}

interface RwDirectory extends(Directory) {
  # A directory, with write access.

  create @0 (name :Text, type :Node.Type) -> (node :Node);
  # Create a node named `name` within the directory. `type`
  # indicates what type of node to create. The returned `node`
  # always implements the writable variant of that type.

  delete @1 (name :Text);
  # Delete the node in this directory named `name`.
}

interface File extends(Node) {
  # A regular file

  size @0 () -> (size: UInt64);
  # Return the size of the file.

  read @1 (startAt :UInt64, amount :UInt64, sink :Util.ByteStream) ->
    (handle :Util.Handle);
  # Read `amount` bytes from the file into `sink`, starting at position
  # `startAt`. As a special case, if `amount` is 0, data will be read
  # until the end of the file is reached.
  #
  # Dropping the returned handle can be used to request that the transfer
  # be canceled.
}

interface RwFile extends(File) {
  # A file, with write access.

  write @0 (startAt :UInt64) -> (sink :Util.ByteStream);
  # Return a ByteStream that can be used to write data to the file.
  # Writing starts at offset `startAt`.

  truncate @1 (size :UInt64);
  # Truncate the file to `size` bytes.
}