catalog: document that ID cannot be zero

# 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 and cannot be zero.

  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.
    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.
  }
}


Revise comments following feedback in anticipation of merge

@0xfa7d16f86048a6e4;

# Next ID: 10
struct ScalarEncoderProto {
  w @0 :UInt32;
  minval @1 :Float32;
  maxval @2 :Float32;
  periodic @3 :Bool;
  n @4 :UInt32;
  radius @5 :Float32;
  resolution @6 :Float32;
  name @7 :Text;
  verbosity @8 :UInt8;
  clipInput @9 :Bool;
}

@0xfa7d16f86048a6e4;

struct ScalarEncoderProto {
  # ScalarEncoder() constructor signature

  w @0 :UInt32;
  minval @1 :Float32;
  maxval @2 :Float32;
  periodic @3 :Bool;
  n @4 :UInt32;
  radius @5 :Float32;
  resolution @6 :Float32;
  name @7 :Text;
  verbosity @8 :UInt8;
  clipInput @9 :Bool;
}


fixed typos

fixed typos

@0xca7b62e1bed2bc72;

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

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

struct TransmissionHeader
{
    wantReliable @0 :Bool;
    wantOrdering @1 :Bool;
    unusedA @2 :Bool;
    unusedB @3 :Bool;
    unusedC @4 :Bool;
    unusedD @5 :Bool;
    unusedE @6 :Bool;
    unusedF @7 :Bool;
    channel @8 :Metadata.ChannelId;
    sequence @9 :Metadata.SequenceNumber;
}

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

struct ServerTransmission
{
    header @0 :TransmissionHeader;
    union
    {
	unknownMsg @1 :Error.UnknownMsgError;
	malformedMsg @2 :Error.MalformedMsgError;
	init @3 :Command.InitReply;
	reconnect @4 :Command.ReconnectReply;
	bye @5 :Command.ByeReply;
    }
}

@0xca7b62e1bed2bc72;

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

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

struct TransmissionHeader
{
    wantReliable @0 :Bool;
    wantOrdering @1 :Bool;
    unusedA @2 :Bool;
    unusedB @3 :Bool;
    unusedC @4 :Bool;
    unusedD @5 :Bool;
    unusedE @6 :Bool;
    unusedF @7 :Bool;
    channel @8 :Metadata.channelId;
    sequence @9 :Metadata.SequenceNumber;
}

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

struct ServerTransmission
{
    header @0 :TransmissionHeader
    union
    {
	unknownMsg @1 :Error.UnknownMsgError;
	malformedMsg @2 :Error.MalformedMsgError;
	init @3 :Command.InitReply;
	reconnect @4 :Command.ReconnectReply;
	bye @5 :Command.ByeReply;
    }
}


oops used a duplicate Capn Proto ID

oops used a duplicate Capn Proto ID

@0xabe13ea5f0adf862;

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

using Error = import "/core/error.capnp";
using Metadata = import "/core/metadata.capnp";
using Command = import "command.capnp";
using CoreCommand = import "/core/command.capnp";

struct TransmissionHeader
{
    wantReliable @0 :Bool;
    wantOrdering @1 :Bool;
    unusedA @2 :Bool;
    unusedB @3 :Bool;
    unusedC @4 :Bool;
    unusedD @5 :Bool;
    unusedE @6 :Bool;
    unusedF @7 :Bool;
    channel @8 :Metadata.ChannelId;
    sequence @9 :Metadata.SequenceNumber;
}

struct ClientTransmission
{
    header @0 :TransmissionHeader;
    union
    {
	init @1 :Command.InitRequest;
	control @2 :Void;
    }
}

struct ServerTransmission
{
    header @0 :TransmissionHeader;
    union
    {
	unknownMsg @1 :Error.UnknownMsgError;
	malformedMsg @2 :Error.MalformedMsgError;
	init @3 :Command.InitReply;
	close @4 :CoreCommand.MatchClose;
	abort @5 :CoreCommand.MatchAbort;
    }
}

@0xca7b62e1bed2bc72;

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

using Error = import "/core/error.capnp";
using Metadata = import "/core/metadata.capnp";
using Command = import "command.capnp";
using CoreCommand = import "/core/command.capnp";

struct TransmissionHeader
{
    wantReliable @0 :Bool;
    wantOrdering @1 :Bool;
    unusedA @2 :Bool;
    unusedB @3 :Bool;
    unusedC @4 :Bool;
    unusedD @5 :Bool;
    unusedE @6 :Bool;
    unusedF @7 :Bool;
    channel @8 :Metadata.ChannelId;
    sequence @9 :Metadata.SequenceNumber;
}

struct ClientTransmission
{
    header @0 :TransmissionHeader;
    union
    {
	init @1 :Command.InitRequest;
	control @2 :Void;
    }
}

struct ServerTransmission
{
    header @0 :TransmissionHeader;
    union
    {
	unknownMsg @1 :Error.UnknownMsgError;
	malformedMsg @2 :Error.MalformedMsgError;
	init @3 :Command.InitReply;
	close @4 :CoreCommand.MatchClose;
	abort @5 :CoreCommand.MatchAbort;
    }
}


Bumped ordinal number in date.capnp

Bumped ordinal number in date.capnp

@0x9b23d989c61ef9e6;

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

struct DateEncoderProto {
  name @0 :Text;
  seasonEncoder @1 :ScalarEncoderProto;
  dayOfWeekEncoder @2 :ScalarEncoderProto;
  weekendEncoder @3 :ScalarEncoderProto;
  customDaysEncoder @4 :ScalarEncoderProto;
  holidayEncoder @5 :ScalarEncoderProto;
  timeOfDayEncoder @6 :ScalarEncoderProto;
  hourOfWeekEncoder @6 :ScalarEncoderProto;
}

@0x9b23d989c61ef9e5;

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

struct DateEncoderProto {
  name @0 :Text;
  seasonEncoder @1 :ScalarEncoderProto;
  dayOfWeekEncoder @2 :ScalarEncoderProto;
  weekendEncoder @3 :ScalarEncoderProto;
  customDaysEncoder @4 :ScalarEncoderProto;
  holidayEncoder @5 :ScalarEncoderProto;
  timeOfDayEncoder @6 :ScalarEncoderProto;
  hourOfWeekEncoder @6 :ScalarEncoderProto;
}


trying to get an ask api call working

trying to get an ask api call working

@0xce4c7cd66480f6f2;

interface KillrAnswers {
    ask @0 (i :Text) -> (questionId: Text);
}

struct Question {
    questionId @0 : Text;
    questionText @1 : Text;
}

struct Category {
    categoryId @0 : Text;
}

@0xce4c7cd66480f6f2;

interface KillrAnswers {
    struct Question {
        questionId @0 : Text;
        questionText @1 : Text;
    }

}


