@silo-ai/silo 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,188 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/silo-ai/silo/skills/silo/schemas/table-create.schema.json",
4
+ "title": "Silo table creation request",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["name", "comment", "columns"],
8
+ "properties": {
9
+ "name": { "$ref": "#/$defs/identifier" },
10
+ "comment": { "type": "string", "minLength": 1 },
11
+ "columns": { "type": "array", "items": { "$ref": "#/$defs/column" } },
12
+ "primary_key": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" } },
13
+ "foreign_keys": { "type": "array", "items": { "$ref": "#/$defs/foreignKey" } },
14
+ "unique_constraints": { "type": "array", "items": { "$ref": "#/$defs/unique" } },
15
+ "indexes": { "type": "array", "items": { "$ref": "#/$defs/index" } },
16
+ "checks": { "type": "array", "items": { "$ref": "#/$defs/check" } },
17
+ "policies": { "type": "array", "items": { "$ref": "#/$defs/policy" } },
18
+ "strict": { "type": "boolean", "default": true },
19
+ "without_rowid": { "type": "boolean", "default": false }
20
+ },
21
+ "$defs": {
22
+ "identifier": {
23
+ "type": "string",
24
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
25
+ "not": { "pattern": "^_[sS][iI][lL][oO]_" }
26
+ },
27
+ "column": {
28
+ "type": "object",
29
+ "additionalProperties": false,
30
+ "required": ["name", "type", "comment"],
31
+ "properties": {
32
+ "name": { "$ref": "#/$defs/identifier" },
33
+ "type": { "type": "string", "minLength": 1 },
34
+ "type_options": { "type": "object" },
35
+ "nullable": { "type": "boolean", "default": true },
36
+ "comment": { "type": "string", "minLength": 1 },
37
+ "collate": { "$ref": "#/$defs/identifier" },
38
+ "default": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "minProperties": 1,
42
+ "maxProperties": 1,
43
+ "properties": {
44
+ "literal": {},
45
+ "expression": { "type": "string", "minLength": 1 }
46
+ }
47
+ },
48
+ "generated": {
49
+ "type": "object",
50
+ "additionalProperties": false,
51
+ "required": ["expression"],
52
+ "properties": {
53
+ "expression": { "type": "string", "minLength": 1 },
54
+ "storage": { "enum": ["VIRTUAL", "STORED"] }
55
+ }
56
+ }
57
+ }
58
+ },
59
+ "foreignKey": {
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": ["columns", "references"],
63
+ "properties": {
64
+ "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" } },
65
+ "references": {
66
+ "type": "object",
67
+ "additionalProperties": false,
68
+ "required": ["table", "columns"],
69
+ "properties": {
70
+ "table": { "$ref": "#/$defs/identifier" },
71
+ "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" } }
72
+ }
73
+ },
74
+ "on_update": { "$ref": "#/$defs/action" },
75
+ "on_delete": { "$ref": "#/$defs/action" },
76
+ "deferrable": { "type": "boolean" },
77
+ "initially_deferred": { "type": "boolean" }
78
+ }
79
+ },
80
+ "action": { "enum": ["NO ACTION", "RESTRICT", "SET NULL", "SET DEFAULT", "CASCADE"] },
81
+ "unique": {
82
+ "type": "object",
83
+ "additionalProperties": false,
84
+ "required": ["columns"],
85
+ "properties": {
86
+ "name": { "$ref": "#/$defs/identifier" },
87
+ "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" } }
88
+ }
89
+ },
90
+ "check": {
91
+ "type": "object",
92
+ "additionalProperties": false,
93
+ "required": ["expression"],
94
+ "properties": {
95
+ "name": { "$ref": "#/$defs/identifier" },
96
+ "expression": { "type": "string", "minLength": 1 },
97
+ "comment": { "type": "string" }
98
+ }
99
+ },
100
+ "indexPart": {
101
+ "type": "object",
102
+ "additionalProperties": false,
103
+ "oneOf": [{ "required": ["column"] }, { "required": ["expression"] }],
104
+ "properties": {
105
+ "column": { "$ref": "#/$defs/identifier" },
106
+ "expression": { "type": "string", "minLength": 1 },
107
+ "direction": { "enum": ["ASC", "DESC"] },
108
+ "collate": { "$ref": "#/$defs/identifier" }
109
+ }
110
+ },
111
+ "index": {
112
+ "type": "object",
113
+ "additionalProperties": false,
114
+ "required": ["columns"],
115
+ "properties": {
116
+ "name": { "$ref": "#/$defs/identifier" },
117
+ "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/indexPart" } },
118
+ "unique": { "type": "boolean" },
119
+ "where": { "type": "string", "minLength": 1 },
120
+ "comment": { "type": "string" }
121
+ }
122
+ },
123
+ "policy": {
124
+ "oneOf": [
125
+ {
126
+ "type": "object",
127
+ "additionalProperties": false,
128
+ "required": ["type", "column", "strategy"],
129
+ "properties": {
130
+ "type": { "const": "generated_identity" },
131
+ "column": { "$ref": "#/$defs/identifier" },
132
+ "strategy": { "enum": ["integer", "uuid", "ulid"] }
133
+ }
134
+ },
135
+ {
136
+ "type": "object",
137
+ "additionalProperties": false,
138
+ "required": ["type"],
139
+ "anyOf": [{ "required": ["created_column"] }, { "required": ["updated_column"] }],
140
+ "properties": {
141
+ "type": { "const": "timestamps" },
142
+ "created_column": { "$ref": "#/$defs/identifier" },
143
+ "updated_column": { "$ref": "#/$defs/identifier" }
144
+ }
145
+ },
146
+ {
147
+ "type": "object",
148
+ "additionalProperties": false,
149
+ "required": ["type", "column"],
150
+ "properties": {
151
+ "type": { "const": "optimistic_revision" },
152
+ "column": { "$ref": "#/$defs/identifier" },
153
+ "initial": { "type": "integer" }
154
+ }
155
+ },
156
+ {
157
+ "type": "object",
158
+ "additionalProperties": false,
159
+ "required": ["type"],
160
+ "properties": { "type": { "enum": ["immutable_rows", "append_only"] } }
161
+ },
162
+ {
163
+ "type": "object",
164
+ "additionalProperties": false,
165
+ "required": ["type", "columns"],
166
+ "properties": {
167
+ "type": { "const": "immutable_columns" },
168
+ "columns": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/identifier" } }
169
+ }
170
+ },
171
+ {
172
+ "type": "object",
173
+ "additionalProperties": false,
174
+ "required": ["type", "columns"],
175
+ "properties": {
176
+ "type": { "const": "natural_key_upsert" },
177
+ "columns": {
178
+ "type": "array",
179
+ "minItems": 1,
180
+ "items": { "$ref": "#/$defs/identifier" }
181
+ },
182
+ "update_columns": { "type": "array", "items": { "$ref": "#/$defs/identifier" } }
183
+ }
184
+ }
185
+ ]
186
+ }
187
+ }
188
+ }
@@ -0,0 +1,25 @@
1
+ # Make an additive schema change
2
+
3
+ > Extend an existing table without invoking an unsupported or destructive table rebuild.
4
+
5
+ Inspect [the alteration request schema](../schemas/table-alter.schema.json), then add a nullable column and an index:
6
+
7
+ ```sh
8
+ silo table alter issues <<'JSON'
9
+ {
10
+ "add_columns": [
11
+ {
12
+ "name": "owner",
13
+ "type": "text",
14
+ "nullable": true,
15
+ "comment": "Agent or team currently responsible for the issue; NULL means unassigned."
16
+ }
17
+ ],
18
+ "add_indexes": [
19
+ { "columns": [{ "column": "owner" }] }
20
+ ]
21
+ }
22
+ JSON
23
+ ```
24
+
25
+ Verify the new logical definition with `silo table show issues`. Initial Silo alterations do not rename or drop columns, tighten nullability, change keys or types, or modify policies.
@@ -0,0 +1,43 @@
1
+ # Create a refreshable report
2
+
3
+ Use a report when a human should revisit a stable explanation whose factual tables come from current Silo data. Keep changing facts inside query slots; refreshing does not ask an agent to rewrite ordinary Markdown.
4
+
5
+ Read [the report request schema](../schemas/report-put.schema.json), then define the report and every referenced query:
6
+
7
+ ```json
8
+ {
9
+ "slug": "execution-brief",
10
+ "title": "Project execution brief",
11
+ "markdown": "# Project execution brief\n\n## Work by status\n\n{{silo-query:work_by_status}}",
12
+ "queries": [
13
+ {
14
+ "name": "work_by_status",
15
+ "sql": "SELECT status, count(*) AS tasks FROM tasks GROUP BY status ORDER BY tasks DESC",
16
+ "empty_markdown": "_No tasks._"
17
+ }
18
+ ]
19
+ }
20
+ ```
21
+
22
+ Save and perform the initial refresh atomically:
23
+
24
+ ```sh
25
+ silo report put --file execution-brief.json
26
+ ```
27
+
28
+ Use `ORDER BY` whenever presentation order matters. Each query must be one read-only statement, every saved query must have a matching `{{silo-query:name}}` slot, and every slot must name a saved query. Failed replacements leave an existing valid report unchanged.
29
+
30
+ Inspect or refresh the saved report:
31
+
32
+ ```sh
33
+ silo report show execution-brief
34
+ silo report refresh execution-brief
35
+ ```
36
+
37
+ Open the packaged human viewer when the report is ready to hand off:
38
+
39
+ ```sh
40
+ silo report open execution-brief
41
+ ```
42
+
43
+ The foreground command serves only on loopback and runs until interrupted. The page shows the last successful rendering immediately and refreshes in the background after opening or regaining focus; a refresh error leaves that rendering visible.
@@ -0,0 +1,36 @@
1
+ # Create a table
2
+
3
+ > Define a durable entity with comments, semantic types, keys, and policies before writing rows.
4
+
5
+ Inspect [the table request schema](../schemas/table-create.schema.json), then create an `issues` table:
6
+
7
+ ```sh
8
+ silo table create <<'JSON'
9
+ {
10
+ "name": "issues",
11
+ "comment": "One actionable repository issue; read before planning work.",
12
+ "columns": [
13
+ { "name": "id", "type": "text/uuid", "nullable": false, "comment": "Stable generated issue identifier." },
14
+ { "name": "title", "type": "text", "nullable": false, "comment": "Short actionable summary." },
15
+ { "name": "context", "type": "text/json", "nullable": false, "comment": "Structured labels and routing context." }
16
+ ],
17
+ "primary_key": ["id"],
18
+ "policies": [
19
+ { "type": "generated_identity", "column": "id", "strategy": "uuid" }
20
+ ]
21
+ }
22
+ JSON
23
+ ```
24
+
25
+ The first schema mutation also creates the workspace database. Add a row with native JSON rather than a serialized JSON string:
26
+
27
+ ```sh
28
+ silo row add issues <<'JSON'
29
+ {
30
+ "title": "Document release process",
31
+ "context": { "labels": ["docs", "release"] }
32
+ }
33
+ JSON
34
+ ```
35
+
36
+ The output includes the generated UUID and canonical persisted values. Verify the logical contract with `silo table show issues`.
@@ -0,0 +1,27 @@
1
+ # Query with SQL
2
+
3
+ > Use SQLite-native reads for joins, aggregates, CTEs, windows, and JSON operations without enabling mutation.
4
+
5
+ Add explicit ordering whenever result order matters:
6
+
7
+ ```sh
8
+ silo sql '
9
+ SELECT status, count(*) AS issue_count
10
+ FROM issues
11
+ GROUP BY status
12
+ ORDER BY status
13
+ '
14
+ ```
15
+
16
+ For longer queries, send SQL through stdin:
17
+
18
+ ```sh
19
+ silo sql <<'SQL'
20
+ WITH recent AS (
21
+ SELECT * FROM issues ORDER BY created_at DESC LIMIT 10
22
+ )
23
+ SELECT id, title FROM recent ORDER BY created_at DESC;
24
+ SQL
25
+ ```
26
+
27
+ The connection is read-only. Use row commands for mutations and remember that exact decimals and semantic versions do not have numerically meaningful lexical ordering.
@@ -0,0 +1,34 @@
1
+ # Synchronize a database
2
+
3
+ > Exchange local Silo transactions through an already authorized S3-compatible remote without silently choosing a conflict winner.
4
+
5
+ Before initialization, verify Litestream 0.5.12 or newer is installed and that the standard AWS credential environment is available to both Silo and Litestream. Keep the active database on local storage.
6
+
7
+ Initialize once, then inspect the result:
8
+
9
+ ```sh
10
+ silo sync init s3://my-bucket/silo/project
11
+ silo sync status
12
+ ```
13
+
14
+ An existing local database with an empty remote becomes `ahead`; push it to establish remote `HEAD`. An absent local database restores an existing remote. Do not attempt to combine an existing unconfigured local database with an existing remote.
15
+
16
+ For normal shared work:
17
+
18
+ ```sh
19
+ silo pull
20
+ # Inspect and mutate through ordinary Silo commands.
21
+ silo push
22
+ ```
23
+
24
+ Treat `ahead`, `behind`, and `diverged` as synchronization state, not errors to bypass. Pull rebases non-conflicting pending row transactions. If status is `conflicted`, preserve any values needed from the identified operation, then discard only that transaction and issue a deliberate reconciled mutation:
25
+
26
+ ```sh
27
+ silo sync discard <transaction-id>
28
+ ```
29
+
30
+ Discard rebuilds from remote and replays the remaining pending transactions; it permanently removes the selected transaction's effects. Never delete an outbox row directly.
31
+
32
+ Schema commands require `clean` status and no pending data transaction. Pull first, make one schema mutation, and push it before further work. Concurrent schema changes do not merge; discard the losing schema transaction, adopt the remote winner, and reapply a compatible change deliberately.
33
+
34
+ Synchronization is explicit. There is no background replication, Git-style history, automatic conflict winner, or automatic remote generation cleanup.
@@ -0,0 +1,22 @@
1
+ # Update with optimistic revision
2
+
3
+ > Apply a change only when the row still has the revision previously read by the agent.
4
+
5
+ First read the current row and retain its `revision` value:
6
+
7
+ ```sh
8
+ silo row get issues 550e8400-e29b-41d4-a716-446655440000
9
+ ```
10
+
11
+ If the row reports revision `3`, submit the expected revision with the changed fields:
12
+
13
+ ```sh
14
+ silo row update issues 550e8400-e29b-41d4-a716-446655440000 <<'JSON'
15
+ {
16
+ "title": "Document and automate release process",
17
+ "_expected_revision": 3
18
+ }
19
+ JSON
20
+ ```
21
+
22
+ On a revision conflict, reread the row and reconcile the other writer's changes. Never retry blindly with a newer revision.
@@ -0,0 +1,18 @@
1
+ # Perform an idempotent upsert
2
+
3
+ > Repeat a write safely when the table declares a natural conflict key and allowed update fields.
4
+
5
+ Confirm that `silo table show dependencies` lists a `natural_key_upsert` policy. Then upsert through that declared key:
6
+
7
+ ```sh
8
+ silo row upsert dependencies <<'JSON'
9
+ {
10
+ "package": "better-sqlite3",
11
+ "latest_version": "12.4.1"
12
+ }
13
+ JSON
14
+ ```
15
+
16
+ Running the same command again updates only the fields allowed by the policy. If the table has no such policy, use an explicit read followed by insert or update instead.
17
+
18
+ When no update fields are needed, supply only the complete natural key. Silo performs a no-op and returns the existing persisted row instead of issuing an empty update.