-
-
Notifications
You must be signed in to change notification settings - Fork 709
/
Copy pathpackage.capnp
752 lines (621 loc) · 32.4 KB
/
package.capnp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
# Sandstorm - Personal Cloud Sandbox
# Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors
# 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.
@0xdf9bc20172856a3a;
# This file contains schemas relevant to the Sandstorm package format. See also the `spk` tool.
$import "/capnp/c++.capnp".namespace("sandstorm::spk");
using Util = import "util.capnp";
using Powerbox = import "powerbox.capnp";
using Grain = import "grain.capnp";
using ApiSession = import "api-session.capnp".ApiSession;
using Identity = import "identity.capnp";
using WebSession = import "web-session.capnp".WebSession;
struct PackageDefinition {
id @0 :Text;
# The app's ID string. This is actually an encoding of the app's public key generated by the spk
# tool, and looks something like "h37dm17aa89yrd8zuqpdn36p6zntumtv08fjpu8a8zrte7q1cn60".
#
# Normally, `spk init` will fill this in for you. You can use `spk keygen` to generate a new ID
# if needed. The private key corresponding to each ID is stored in a keyring outside your project
# directory; see `spk help` for more on this.
#
# Note that you can specify an alternative ID to `spk pack` with the `-i` flag. This makes sense
# when you are doing an unofficial build of an app and don't want to use (or don't have access
# to) the app's real private key.
manifest @1 :Manifest;
# Manifest to write as the package's `sandstorm_manifest`. If null, then `sandstorm-manifest`
# should appear in the file list.
sourceMap @2 :SourceMap;
# Indicates where to search for file to include in the package.
fileList @3 :Text;
# Name of a file which itself contains a list of files, one per line, that should be included
# in the package. Each file should be specified according to its location in the package; the
# source file will be found by mapping this through `sourceMap`. Each name should be canonical
# (no ".", "..", or consecutive slashes) and should NOT start with '/'.
#
# The file list is automatically generated by `spk dev` based on watching what files are opened
# by the actual running server. On subsequent runs, new files will be added, but files will never
# be removed from the list. To reset the list, simply delete it and run `spk dev` again.
alwaysInclude @4 :List(Text);
# Files and directories that should always be included in the package whether or not they are
# in the file named by `fileList`. If you name a directory here, its entire contents will be
# included recursively (this is not the case in `fileList`). Use this list to name files that
# wouldn't automatically be included, because for whatever reason the server does not actually
# open them when running in dev mode. This could include runtime dependencies that are too
# difficult to test fully, or perhaps a readme file or copyright notice that you want people to
# see if they unpack your package manually.
bridgeConfig @5 :BridgeConfig;
# Configuration variables for apps that use sandstorm-http-bridge.
}
struct Manifest {
# This manifest file defines an application. The file `sandstorm-manifest` at the root of the
# application's `.spk` package contains a serialized (binary) instance of `Manifest`.
#
# TODO(soon): Maybe this should be renamed. A "manifest" is a list of contents, but this
# structure doesn't contain a list at all; it contains information on how to use the contents.
const sizeLimitInWords :UInt64 = 1048576;
# The maximum size of the Manifest is 8MB (1M words). This limit is enforced in many places.
appTitle @7 :Util.LocalizedText;
# The name of this app as it should be displayed to the user.
appVersion @4 :UInt32;
# Among app packages with the same app ID (i.e. the same `publicKey`), `version` is used to
# decide which packages represent newer vs. older versions of the app. The sole purpose of this
# number is to decide whether one package is newer than another; it is not normally displayed to
# the user. This number need not have anything to do with the "marketing version" of your app.
minUpgradableAppVersion @5 :UInt32;
# The minimum version of the app which can be safely replaced by this app package without data
# loss. This might be non-zero if the app's data store format changed drastically in the past
# and the app is no longer able to read the old format.
appMarketingVersion @6 :Util.LocalizedText;
# Human-readable presentation of the app version, e.g. "2.9.17". This will be displayed to the
# user to distinguish versions. It _should_ match the way you identify versions of your app to
# users in documentation and marketing.
minApiVersion @0 :UInt32;
maxApiVersion @1 :UInt32;
# Min and max API versions against which this app is known to work. `minApiVersion` primarily
# exists to warn the user if their instance is too old. If the sandstorm instance is newer than
# `maxApiVersion`, it may engage backwards-compatibility hacks and hide features introduced in
# newer versions.
metadata @8 :Metadata;
# Stuff that's not important to actually executing the app, but important to how the app is
# presented to the user in the Sandstorm UI and app marketplace.
struct Command {
# Description of a command to execute.
#
# Note that commands specified this way are NOT interpreted by a shell. If you want shell
# expansion, you must include a shell binary in your app and invoke it to interpret the
# command.
argv @1 :List(Text);
# Argument list, with the program name as argv[0].
environ @2 :List(Util.KeyValue);
# Environment variables to set. The environment will be completely empty other than what you
# define here.
deprecatedExecutablePath @0 :Text;
# (Obsolete) If specified, will be inserted at the beginning of argv. This is now redundant
# because you should just specify the program as argv[0]. To be clear, this does not and did
# never provide a way to make argv[0] contain something other than the executable name, as
# you can technically do with the `exec` system call.
}
struct Action {
input :union {
none @0 :Void;
# This action creates a new grain with no input.
capability @1 :List(Powerbox.PowerboxDescriptor);
# This action creates a new grain from a powerbox offer. When a capability matching the query
# is offered to the user (e.g. by another application calling SessionContext.offer()), this
# action will be listed as one of the things the user can do with it.
#
# On startup, the platform will call create the first session with
# `UiView.newOfferSession()`.
}
command @2 :Command;
# Command to execute (in a newly-allocated grain) to run this action.
title @3 :Util.LocalizedText;
# (Obsolete) Title of this action, to display in the action selector. This should no longer
# be used for new apps.
nounPhrase @5 : Util.LocalizedText;
# When this action is run, what kind of thing is created? E.g. Etherpad creates a "document".
# Displayed as "New <nounPhrase>" in the "create new grain" UI.
description @4 :Util.LocalizedText;
# Description of this action, suitable for help text.
}
actions @2 :List(Action);
# Actions which this grain offers.
continueCommand @3 :Command;
# Command to run to restart an already-created grain.
}
struct SourceMap {
# Defines where to find files that need to be included in a package. This is usually combined
# with a list of files that the package is expected to contain in order to compile a package.
# The list of files may come from using "spk dev" to
searchPath @0 :List(Mapping);
# List of directories to map into the package.
struct Mapping {
# Describes a directory to be mapped into the package.
packagePath @0 :Text;
# Path where this directory should be mapped into the package. Must be a canonical file name
# (no "." nor "..") and must not start with '/'. Omit to map to the package root directory.
sourcePath @1 :Text;
# Path on the local system where this directory may be found. Relative paths are interpreted
# relative to the location of the package definition file.
hidePaths @2 :List(Text);
# Names of files or subdirectories within the directory which should be hidden when mapping
# this path into the spk. Use only canonical paths here -- i.e. do not use ".", "..", or
# multiple consecutive slashes. Do not use a leading slash.
}
}
struct BridgeConfig {
# Configuration variables specific to apps that are using sandstorm-http-bridge. This includes
# things that need to be communicated to the bridge process before the app starts up, such as
# permissions.
viewInfo @0 :Grain.UiView.ViewInfo;
# What to return from the UiView's getViewInfo(). This structure defines, among other things, the
# list of shareable permissions and roles that apply to this app. See grain.capnp for more details.
#
# When a request comes in from the user, sandstorm-http-bridge will set the
# X-Sandstorm-Permissions header to a comma-delimited list of permission names corresponding to
# the user's permissions.
apiPath @1 :Text;
# Specifies a path which will be prefixed to all API requests -- that is, requests coming in
# through the API endpoint as described in:
# https://docs.sandstorm.io/en/latest/developing/http-apis/
#
# Note that this form of HTTP APIs is old and will eventually be deprecated. In the fantastic
# future, available APIs should be defined by `powerboxApis`, below. However, as of this writing,
# `powerboxApis` cannot do everything that old-style HTTP APIs do. Why yes, I did once work at
# Google, how could you tell?
#
# apiPath must end with "/".
#
# WARNING: Specifying this does NOT prevent access to other paths. Anyone holding an API token
# can convert it into a sharing token, which provides full access to the grain's web interface.
# The purpose of apiPath is only to allow you to design your API URL schema independently of
# your UI's URL schema, which is often convenient. To actually restrict what an API token
# holder is allowed to do, you MUST use permissions and enforce them for both API and UI
# requests. See:
# https://docs.sandstorm.io/en/latest/developing/auth/
saveIdentityCaps @2 :Bool;
# If true, the first time a new user accesses the grain, the bridge will save the user's Identity
# capability so that it can be fetched later using `SandstormHttpBridge.getSavedIdentity`. You
# will probably want to enable this if your app supports notifications.
expectAppHooks @4 :Bool;
# Set this to true if you are using sandstorm-http-bridge and want to do any of
# the following:
#
# - Provide an implementation of getViewInfo() that generates its result dynamically,
# rather than statically defining the result via `viewInfo` above.
# - Support exporting persistent capabilities other than the HTTP APIs specified by
# PowerboxApi below.
#
# If this is true, the bridge will expect the application to establish a capnproto
# connection to the bridge via `/tmp/sandstorm-api`, and it will expect the app's
# bootstrap interface on this connection to implement `AppHooks`, defined in
# sandstorm-http-bridge.capnp. The methods described there can be used to
# implement the above functionality.
powerboxApis @3 :List(PowerboxApi);
struct PowerboxApi {
# Defines an HTTP API which this application exports, to which other apps can request access
# via the powerbox.
#
# Use this to define APIs to which other applications can request access.
#
# Note that this metadata is consulted at the time of a powerbox request. Once the request is
# complete and a connection has been formed, future changes to the app's manifest will not
# affect the already-made connection.
name @0 :Text;
# Symbolic name for this API. This is passed back to the app as the value of the
# `X-Sandstorm-Api` header, in all requests made to this API. Note that removing an API
# definition will NOT revoke existing connections formed through the powerbox. So, the app
# should be prepared to handle all API names that it has ever defined (or, perhaps, return
# an appropriate error when it receives a request for an API that no longer exists).
displayInfo @1 :Powerbox.PowerboxDisplayInfo;
# Information for display to the user when representing this API.
#
# displayInfo.title in particular will be used when displaying a chooser to the user to choose
# among the app's available APIs.
path @2 :Text;
# Specifies the path which will be prefixed to all requests to this API.
#
# Like `apiPath` (above), this must end with "/". It is perfectly reasonable for the path to be
# just "/", if you consider your app's entire HTTP surface to be an API. However, note that
# unlike with `apiPath`, restricting a powerbox API to a sub-path actually does prevent
# consumers of the API from accessing other paths. You may wish to use this to your advantage.
tag @3 :ApiSession.PowerboxTag;
# Tag defining this API for powerbox matching purposes.
permissions @4 :Identity.PermissionSet;
# The permissions represented by this API. A user interacting with the powerbox will not have
# the option of choosing this API unless they possess at least these permissions. Meanwhile,
# when a request is made to this API, the `Sandstorm-Permissions` header will always contain
# exactly these permissions, even if the user who made the powerbox connection has greater
# permissions.
#
# If not specified, the `X-Sandstorm-Permissions` header will contain the exact list of
# permissions that the user had at the time that they formed the connection. Note that if any
# of these permissions are later revoked from the user, then the API connection will be revoked
# in whole.
# TODO(someday): Allow non-singleton APIs, for grains that contain many objects. Requires app
# to implement an embeddable picker UI.
# TODO(someday): Allow implementing Cap'n Proto APIs via JSON conversion.
}
}
struct Metadata {
# Data which is not needed specifically to execute the app, but is useful for purposes like
# marketing and display.
#
# Technically, appMarketingVersion and appTitle belong in this category, but they were defined
# before Metadata became a thing.
#
# NOTE: Any changes here which add new blobs may require updating the front-end so that it
# correctly extracts those blobs into separate assets on install.
icons :group {
# Various icons to represent the app in various contexts.
#
# Each context is associated with a List(Icon). This list contains versions of the same image
# in varying sizes and formats. When the icon is used, the optimal icon image will be chosen
# from the list based on the context where it is to be displayed, possibly taking into account
# parameters like size, display pixel density, and browser image format support.
appGrid @0 :Icon;
# The icon shown on the app grid, in the "new grain" flow.
#
# Size: 128x128
# Data size limit: 64kB
grain @1 :Icon;
# The icon shown to represent an individual grain, both in the grain table and on the navbar.
# If omitted, the appGrid icon will be used.
#
# Size: 24x24
# Data size limit: 4kB
market @2 :Icon;
# The icon shown in the app market grid. If omitted, the appGrid icon will be used.
#
# Size: 150x150
# Data size limit: 64kB
marketBig @18 :Icon;
# The image shown in the app market when visiting the app's page directly, or when featuring
# a particular app with a bigger display. If omitted, the regular market icon will be used
# (raster images may look bad).
#
# Size: 300x300
# Data size limit: 256kB
}
struct Icon {
# Represents one icon image.
union {
unknown @0 :Void;
# Unknown file format.
svg @1 :Text;
# Scalable Vector Graphics image. This format is *highly* preferred whenever possible.
#
# The uncompressed SVG can be up to 4x the documented size limit, to account for the fact
# that it will be compressed when served.
png :group {
# PNG image. You may specify one or both DPI levels.
dpi1x @2 :Data;
# Normal-resolution PNG. The image's resolution should exactly match the documented
# viewport size.
dpi2x @3 :Data;
# Double-resolution PNG for high-dpi displays. Any documented data size limit is also
# doubled for this PNG. (The size limit is only doubled, not quadrupled, because the size
# of a compressed image should be a function of total interior edge length, not area.)
}
}
}
website @3 :Text;
# URL of the app's main web site.
codeUrl @4 :Text;
# URL of the app's source code repository, e.g. a Github URL.
#
# This field is required if the app's license requires redistributing code (such as the GPL),
# but is optional otherwise.
license :group {
# How is this app licensed?
#
# Example usage for open source licenses:
#
# license = (openSource = apache2, notices = (defaultText = embed "notices.txt")),
#
# Example usage for proprietary licenses:
#
# license = (proprietary = (defaultText = embed "license.txt"),
# notices = (defaultText = embed "notices.txt")),
union {
none @5 :Void;
# No license. Default copyright rules apply; e.g. redistribution is prohibited. See:
# http://choosealicense.com/no-license/
#
# "None" does NOT mean "public domain". See `publicDomain` below.
openSource @6 :OpenSourceLicense;
# Indicates an OSI-approved open source license.
#
# If you choose such a license, the license title will be displayed with your app on the app
# market, and users who specify they want to see only open source apps will see your app.
proprietary @7 :Util.LocalizedText;
# Full text of a non-OSI-approved license.
#
# Proprietary licenses usually not only restrict copying but also place limitations on *use*
# of the app. In other words, while open source licenses grant users additional freedoms
# compared to default copyright rules, proprietary licenses impose additional restrictions.
#
# Because of this, the user must explicitly agree to the license. Sandstorm will display the
# license to the user and ask them to agree before they can start using the app.
#
# If your license does not require such approval -- because it does not add any restrictions
# beyond default copyright protections -- consider whether it would make sense to use `none`
# instead; this will avoid prompting the user.
publicDomain @8 :Util.LocalizedText;
# Indicates that the app is placed in the public domain; you place absolutely no restrictions
# on its use or distribution. The text is your public domain dedication statement. Please
# note that public domain is not recognized in all jurisdictions, therefore using public
# domain is widely considered risky. The Open Source Initiative recommends using a permissive
# license like MIT's rather than public domain. unlicense.org provides resources to help you
# use public domain; it is highly recommended that you read it before using this.
}
notices @9 :Util.LocalizedText;
# Contains any third-party copyright notices that the app is required to display, for example
# due to use of third-party open source libraries.
}
categories @10 :List(Category);
# List of categories/genres to which this app belongs, sorted with best fit first. See the
# `Category` enum below.
#
# You can list multiple categories, but note that as with all things the app market moderators
# may ask you to make changes, e.g. if you list categories that don't fit or seem spammy.
author :group {
# Fields relating to the author of this app.
#
# The "author" might be a human, but could also be a company, or a pseudo-identity created to
# represent the app itself.
#
# It is extremely important to users that they be able to verify the author's identity in a way
# that is not susceptible to spoofing or forgery. Therefore, we *only* identify the author by
# PGP key. Various PGP infrastructure exists which can be used to determine the author's
# identity based on their PGP key. For example, Keybase.io has done a really good job of
# connecting PGP keys to other Internet identities in a verifiable way.
upstreamAuthor @19 :Text;
# 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 "ported" the app to Sandstorm.
contactEmail @11 :Text;
# 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 @12 :Data;
# 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
#
# To learn how to set up gpg, visit Keybase (https://keybase.io) -- they have excellent
# documentation and tools. Moreover, if you create a Keybase account for your key and follow
# Keybase's instructions to link it to other social accounts (like your Github account), then
# the Sandstorm app install flow and app market will present this information to the user as
# "verified".
}
pgpKeyring @13 :Data;
# 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 @14 :Util.LocalizedText;
# The app's description in Github-flavored Markdown format, to be displayed e.g.
# in an app store. Note that the Markdown is not permitted to cotnain HTML nor image tags (but
# you can include a list of screenshots separately).
shortDescription @15 :Util.LocalizedText;
# 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 @16 :List(Screenshot);
# Screenshots to use for marketing purposes.
struct Screenshot {
width @0 :UInt32;
height @1 :UInt32;
# Width and height of the screenshot in "device-independent pixels". The actual width and
# height of the image is in the image data, but this width and height is used to decide how
# much to scale the image for it to "look right". Typically, a screenshot taken on a high-DPI
# display should specify this width and height as half of the actual image width and height.
#
# The market is under no obligation to display images with any particular size; these are just
# hints.
union {
unknown @2 :Void;
# Unknown file format.
png @3 :Data;
# PNG-encoded image data. Usually preferred for screenshots.
jpeg @4 :Data;
# JPEG-encoded image data. Preferred for screenshots that contain photographs or the like.
}
}
changeLog @17 :Util.LocalizedText;
# 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.
}
struct OsiLicenseInfo {
id @0 :Text;
# The file name of the license at opensource.org, i.e. such that the URL can be constructed as:
# http://opensource.org/licenses/<id>
title @1 :Text;
# Display title for app market. E.g. "Apache License 2.0".
requireSource @2 :Bool = false;
# Whether or not you are required to provide a `codeUrl` when specifying this license.
}
annotation osiInfo @0x9476412d0315d869 (enumerant) :OsiLicenseInfo;
# Annotation applied to each item in the OpenSourceLicense enum.
enum OpenSourceLicense {
# Identities an OSI-approved Open Source license. Apps which claim to be "open source" must use
# one of these licenses.
invalid @0; # Sentinel value; do not choose this.
# Recommended licenses, especially for new code. These four licenses cover the spectrum of open
# source license mechanics and are widely recognized and understood.
mit @1 $osiInfo(id = "MIT" , title = "MIT License");
apache2 @2 $osiInfo(id = "Apache-2.0", title = "Apache License v2");
gpl3 @3 $osiInfo(id = "GPL-3.0" , title = "GNU GPL v3", requireSource = true);
agpl3 @4 $osiInfo(id = "AGPL-3.0" , title = "GNU AGPL v3", requireSource = true);
# Other popular general-purpose licenses.
bsd3Clause @5 $osiInfo(id = "BSD-3-Clause", title = "BSD 3-Clause");
bsd2Clause @6 $osiInfo(id = "BSD-2-Clause", title = "BSD 2-Clause");
gpl2 @7 $osiInfo(id = "GPL-2.0" , title = "GNU GPL v2", requireSource = true);
lgpl2 @8 $osiInfo(id = "LGPL-2.1" , title = "GNU LGPL v2.1", requireSource = true);
lgpl3 @9 $osiInfo(id = "LGPL-3.0" , title = "GNU LGPL v3", requireSource = true);
isc @10 $osiInfo(id = "ISC" , title = "ISC License");
# Popular licenses associated with specific languages.
artistic2 @11 $osiInfo(id = "Artistic-2.0", title = "Artistic License v2");
python2 @12 $osiInfo(id = "Python-2.0" , title = "Python License v2");
php3 @13 $osiInfo(id = "PHP-3.0" , title = "PHP License v3");
# Popular licenses associated with specific projects or companies.
mpl2 @14 $osiInfo(id = "MPL-2.0" , title = "Mozilla Public License v2", requireSource = true);
cddl @15 $osiInfo(id = "CDDL-1.0", title = "CDDL", requireSource = true);
epl @16 $osiInfo(id = "EPL-1.0" , title = "Eclipse Public License", requireSource = true);
cpal @17 $osiInfo(id = "CPAL-1.0" , title = "Common Public Attribution License", requireSource = true);
zlib @18 $osiInfo(id = "Zlib" , title = "Zlib/libpng License");
# Is your preferred license not on the list? We are happy to add any OSI-approved license; that
# is, anything on this page:
# http://opensource.org/licenses/alphabetical
#
# Feel free to send a pull request adding yours.
}
struct AppId {
id0 @0 :UInt64;
id1 @1 :UInt64;
id2 @2 :UInt64;
id3 @3 :UInt64;
}
struct PackageId {
id0 @0 :UInt64;
id1 @1 :UInt64;
}
struct VerifiedInfo {
# `spk verify --capnp` writes this to stdout. Also, `spk verify --details` writes a JSON version
# of this, with large `Data` and `Text` fields removed and `LocalizedText` simplified to their
# `defaultText`.
appId @0 :AppId;
packageId @1 :PackageId;
# App and package ID computed from package file signature and hash.
title @2 :Util.LocalizedText;
version @3 :UInt32;
marketingVersion @4 :Util.LocalizedText;
authorPgpKeyFingerprint @5 :Text;
metadata @6 :Metadata;
# Stuff extracted directly from manifest.
}
struct CategoryInfo {
title @0 :Text;
}
annotation categoryInfo @0x8d51dd236606d205 (enumerant) :CategoryInfo;
enum Category {
# ------------------------------------
# "Meta": communication & coordination
productivity @1 $categoryInfo(title = "Productivity");
# Apps which manage productivity -- i.e. the "meta" apps you use to "get organized", NOT the apps
# you use to actually produce content.
#
# Examples: Note-taking, to-dos, calendars, kanban boards, project management, team management.
#
# NON-examples: Document editors (-> office), e-mail (-> communications).
communications @2 $categoryInfo(title = "Communications");
# Email, chat, conferencing, etc. Things that you use primarily to communicate, not to organize.
social @3 $categoryInfo(title = "Social");
# Social networking. Overlaps with communication, but focuses on organizing a network of people
# and surfacing content and interactions from your network that aren't explicitly addressed
# to you.
# ------------------------------------
# Content creation
webPublishing @4 $categoryInfo(title = "Web Publishing");
# Tools for publishing web sites and blogs.
office @5 $categoryInfo(title = "Office");
# Tools for the office: editors for documents, spreadsheets, presentations, etc.
developerTools @6 $categoryInfo(title = "DevTools");
# Tools for software engineering: source control, test automation, compilers, IDEs, etc.
science @7 $categoryInfo(title = "Science");
# Tools for scientific / academic pursuits: data gathering, data processing, paper publishing,
# etc.
graphics @10 $categoryInfo(title = "Graphics");
# Tools for creating graphics / visual art.
# ------------------------------------
# Content consumption
media @8 $categoryInfo(title = "Media");
# Content *consumption*: Apps that aren't used to create content, but are used to display and
# consume it. Music players, photo galleries, video, feed readers, etc.
games @9 $categoryInfo(title = "Games");
# Games.
# ------------------------------------
other @0 $categoryInfo(title = "Other");
# Use if nothing else fits -- but consider sending us a pull request to add a better category!
}
# ==============================================================================
# Below this point is not interesting to app developers.
#
# TODO(cleanup): Maybe move elsewhere?
struct KeyFile {
# A public/private key pair, as generated by libsodium's crypto_sign_keypair.
#
# The keyring maintained by the spk tool contains a sequence of these.
#
# TODO(someday): Integrate with desktop environment's keychain for more secure storage.
publicKey @0 :Data;
privateKey @1 :Data;
}
const magicNumber :Data = "\x8f\xc6\xcd\xef\x45\x1a\xea\x96";
# A sandstorm package is a file composed of two messages: a `Signature` and an `Archive`.
# Additionally, the whole file is XZ-compressed on top of that, and the XZ data is prefixed with
# `magicNumber`. (If a future version of the package format breaks compatibility, the magic number
# will change.)
struct Signature {
# Contains a cryptographic signature of the `Archive` part of the package, along with the public
# key used to verify that signature. The public key itself is the application ID, thus all
# packages signed with the same key will be considered to be different versions of the same app.
publicKey @0 :Data;
# A libsodium crypto_sign public key.
#
# libsodium signing public keys are 32 bytes. The application's ID is simply a textual
# representation of this key.
signature @1 :Data;
# libsodium crypto_sign signature of the crypto_hash of the `Archive` part of the package
# (i.e. the package file minus the header).
}
struct Archive {
# A tree of files. Used to represent the package contents.
files @0 :List(File);
struct File {
name @0 :Text;
# Name of the file.
#
# Must not contain forward slashes nor NUL characters. Must not be "." nor "..". Must not
# be the same as any other file in the directory.
lastModificationTimeNs @5 :Int64;
# Modification timestamp to apply to the file after unpack. Measured in nanoseconds.
union {
regular @1 :Data;
# Content of a regular file.
executable @2 :Data;
# Content of an executable.
symlink @3 :Text;
# Symbolic link path. The link will be interpreted in the context of the sandbox, where the
# archive itself mounted as the root directory.
directory @4 :List(File);
# A subdirectory containing a list of files.
}
}
}