Fix SignedCtrlPld comment in capnp schema (#2479)

@0x99440334ec0946a0;
using Go = import "go.capnp";
$Go.package("proto");
$Go.import("github.com/scionproto/scion/go/proto");

struct SignedBlob {
    blob @0 :Data;
    sign @1 :Sign;
}

struct Sign {
    # Signature type. If this is `none`, then the rest of this struct should be ignored.
    type @0 :SignType;
    # Id (e.g. ISD-AS) of signer. Unset if signType is `none`.
    src @1 :Data;
    # Signature over blob, type (represented as a UTF-8 string, e.g.,
    # "ed25519"), src, and timestamp (represented in network-byte order) using
    # signType, created by src. Unset if signType is `none`.
    signature @2 :Data;
    # Signature creation time. Seconds since Unix Epoch.
    timestamp @3 :UInt32;
}

enum SignType {
    none @0;
    ed25519 @1;
}

@0x99440334ec0946a0;
using Go = import "go.capnp";
$Go.package("proto");
$Go.import("github.com/scionproto/scion/go/proto");

struct SignedBlob {
    blob @0 :Data;
    sign @1 :Sign;
}

struct Sign {
    # Signature type. If this is `none`, then the rest of this struct should be ignored.
    type @0 :SignType;
    # Id (e.g. ISD-AS) of signer. Unset if signType is `none`.
    src @1 :Data;
    # Signature over blob, using signType, created by src. Unset if signType is `none`.
    signature @2 :Data;
    # Signature creation time. Seconds since Unix Epoch.
    timestamp @3 :UInt32;
}

enum SignType {
    none @0;
    ed25519 @1;
}


added in a query to discover the team's registration status

@0xc9dafaeac85c954c;

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

using Physics = import "/core/physics.capnp";
using Rule = import "/core/rule.capnp";

struct ScoreQuery { }

struct ScoreResult
{
    time @0 :Physics.NanoSecond;
    ourScore @1 :Rule.Score;
    theirScore @2 :Rule.Score;
}

struct TimeQuery { }

struct TimeResult
{
    time @0 :Physics.NanoSecond;
}

struct RegistrationQuery { }

struct TeamRegistrationStatus
{
    teamName @0 :Text;
    playerCount @1 :UInt8;
}

struct RegistrationResult
{
    startTime @0 :Physics.NanoSecond;
    deadLine @1 :Physics.NanoSecond;
    leftTeam @2 :TeamRegistrationStatus;
    rightTeam @3 :TeamRegistrationStatus;
}

@0xc9dafaeac85c954c;

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

using Physics = import "/core/physics.capnp";
using Rule = import "/core/rule.capnp";

struct ScoreQuery { }

struct ScoreResult
{
    time @0 :Physics.Nanoseconds;
    ourScore @1 :Rule.Score;
    theirScore @2 :Rule.Score;
}

struct TimeQuery { }

struct TimeResult
{
    time @0 :Physics.Nanoseconds;
}


Explicitly namespace holmes

Explicitly namespace holmes

@0xaaef86128cdda946;
using Cxx = import "/capnp/c++.capnp";

$Cxx.namespace("holmes");

interface Holmes {
  # Dynamic value type for use in facts
  struct Val {
    union {
      stringVal @0 :Text;
      addrVal   @1 :UInt64;
      blobVal   @2 :Data;
    }
  }

  # Logical facts
  using FactName = Text;
  struct Fact {
    factName @0 :FactName;
    args     @1 :List(Val);
  }

  # Argument restriction when searching
  struct TemplateVal {
    union {
      exactVal @0 :Val;  #Argument must have this exact value
      unbound  @1 :Void; #Argument is unrestricted
    }
  }

  # FactTemplate to be used as a search query
  struct FactTemplate {
    factName @0 :FactName;
    args     @1 :List(TemplateVal);
  }

  # Callback provided by an analysis
  interface Analysis {
    analyze @0 (premises :List(Fact)) -> (derived :List(Fact));
  }

  # Assert a fact to the server
  set @0 (fact :Fact);

  # Ask the server to search for facts
  derive @1 (target :FactTemplate) -> (facts :List(Fact));

  # Register as an analysis
  analyzer @2 (premises    :List(FactTemplate),
	       analysis    :Analysis);
}

@0xaaef86128cdda946;

interface Holmes {
  # Dynamic value type for use in facts
  struct Val {
    union {
      stringVal @0 :Text;
      addrVal   @1 :UInt64;
      blobVal   @2 :Data;
    }
  }

  # Logical facts
  using FactName = Text;
  struct Fact {
    factName @0 :FactName;
    args     @1 :List(Val);
  }

  # Argument restriction when searching
  struct TemplateVal {
    union {
      exactVal @0 :Val;  #Argument must have this exact value
      unbound  @1 :Void; #Argument is unrestricted
    }
  }

  # FactTemplate to be used as a search query
  struct FactTemplate {
    factName @0 :FactName;
    args     @1 :List(TemplateVal);
  }

  # Callback provided by an analysis
  interface Analysis {
    analyze @0 (premises :List(Fact)) -> (derived :List(Fact));
  }

  # Assert a fact to the server
  set @0 (fact :Fact);

  # Ask the server to search for facts
  derive @1 (target :FactTemplate) -> (facts :List(Fact));

  # Register as an analysis
  analyzer @2 (premises    :List(FactTemplate),
	       analysis    :Analysis);
}


Prepend copyright statement to Cap'n Proto schema.

# Copyright 2014 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.

@0x81f586f4d873f6ac;

struct Snapshot {
	id @0 :Int64;

	familyName @1: Text;
	msg @2 :Text;

	hash @3 :Data;
	treeReference @4 :Data;
}

struct SnapshotList {
	snapshots @0 :List(Snapshot);
}

struct ChunkRef {
	blobId @0 :Data;

	offset @1: Int64;
	length @2: Int64;
}

struct HashRef {
	hash @0 :Data;
	chunkRef @1 :ChunkRef;
}

struct HashRefList {
	hashRefs @0 :List(HashRef);
}


New App Key

New App Key

According to: https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/appid-replacements.capnp

@0xaedf071934889091;

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 = "vxe8awcxvtj6yu0vgjpm1tsaeu7x8v8tfp71tyvnm6ykkephu9q0",
  # 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 = (
    # This manifest is included in your app package to tell Sandstorm
    # about your app.

    appTitle = (defaultText = "Paperwork"),

    appVersion = 7,  # Increment this for every release.

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

    actions = [
      # Define your "new document" handlers here.
      ( title = (defaultText = "New Paperwork"),
        nounPhrase = (defaultText = "note"),
        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 = (svg = embed "app-graphics/paperwork-128.svg"),
         grain = (svg = embed "app-graphics/paperwork-24.svg"),
         market = (svg = embed "app-graphics/paperwork-150.svg"),
       ),

       website = "http://paperwork.rocks/",
       codeUrl = "https://github.com/JamborJan/paperwork",
       license = (openSource = mit),
       categories = [productivity],

       author = (
         contactEmail = "jan@jambor.pro",
         pgpSignature = embed "pgp-signature",
         upstreamAuthor = "Twostairs",
       ),
       pgpKeyring = embed "pgp-keyring",

       description = (defaultText = embed "description.md"),

       screenshots = [
         (width = 448, height = 249, png = embed "sandstorm-screenshot.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 = [],
  # 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 = "admin", title = (defaultText = "admin"),
                      description = (defaultText = "Is the owner.")),
                     (name = "write", title = (defaultText = "write"),
                      description = (defaultText = "Can write.")),
                     (name = "read", title = (defaultText = "read"),
                      description = (defaultText = "Can read."))],
      roles = [(title = (defaultText = "Owner"),
                permissions = [true, true, true],
                verbPhrase = (defaultText = "Is owner, can add & edit notes."),
                default = true),
               (title = (defaultText = "Read & write"),
                permissions = [false, true, true],
                verbPhrase = (defaultText = "Can add & edit notes.")),
               (title = (defaultText = "Read only"),
                permissions = [false, false, true],
                verbPhrase = (defaultText = "Can read existing notes."))]
    )
  )
);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/sandstorm-http-bridge", "8000", "--", "/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 = "HOME", value = "/var")
  ]
);

@0xf808754757003fd7;

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 = "n8cn71407n4mezn7mg0k5kkm21juuphhecc24hdf9kf56zyxm4ah",
  # 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 = (
    # This manifest is included in your app package to tell Sandstorm
    # about your app.

    appTitle = (defaultText = "Paperwork"),

    appVersion = 7,  # Increment this for every release.

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

    actions = [
      # Define your "new document" handlers here.
      ( title = (defaultText = "New Paperwork"),
        nounPhrase = (defaultText = "note"),
        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 = (svg = embed "app-graphics/paperwork-128.svg"),
         grain = (svg = embed "app-graphics/paperwork-24.svg"),
         market = (svg = embed "app-graphics/paperwork-150.svg"),
       ),

       website = "http://paperwork.rocks/",
       codeUrl = "https://github.com/JamborJan/paperwork",
       license = (openSource = mit),
       categories = [productivity],

       author = (
         contactEmail = "jan@jambor.pro",
         pgpSignature = embed "pgp-signature",
         upstreamAuthor = "Twostairs",
       ),
       pgpKeyring = embed "pgp-keyring",

       description = (defaultText = embed "description.md"),

       screenshots = [
         (width = 448, height = 249, png = embed "sandstorm-screenshot.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 = [],
  # 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 = "admin", title = (defaultText = "admin"),
                      description = (defaultText = "Is the owner.")),
                     (name = "write", title = (defaultText = "write"),
                      description = (defaultText = "Can write.")),
                     (name = "read", title = (defaultText = "read"),
                      description = (defaultText = "Can read."))],
      roles = [(title = (defaultText = "Owner"),
                permissions = [true, true, true],
                verbPhrase = (defaultText = "Is owner, can add & edit notes."),
                default = true),
               (title = (defaultText = "Read & write"),
                permissions = [false, true, true],
                verbPhrase = (defaultText = "Can add & edit notes.")),
               (title = (defaultText = "Read only"),
                permissions = [false, false, true],
                verbPhrase = (defaultText = "Can read existing notes."))]
    )
  )
);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/sandstorm-http-bridge", "8000", "--", "/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 = "HOME", value = "/var")
  ]
);


Bump sandstorm package to 0.2.0

Bump sandstorm package to 0.2.0

@0x883e6eeef30755a7;

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 = "u3agt06j2g56q9374g6j8qz2rt1jf813zxuxc0v1xehuqj33pzw0",
  # 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 = (
    # This manifest is included in your app package to tell Sandstorm
    # about your app.

    appTitle = (defaultText = "HTTP Header Debugger"),

    appVersion = 1,  # Increment this for every release.

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

    actions = [
      # Define your "new document" handlers here.
      ( title = (defaultText = "New debugger"),
        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 = (
      # 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://github.com/sprin/http-header-debugger",
      # This should be the app's main website url.

      codeUrl = "https://github.com/sprin/http-header-debugger",
      # URL of the app's source code repository, e.g. a GitHub URL.
      # Required if you specify a license requiring redistributing code, but optional otherwise.

      license = (none = void),
      # The license this package is distributed under.  See
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#license

      categories = [],
      # 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 = (
        # Fields relating to the author of this app.

        contactEmail = "steffen@sprin.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

        upstreamAuthor = "Steffen Prince",
        # Name of the original primary author of this app, if it is different from the person who
        # produced the Sandstorm package. Setting this implies that the author connected to the PGP
        # signature only "packaged" the app for Sandstorm, rather than developing the app.
        # Remove this line if you consider yourself as the author of the app.
      ),

      #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 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 = "debug HTTP proxy"),
      # 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 = (
    # The following directories will be copied into your package.
    searchPath = [
      ( sourcePath = "/home/vagrant/bundle" ),
      ( sourcePath = "/opt/meteor-spk/meteor-spk.deps" )
    ]
  ),

  alwaysInclude = [ "." ],
  # This says that we always want to include all files from the source map.
  # (An alternative is to automatically detect dependencies by watching what
  # the app opens while running in dev mode. To see what that looks like,
  # run `spk init` without the -A option.)

  #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", "--", "/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.
  ]
);

@0x883e6eeef30755a7;

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 = "u3agt06j2g56q9374g6j8qz2rt1jf813zxuxc0v1xehuqj33pzw0",
  # 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 = (
    # This manifest is included in your app package to tell Sandstorm
    # about your app.

    appTitle = (defaultText = "Proxy Debugger"),

    appVersion = 0,  # Increment this for every release.

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

    actions = [
      # Define your "new document" handlers here.
      ( title = (defaultText = "New debugger"),
        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 = (
      # 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://github.com/sprin/proxy-debugger",
      # This should be the app's main website url.

      codeUrl = "https://github.com/sprin/proxy-debugger",
      # URL of the app's source code repository, e.g. a GitHub URL.
      # Required if you specify a license requiring redistributing code, but optional otherwise.

      license = (none = void),
      # The license this package is distributed under.  See
      # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#license

      categories = [],
      # 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 = (
        # Fields relating to the author of this app.

        contactEmail = "steffen@sprin.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

        upstreamAuthor = "Steffen Prince",
        # Name of the original primary author of this app, if it is different from the person who
        # produced the Sandstorm package. Setting this implies that the author connected to the PGP
        # signature only "packaged" the app for Sandstorm, rather than developing the app.
        # Remove this line if you consider yourself as the author of the app.
      ),

      #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 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 = "debug HTTP proxy"),
      # 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 = (
    # The following directories will be copied into your package.
    searchPath = [
      ( sourcePath = "/home/vagrant/bundle" ),
      ( sourcePath = "/opt/meteor-spk/meteor-spk.deps" )
    ]
  ),

  alwaysInclude = [ "." ],
  # This says that we always want to include all files from the source map.
  # (An alternative is to automatically detect dependencies by watching what
  # the app opens while running in dev mode. To see what that looks like,
  # run `spk init` without the -A option.)

  #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", "--", "/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.
  ]
);


using GetResult

using GetResult

@0xbcc55cbe2b79513a;

interface RampInterface {
    prepare @0 (key:Text, value:Text, dependencies:List(Text), timestamp:Int64);
    commit @1 (timestamp:Int64);
    get @2 (key:Text) -> (result: GetResult);
    getVersion @3 (key:Text, timestamp:Int64) -> (result: GetResult);
}

# since a Get or GetVersion call can have no result we need a union here
struct GetResult {
    union {
        none @0 : Void;
        version @1 : Version;
    }
}

struct Version {
    value @0: Text;
    timestamp @1: Int64;
    dependencies @2: List(Text);
}

@0xbcc55cbe2b79513a;

interface RampInterface {
    prepare @0 (key:Text, value:Text, dependencies:List(Text), timestamp:Int64);
    commit @1 (timestamp:Int64);
    get @2 (key:Text) -> (value:Text, timestamp:Int64, dependencies:List(Text));
    getVersion @3 (key:Text, timestamp:Int64) -> (value:Text, timestamp:Int64, dependencies:List(Text));
}

struct GetResult {
    union {
        none @0 : Void;
        version @1 : Version;
    }
}

struct Version {
    value @0: Text;
    timestamp @1: Int64;
    dependencies @2: List(Text);
}


bump version of sandstorm SPK

bump version of sandstorm SPK

@0xbbbe049af795122e;

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 = "vfnwptfn02ty21w715snyyczw0nqxkv3jvawcah10c6z7hj1hnu0",
  # 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 = (
    # This manifest is included in your app package to tell Sandstorm
    # about your app.

    appTitle = (defaultText = "Rocket.Chat"),

    appVersion = 1,  # Increment this for every release.

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

    actions = [
      # Define your "new document" handlers here.
      ( title = (defaultText = "New Rocket.Chat"),
        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 = (svg = embed "rocket.chat-128.svg"),
        grain = (svg = embed "rocket.chat-24.svg"),
        market = (svg = embed "rocket.chat-150.svg"),
      ),

      website = "https://rocket.chat",
      codeUrl = "https://github.com/RocketChat/Rocket.Chat",
      license = (openSource = mit),
      categories = [communications, productivity],

      author = (
        contactEmail = "team@rocket.chat",
        pgpSignature = embed "pgp-signature",
        upstreamAuthor = "Rocket.Chat",
      ),
      pgpKeyring = embed "pgp-keyring",

      description = (defaultText = embed "description.md"),
      shortDescription = (defaultText = "Chat app"),

      screenshots = [
        (width = 1203, height = 760, png = embed "screenshot.png")
      ],

      changeLog = (defaultText = embed "CHANGELOG.md"),
    ),

  ),

  sourceMap = (
    # The following directories will be copied into your package.
    searchPath = [
      ( sourcePath = "/home/vagrant/bundle" ),
      ( sourcePath = "/opt/meteor-spk/meteor-spk.deps" )
    ]
  ),

  alwaysInclude = [ "." ]
  # This says that we always want to include all files from the source map.
  # (An alternative is to automatically detect dependencies by watching what
  # the app opens while running in dev mode. To see what that looks like,
  # run `spk init` without the -A option.)
);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/sandstorm-http-bridge", "8000", "--", "/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")
  ]
);

@0xbbbe049af795122e;

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 = "vfnwptfn02ty21w715snyyczw0nqxkv3jvawcah10c6z7hj1hnu0",
  # 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 = (
    # This manifest is included in your app package to tell Sandstorm
    # about your app.

    appTitle = (defaultText = "Rocket.Chat"),

    appVersion = 1,  # Increment this for every release.

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

    actions = [
      # Define your "new document" handlers here.
      ( title = (defaultText = "New Rocket.Chat"),
        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 = (svg = embed "rocket.chat-128.svg"),
        grain = (svg = embed "rocket.chat-24.svg"),
        market = (svg = embed "rocket.chat-150.svg"),
      ),

      website = "https://rocket.chat",
      codeUrl = "https://github.com/RocketChat/Rocket.Chat",
      license = (openSource = mit),
      categories = [communications, productivity],

      author = (
        contactEmail = "team@rocket.chat",
        pgpSignature = embed "pgp-signature",
        upstreamAuthor = "Rocket.Chat",
      ),
      pgpKeyring = embed "pgp-keyring",

      description = (defaultText = embed "description.md"),
      shortDescription = (defaultText = "Chat app"),

      screenshots = [
        (width = 1203, height = 760, png = embed "screenshot.png")
      ],

      changeLog = (defaultText = embed "CHANGELOG.md"),
    ),

  ),

  sourceMap = (
    # The following directories will be copied into your package.
    searchPath = [
      ( sourcePath = "/home/vagrant/bundle" ),
      ( sourcePath = "/opt/meteor-spk/meteor-spk.deps" )
    ]
  ),

  alwaysInclude = [ "." ]
  # This says that we always want to include all files from the source map.
  # (An alternative is to automatically detect dependencies by watching what
  # the app opens while running in dev mode. To see what that looks like,
  # run `spk init` without the -A option.)
);

const myCommand :Spk.Manifest.Command = (
  # Here we define the command used to start up your server.
  argv = ["/sandstorm-http-bridge", "8000", "--", "/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")
  ]
);


Expand comments for Brand.Scope.inherit

Expand comments for Brand.Scope.inherit

The first time I learned about Cap'n Proto generics, and again this weekend while trying to relearn them, I spent a long amount of time trying to understand the meaning of Brand.Scope.inherit. I found the existing doc comment to be unhelpful: what exactly is a "reference point" and what does it mean to inherit from one?

What finally made things click was to think of Brands as type substitutions, and to think of inherit as an identity substitution -- it just replaces the parameters with themselves.

This pull request expands the documentation and adds an example that should make things more clear.

# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
# Licensed under the MIT License:
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

using Cxx = import "/capnp/c++.capnp";

@0xa93fc509624c72d9;
$Cxx.namespace("capnp::schema");

using Id = UInt64;
# The globally-unique ID of a file, type, or annotation.

struct Node {
  id @0 :Id;

  displayName @1 :Text;
  # Name to present to humans to identify this Node.  You should not attempt to parse this.  Its
  # format could change.  It is not guaranteed to be unique.
  #
  # (On Zooko's triangle, this is the node's nickname.)

  displayNamePrefixLength @2 :UInt32;
  # If you want a shorter version of `displayName` (just naming this node, without its surrounding
  # scope), chop off this many characters from the beginning of `displayName`.

  scopeId @3 :Id;
  # ID of the lexical parent node.  Typically, the scope node will have a NestedNode pointing back
  # at this node, but robust code should avoid relying on this (and, in fact, group nodes are not
  # listed in the outer struct's nestedNodes, since they are listed in the fields).  `scopeId` is
  # zero if the node has no parent, which is normally only the case with files, but should be
  # allowed for any kind of node (in order to make runtime type generation easier).

  parameters @32 :List(Parameter);
  # If this node is parameterized (generic), the list of parameters. Empty for non-generic types.

  isGeneric @33 :Bool;
  # True if this node is generic, meaning that it or one of its parent scopes has a non-empty
  # `parameters`.

  struct Parameter {
    # Information about one of the node's parameters.

    name @0 :Text;
  }

  nestedNodes @4 :List(NestedNode);
  # List of nodes nested within this node, along with the names under which they were declared.

  struct NestedNode {
    name @0 :Text;
    # Unqualified symbol name.  Unlike Node.displayName, this *can* be used programmatically.
    #
    # (On Zooko's triangle, this is the node's petname according to its parent scope.)

    id @1 :Id;
    # ID of the nested node.  Typically, the target node's scopeId points back to this node, but
    # robust code should avoid relying on this.
  }

  annotations @5 :List(Annotation);
  # Annotations applied to this node.

  union {
    # Info specific to each kind of node.

    file @6 :Void;

    struct :group {
      dataWordCount @7 :UInt16;
      # Size of the data section, in words.

      pointerCount @8 :UInt16;
      # Size of the pointer section, in pointers (which are one word each).

      preferredListEncoding @9 :ElementSize;
      # The preferred element size to use when encoding a list of this struct.  If this is anything
      # other than `inlineComposite` then the struct is one word or less in size and is a candidate
      # for list packing optimization.

      isGroup @10 :Bool;
      # If true, then this "struct" node is actually not an independent node, but merely represents
      # some named union or group within a particular parent struct.  This node's scopeId refers
      # to the parent struct, which may itself be a union/group in yet another struct.
      #
      # All group nodes share the same dataWordCount and pointerCount as the top-level
      # struct, and their fields live in the same ordinal and offset spaces as all other fields in
      # the struct.
      #
      # Note that a named union is considered a special kind of group -- in fact, a named union
      # is exactly equivalent to a group that contains nothing but an unnamed union.

      discriminantCount @11 :UInt16;
      # Number of fields in this struct which are members of an anonymous union, and thus may
      # overlap.  If this is non-zero, then a 16-bit discriminant is present indicating which
      # of the overlapping fields is active.  This can never be 1 -- if it is non-zero, it must be
      # two or more.
      #
      # Note that the fields of an unnamed union are considered fields of the scope containing the
      # union -- an unnamed union is not its own group.  So, a top-level struct may contain a
      # non-zero discriminant count.  Named unions, on the other hand, are equivalent to groups
      # containing unnamed unions.  So, a named union has its own independent schema node, with
      # `isGroup` = true.

      discriminantOffset @12 :UInt32;
      # If `discriminantCount` is non-zero, this is the offset of the union discriminant, in
      # multiples of 16 bits.

      fields @13 :List(Field);
      # Fields defined within this scope (either the struct's top-level fields, or the fields of
      # a particular group; see `isGroup`).
      #
      # The fields are sorted by ordinal number, but note that because groups share the same
      # ordinal space, the field's index in this list is not necessarily exactly its ordinal.
      # On the other hand, the field's position in this list does remain the same even as the
      # protocol evolves, since it is not possible to insert or remove an earlier ordinal.
      # Therefore, for most use cases, if you want to identify a field by number, it may make the
      # most sense to use the field's index in this list rather than its ordinal.
    }

    enum :group {
      enumerants@14 :List(Enumerant);
      # Enumerants ordered by numeric value (ordinal).
    }

    interface :group {
      methods @15 :List(Method);
      # Methods ordered by ordinal.

      superclasses @31 :List(Superclass);
      # Superclasses of this interface.
    }

    const :group {
      type @16 :Type;
      value @17 :Value;
    }

    annotation :group {
      type @18 :Type;

      targetsFile @19 :Bool;
      targetsConst @20 :Bool;
      targetsEnum @21 :Bool;
      targetsEnumerant @22 :Bool;
      targetsStruct @23 :Bool;
      targetsField @24 :Bool;
      targetsUnion @25 :Bool;
      targetsGroup @26 :Bool;
      targetsInterface @27 :Bool;
      targetsMethod @28 :Bool;
      targetsParam @29 :Bool;
      targetsAnnotation @30 :Bool;
    }
  }

  struct SourceInfo {
    # Additional information about a node which is not needed at runtime, but may be useful for
    # documentation or debugging purposes. This is kept in a separate struct to make sure it
    # doesn't accidentally get included in contexts where it is not needed. The
    # `CodeGeneratorRequest` includes this information in a separate array.

    id @0 :Id;
    # ID of the Node which this info describes.

    docComment @1 :Text;
    # The top-level doc comment for the Node.

    members @2 :List(Member);
    # Information about each member -- i.e. fields (for structs), enumerants (for enums), or
    # methods (for interfaces).
    #
    # This list is the same length and order as the corresponding list in the Node, i.e.
    # Node.struct.fields, Node.enum.enumerants, or Node.interface.methods.

    struct Member {
      docComment @0 :Text;
      # Doc comment on the member.
    }

    # TODO(someday): Record location of the declaration in the original source code.
  }
}

struct Field {
  # Schema for a field of a struct.

  name @0 :Text;

  codeOrder @1 :UInt16;
  # Indicates where this member appeared in the code, relative to other members.
  # Code ordering may have semantic relevance -- programmers tend to place related fields
  # together.  So, using code ordering makes sense in human-readable formats where ordering is
  # otherwise irrelevant, like JSON.  The values of codeOrder are tightly-packed, so the maximum
  # value is count(members) - 1.  Fields that are members of a union are only ordered relative to
  # the other members of that union, so the maximum value there is count(union.members).

  annotations @2 :List(Annotation);

  const noDiscriminant :UInt16 = 0xffff;

  discriminantValue @3 :UInt16 = Field.noDiscriminant;
  # If the field is in a union, this is the value which the union's discriminant should take when
  # the field is active.  If the field is not in a union, this is 0xffff.

  union {
    slot :group {
      # A regular, non-group, non-fixed-list field.

      offset @4 :UInt32;
      # Offset, in units of the field's size, from the beginning of the section in which the field
      # resides.  E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the
      # beginning of the data section.

      type @5 :Type;
      defaultValue @6 :Value;

      hadExplicitDefault @10 :Bool;
      # Whether the default value was specified explicitly.  Non-explicit default values are always
      # zero or empty values.  Usually, whether the default value was explicit shouldn't matter.
      # The main use case for this flag is for structs representing method parameters:
      # explicitly-defaulted parameters may be allowed to be omitted when calling the method.
    }

    group :group {
      # A group.

      typeId @7 :Id;
      # The ID of the group's node.
    }
  }

  ordinal :union {
    implicit @8 :Void;
    explicit @9 :UInt16;
    # The original ordinal number given to the field.  You probably should NOT use this; if you need
    # a numeric identifier for a field, use its position within the field array for its scope.
    # The ordinal is given here mainly just so that the original schema text can be reproduced given
    # the compiled version -- i.e. so that `capnp compile -ocapnp` can do its job.
  }
}

struct Enumerant {
  # Schema for member of an enum.

  name @0 :Text;

  codeOrder @1 :UInt16;
  # Specifies order in which the enumerants were declared in the code.
  # Like Struct.Field.codeOrder.

  annotations @2 :List(Annotation);
}

struct Superclass {
  id @0 :Id;
  brand @1 :Brand;
}

struct Method {
  # Schema for method of an interface.

  name @0 :Text;

  codeOrder @1 :UInt16;
  # Specifies order in which the methods were declared in the code.
  # Like Struct.Field.codeOrder.

  implicitParameters @7 :List(Node.Parameter);
  # The parameters listed in [] (typically, type / generic parameters), whose bindings are intended
  # to be inferred rather than specified explicitly, although not all languages support this.

  paramStructType @2 :Id;
  # ID of the parameter struct type.  If a named parameter list was specified in the method
  # declaration (rather than a single struct parameter type) then a corresponding struct type is
  # auto-generated.  Such an auto-generated type will not be listed in the interface's
  # `nestedNodes` and its `scopeId` will be zero -- it is completely detached from the namespace.
  # (Awkwardly, it does of course inherit generic parameters from the method's scope, which makes
  # this a situation where you can't just climb the scope chain to find where a particular
  # generic parameter was introduced. Making the `scopeId` zero was a mistake.)

  paramBrand @5 :Brand;
  # Brand of param struct type.

  resultStructType @3 :Id;
  # ID of the return struct type; similar to `paramStructType`.

  resultBrand @6 :Brand;
  # Brand of result struct type.

  annotations @4 :List(Annotation);
}

struct Type {
  # Represents a type expression.

  union {
    # The ordinals intentionally match those of Value.

    void @0 :Void;
    bool @1 :Void;
    int8 @2 :Void;
    int16 @3 :Void;
    int32 @4 :Void;
    int64 @5 :Void;
    uint8 @6 :Void;
    uint16 @7 :Void;
    uint32 @8 :Void;
    uint64 @9 :Void;
    float32 @10 :Void;
    float64 @11 :Void;
    text @12 :Void;
    data @13 :Void;

    list :group {
      elementType @14 :Type;
    }

    enum :group {
      typeId @15 :Id;
      brand @21 :Brand;
    }
    struct :group {
      typeId @16 :Id;
      brand @22 :Brand;
    }
    interface :group {
      typeId @17 :Id;
      brand @23 :Brand;
    }

    anyPointer :union {
      unconstrained :union {
        # A regular AnyPointer.
        #
        # The name "unconstrained" means as opposed to constraining it to match a type parameter.
        # In retrospect this name is probably a poor choice given that it may still be constrained
        # to be a struct, list, or capability.

        anyKind @18 :Void;       # truly AnyPointer
        struct @25 :Void;        # AnyStruct
        list @26 :Void;          # AnyList
        capability @27 :Void;    # Capability
      }

      parameter :group {
        # This is actually a reference to a type parameter defined within this scope.

        scopeId @19 :Id;
        # ID of the generic type whose parameter we're referencing. This should be a parent of the
        # current scope.

        parameterIndex @20 :UInt16;
        # Index of the parameter within the generic type's parameter list.
      }

      implicitMethodParameter :group {
        # This is actually a reference to an implicit (generic) parameter of a method. The only
        # legal context for this type to appear is inside Method.paramBrand or Method.resultBrand.

        parameterIndex @24 :UInt16;
      }
    }
  }
}

struct Brand {
  # Specifies bindings for parameters of generics. Since these bindings turn a generic into a
  # non-generic, we call it the "brand".

  scopes @0 :List(Scope);
  # For each of the target type and each of its parent scopes, a parameterization may be included
  # in this list. If no parameterization is included for a particular relevant scope, then either
  # that scope has no parameters or all parameters should be considered to be `AnyPointer`.

  struct Scope {
    scopeId @0 :Id;
    # ID of the scope to which these params apply.

    union {
      bind @1 :List(Binding);
      # List of parameter bindings.

      inherit @2 :Void;
      # The place where the Brand appears is within this scope or a sub-scope, and bindings
      # for this scope are deferred to later Brand applications. This is equivalent to a
      # pass-through binding list, where each of this scope's parameters is bound to itself.
      # For example:
      #
      #   struct Outer(T) {
      #     struct Inner {
      #       value @0 :T;
      #     }
      #     innerInherit @0 :Inner;            # Outer Brand.Scope is `inherit`.
      #     innerBindSelf @1 :Outer(T).Inner;  # Outer Brand.Scope explicitly binds T to T.
      #   }
      #
      # The innerInherit and innerBindSelf fields have equivalent types, but different Brand
      # styles.
    }
  }

  struct Binding {
    union {
      unbound @0 :Void;
      type @1 :Type;

      # TODO(someday): Allow non-type parameters? Unsure if useful.
    }
  }
}

struct Value {
  # Represents a value, e.g. a field default value, constant value, or annotation value.

  union {
    # The ordinals intentionally match those of Type.

    void @0 :Void;
    bool @1 :Bool;
    int8 @2 :Int8;
    int16 @3 :Int16;
    int32 @4 :Int32;
    int64 @5 :Int64;
    uint8 @6 :UInt8;
    uint16 @7 :UInt16;
    uint32 @8 :UInt32;
    uint64 @9 :UInt64;
    float32 @10 :Float32;
    float64 @11 :Float64;
    text @12 :Text;
    data @13 :Data;

    list @14 :AnyPointer;

    enum @15 :UInt16;
    struct @16 :AnyPointer;

    interface @17 :Void;
    # The only interface value that can be represented statically is "null", whose methods always
    # throw exceptions.

    anyPointer @18 :AnyPointer;
  }
}

struct Annotation {
  # Describes an annotation applied to a declaration.  Note AnnotationNode describes the
  # annotation's declaration, while this describes a use of the annotation.

  id @0 :Id;
  # ID of the annotation node.

  brand @2 :Brand;
  # Brand of the annotation.
  #
  # Note that the annotation itself is not allowed to be parameterized, but its scope might be.

  value @1 :Value;
}

enum ElementSize {
  # Possible element sizes for encoded lists.  These correspond exactly to the possible values of
  # the 3-bit element size component of a list pointer.

  empty @0;    # aka "void", but that's a keyword.
  bit @1;
  byte @2;
  twoBytes @3;
  fourBytes @4;
  eightBytes @5;
  pointer @6;
  inlineComposite @7;
}

struct CapnpVersion {
  major @0 :UInt16;
  minor @1 :UInt8;
  micro @2 :UInt8;
}

struct CodeGeneratorRequest {
  capnpVersion @2 :CapnpVersion;
  # Version of the `capnp` executable. Generally, code generators should ignore this, but the code
  # generators that ship with `capnp` itself will print a warning if this mismatches since that
  # probably indicates something is misconfigured.
  #
  # The first version of 'capnp' to set this was 0.6.0. So, if it's missing, the compiler version
  # is older than that.

  nodes @0 :List(Node);
  # All nodes parsed by the compiler, including for the files on the command line and their
  # imports.

  sourceInfo @3 :List(Node.SourceInfo);
  # Information about the original source code for each node, where available. This array may be
  # omitted or may be missing some nodes if no info is available for them.

  requestedFiles @1 :List(RequestedFile);
  # Files which were listed on the command line.

  struct RequestedFile {
    id @0 :Id;
    # ID of the file.

    filename @1 :Text;
    # Name of the file as it appeared on the command-line (minus the src-prefix).  You may use
    # this to decide where to write the output.

    imports @2 :List(Import);
    # List of all imported paths seen in this file.

    struct Import {
      id @0 :Id;
      # ID of the imported file.

      name @1 :Text;
      # Name which *this* file used to refer to the foreign file.  This may be a relative name.
      # This information is provided because it might be useful for code generation, e.g. to
      # generate #include directives in C++.  We don't put this in Node.file because this
      # information is only meaningful at compile time anyway.
      #
      # (On Zooko's triangle, this is the import's petname according to the importing file.)
    }
  }
}

# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
# Licensed under the MIT License:
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

using Cxx = import "/capnp/c++.capnp";

@0xa93fc509624c72d9;
$Cxx.namespace("capnp::schema");

using Id = UInt64;
# The globally-unique ID of a file, type, or annotation.

struct Node {
  id @0 :Id;

  displayName @1 :Text;
  # Name to present to humans to identify this Node.  You should not attempt to parse this.  Its
  # format could change.  It is not guaranteed to be unique.
  #
  # (On Zooko's triangle, this is the node's nickname.)

  displayNamePrefixLength @2 :UInt32;
  # If you want a shorter version of `displayName` (just naming this node, without its surrounding
  # scope), chop off this many characters from the beginning of `displayName`.

  scopeId @3 :Id;
  # ID of the lexical parent node.  Typically, the scope node will have a NestedNode pointing back
  # at this node, but robust code should avoid relying on this (and, in fact, group nodes are not
  # listed in the outer struct's nestedNodes, since they are listed in the fields).  `scopeId` is
  # zero if the node has no parent, which is normally only the case with files, but should be
  # allowed for any kind of node (in order to make runtime type generation easier).

  parameters @32 :List(Parameter);
  # If this node is parameterized (generic), the list of parameters. Empty for non-generic types.

  isGeneric @33 :Bool;
  # True if this node is generic, meaning that it or one of its parent scopes has a non-empty
  # `parameters`.

  struct Parameter {
    # Information about one of the node's parameters.

    name @0 :Text;
  }

  nestedNodes @4 :List(NestedNode);
  # List of nodes nested within this node, along with the names under which they were declared.

  struct NestedNode {
    name @0 :Text;
    # Unqualified symbol name.  Unlike Node.displayName, this *can* be used programmatically.
    #
    # (On Zooko's triangle, this is the node's petname according to its parent scope.)

    id @1 :Id;
    # ID of the nested node.  Typically, the target node's scopeId points back to this node, but
    # robust code should avoid relying on this.
  }

  annotations @5 :List(Annotation);
  # Annotations applied to this node.

  union {
    # Info specific to each kind of node.

    file @6 :Void;

    struct :group {
      dataWordCount @7 :UInt16;
      # Size of the data section, in words.

      pointerCount @8 :UInt16;
      # Size of the pointer section, in pointers (which are one word each).

      preferredListEncoding @9 :ElementSize;
      # The preferred element size to use when encoding a list of this struct.  If this is anything
      # other than `inlineComposite` then the struct is one word or less in size and is a candidate
      # for list packing optimization.

      isGroup @10 :Bool;
      # If true, then this "struct" node is actually not an independent node, but merely represents
      # some named union or group within a particular parent struct.  This node's scopeId refers
      # to the parent struct, which may itself be a union/group in yet another struct.
      #
      # All group nodes share the same dataWordCount and pointerCount as the top-level
      # struct, and their fields live in the same ordinal and offset spaces as all other fields in
      # the struct.
      #
      # Note that a named union is considered a special kind of group -- in fact, a named union
      # is exactly equivalent to a group that contains nothing but an unnamed union.

      discriminantCount @11 :UInt16;
      # Number of fields in this struct which are members of an anonymous union, and thus may
      # overlap.  If this is non-zero, then a 16-bit discriminant is present indicating which
      # of the overlapping fields is active.  This can never be 1 -- if it is non-zero, it must be
      # two or more.
      #
      # Note that the fields of an unnamed union are considered fields of the scope containing the
      # union -- an unnamed union is not its own group.  So, a top-level struct may contain a
      # non-zero discriminant count.  Named unions, on the other hand, are equivalent to groups
      # containing unnamed unions.  So, a named union has its own independent schema node, with
      # `isGroup` = true.

      discriminantOffset @12 :UInt32;
      # If `discriminantCount` is non-zero, this is the offset of the union discriminant, in
      # multiples of 16 bits.

      fields @13 :List(Field);
      # Fields defined within this scope (either the struct's top-level fields, or the fields of
      # a particular group; see `isGroup`).
      #
      # The fields are sorted by ordinal number, but note that because groups share the same
      # ordinal space, the field's index in this list is not necessarily exactly its ordinal.
      # On the other hand, the field's position in this list does remain the same even as the
      # protocol evolves, since it is not possible to insert or remove an earlier ordinal.
      # Therefore, for most use cases, if you want to identify a field by number, it may make the
      # most sense to use the field's index in this list rather than its ordinal.
    }

    enum :group {
      enumerants@14 :List(Enumerant);
      # Enumerants ordered by numeric value (ordinal).
    }

    interface :group {
      methods @15 :List(Method);
      # Methods ordered by ordinal.

      superclasses @31 :List(Superclass);
      # Superclasses of this interface.
    }

    const :group {
      type @16 :Type;
      value @17 :Value;
    }

    annotation :group {
      type @18 :Type;

      targetsFile @19 :Bool;
      targetsConst @20 :Bool;
      targetsEnum @21 :Bool;
      targetsEnumerant @22 :Bool;
      targetsStruct @23 :Bool;
      targetsField @24 :Bool;
      targetsUnion @25 :Bool;
      targetsGroup @26 :Bool;
      targetsInterface @27 :Bool;
      targetsMethod @28 :Bool;
      targetsParam @29 :Bool;
      targetsAnnotation @30 :Bool;
    }
  }

  struct SourceInfo {
    # Additional information about a node which is not needed at runtime, but may be useful for
    # documentation or debugging purposes. This is kept in a separate struct to make sure it
    # doesn't accidentally get included in contexts where it is not needed. The
    # `CodeGeneratorRequest` includes this information in a separate array.

    id @0 :Id;
    # ID of the Node which this info describes.

    docComment @1 :Text;
    # The top-level doc comment for the Node.

    members @2 :List(Member);
    # Information about each member -- i.e. fields (for structs), enumerants (for enums), or
    # methods (for interfaces).
    #
    # This list is the same length and order as the corresponding list in the Node, i.e.
    # Node.struct.fields, Node.enum.enumerants, or Node.interface.methods.

    struct Member {
      docComment @0 :Text;
      # Doc comment on the member.
    }

    # TODO(someday): Record location of the declaration in the original source code.
  }
}

struct Field {
  # Schema for a field of a struct.

  name @0 :Text;

  codeOrder @1 :UInt16;
  # Indicates where this member appeared in the code, relative to other members.
  # Code ordering may have semantic relevance -- programmers tend to place related fields
  # together.  So, using code ordering makes sense in human-readable formats where ordering is
  # otherwise irrelevant, like JSON.  The values of codeOrder are tightly-packed, so the maximum
  # value is count(members) - 1.  Fields that are members of a union are only ordered relative to
  # the other members of that union, so the maximum value there is count(union.members).

  annotations @2 :List(Annotation);

  const noDiscriminant :UInt16 = 0xffff;

  discriminantValue @3 :UInt16 = Field.noDiscriminant;
  # If the field is in a union, this is the value which the union's discriminant should take when
  # the field is active.  If the field is not in a union, this is 0xffff.

  union {
    slot :group {
      # A regular, non-group, non-fixed-list field.

      offset @4 :UInt32;
      # Offset, in units of the field's size, from the beginning of the section in which the field
      # resides.  E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the
      # beginning of the data section.

      type @5 :Type;
      defaultValue @6 :Value;

      hadExplicitDefault @10 :Bool;
      # Whether the default value was specified explicitly.  Non-explicit default values are always
      # zero or empty values.  Usually, whether the default value was explicit shouldn't matter.
      # The main use case for this flag is for structs representing method parameters:
      # explicitly-defaulted parameters may be allowed to be omitted when calling the method.
    }

    group :group {
      # A group.

      typeId @7 :Id;
      # The ID of the group's node.
    }
  }

  ordinal :union {
    implicit @8 :Void;
    explicit @9 :UInt16;
    # The original ordinal number given to the field.  You probably should NOT use this; if you need
    # a numeric identifier for a field, use its position within the field array for its scope.
    # The ordinal is given here mainly just so that the original schema text can be reproduced given
    # the compiled version -- i.e. so that `capnp compile -ocapnp` can do its job.
  }
}

struct Enumerant {
  # Schema for member of an enum.

  name @0 :Text;

  codeOrder @1 :UInt16;
  # Specifies order in which the enumerants were declared in the code.
  # Like Struct.Field.codeOrder.

  annotations @2 :List(Annotation);
}

struct Superclass {
  id @0 :Id;
  brand @1 :Brand;
}

struct Method {
  # Schema for method of an interface.

  name @0 :Text;

  codeOrder @1 :UInt16;
  # Specifies order in which the methods were declared in the code.
  # Like Struct.Field.codeOrder.

  implicitParameters @7 :List(Node.Parameter);
  # The parameters listed in [] (typically, type / generic parameters), whose bindings are intended
  # to be inferred rather than specified explicitly, although not all languages support this.

  paramStructType @2 :Id;
  # ID of the parameter struct type.  If a named parameter list was specified in the method
  # declaration (rather than a single struct parameter type) then a corresponding struct type is
  # auto-generated.  Such an auto-generated type will not be listed in the interface's
  # `nestedNodes` and its `scopeId` will be zero -- it is completely detached from the namespace.
  # (Awkwardly, it does of course inherit generic parameters from the method's scope, which makes
  # this a situation where you can't just climb the scope chain to find where a particular
  # generic parameter was introduced. Making the `scopeId` zero was a mistake.)

  paramBrand @5 :Brand;
  # Brand of param struct type.

  resultStructType @3 :Id;
  # ID of the return struct type; similar to `paramStructType`.

  resultBrand @6 :Brand;
  # Brand of result struct type.

  annotations @4 :List(Annotation);
}

struct Type {
  # Represents a type expression.

  union {
    # The ordinals intentionally match those of Value.

    void @0 :Void;
    bool @1 :Void;
    int8 @2 :Void;
    int16 @3 :Void;
    int32 @4 :Void;
    int64 @5 :Void;
    uint8 @6 :Void;
    uint16 @7 :Void;
    uint32 @8 :Void;
    uint64 @9 :Void;
    float32 @10 :Void;
    float64 @11 :Void;
    text @12 :Void;
    data @13 :Void;

    list :group {
      elementType @14 :Type;
    }

    enum :group {
      typeId @15 :Id;
      brand @21 :Brand;
    }
    struct :group {
      typeId @16 :Id;
      brand @22 :Brand;
    }
    interface :group {
      typeId @17 :Id;
      brand @23 :Brand;
    }

    anyPointer :union {
      unconstrained :union {
        # A regular AnyPointer.
        #
        # The name "unconstrained" means as opposed to constraining it to match a type parameter.
        # In retrospect this name is probably a poor choice given that it may still be constrained
        # to be a struct, list, or capability.

        anyKind @18 :Void;       # truly AnyPointer
        struct @25 :Void;        # AnyStruct
        list @26 :Void;          # AnyList
        capability @27 :Void;    # Capability
      }

      parameter :group {
        # This is actually a reference to a type parameter defined within this scope.

        scopeId @19 :Id;
        # ID of the generic type whose parameter we're referencing. This should be a parent of the
        # current scope.

        parameterIndex @20 :UInt16;
        # Index of the parameter within the generic type's parameter list.
      }

      implicitMethodParameter :group {
        # This is actually a reference to an implicit (generic) parameter of a method. The only
        # legal context for this type to appear is inside Method.paramBrand or Method.resultBrand.

        parameterIndex @24 :UInt16;
      }
    }
  }
}

struct Brand {
  # Specifies bindings for parameters of generics. Since these bindings turn a generic into a
  # non-generic, we call it the "brand".

  scopes @0 :List(Scope);
  # For each of the target type and each of its parent scopes, a parameterization may be included
  # in this list. If no parameterization is included for a particular relevant scope, then either
  # that scope has no parameters or all parameters should be considered to be `AnyPointer`.

  struct Scope {
    scopeId @0 :Id;
    # ID of the scope to which these params apply.

    union {
      bind @1 :List(Binding);
      # List of parameter bindings.

      inherit @2 :Void;
      # The place where this Brand appears is actually within this scope or a sub-scope,
      # and the bindings for this scope should be inherited from the reference point.
    }
  }

  struct Binding {
    union {
      unbound @0 :Void;
      type @1 :Type;

      # TODO(someday): Allow non-type parameters? Unsure if useful.
    }
  }
}

struct Value {
  # Represents a value, e.g. a field default value, constant value, or annotation value.

  union {
    # The ordinals intentionally match those of Type.

    void @0 :Void;
    bool @1 :Bool;
    int8 @2 :Int8;
    int16 @3 :Int16;
    int32 @4 :Int32;
    int64 @5 :Int64;
    uint8 @6 :UInt8;
    uint16 @7 :UInt16;
    uint32 @8 :UInt32;
    uint64 @9 :UInt64;
    float32 @10 :Float32;
    float64 @11 :Float64;
    text @12 :Text;
    data @13 :Data;

    list @14 :AnyPointer;

    enum @15 :UInt16;
    struct @16 :AnyPointer;

    interface @17 :Void;
    # The only interface value that can be represented statically is "null", whose methods always
    # throw exceptions.

    anyPointer @18 :AnyPointer;
  }
}

struct Annotation {
  # Describes an annotation applied to a declaration.  Note AnnotationNode describes the
  # annotation's declaration, while this describes a use of the annotation.

  id @0 :Id;
  # ID of the annotation node.

  brand @2 :Brand;
  # Brand of the annotation.
  #
  # Note that the annotation itself is not allowed to be parameterized, but its scope might be.

  value @1 :Value;
}

enum ElementSize {
  # Possible element sizes for encoded lists.  These correspond exactly to the possible values of
  # the 3-bit element size component of a list pointer.

  empty @0;    # aka "void", but that's a keyword.
  bit @1;
  byte @2;
  twoBytes @3;
  fourBytes @4;
  eightBytes @5;
  pointer @6;
  inlineComposite @7;
}

struct CapnpVersion {
  major @0 :UInt16;
  minor @1 :UInt8;
  micro @2 :UInt8;
}

struct CodeGeneratorRequest {
  capnpVersion @2 :CapnpVersion;
  # Version of the `capnp` executable. Generally, code generators should ignore this, but the code
  # generators that ship with `capnp` itself will print a warning if this mismatches since that
  # probably indicates something is misconfigured.
  #
  # The first version of 'capnp' to set this was 0.6.0. So, if it's missing, the compiler version
  # is older than that.

  nodes @0 :List(Node);
  # All nodes parsed by the compiler, including for the files on the command line and their
  # imports.

  sourceInfo @3 :List(Node.SourceInfo);
  # Information about the original source code for each node, where available. This array may be
  # omitted or may be missing some nodes if no info is available for them.

  requestedFiles @1 :List(RequestedFile);
  # Files which were listed on the command line.

  struct RequestedFile {
    id @0 :Id;
    # ID of the file.

    filename @1 :Text;
    # Name of the file as it appeared on the command-line (minus the src-prefix).  You may use
    # this to decide where to write the output.

    imports @2 :List(Import);
    # List of all imported paths seen in this file.

    struct Import {
      id @0 :Id;
      # ID of the imported file.

      name @1 :Text;
      # Name which *this* file used to refer to the foreign file.  This may be a relative name.
      # This information is provided because it might be useful for code generation, e.g. to
      # generate #include directives in C++.  We don't put this in Node.file because this
      # information is only meaningful at compile time anyway.
      #
      # (On Zooko's triangle, this is the import's petname according to the importing file.)
    }
  }
}