sigit-code 1.1.0__tar.gz → 1.2.0__tar.gz
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.
- {sigit_code-1.1.0 → sigit_code-1.2.0}/CHANGELOG.md +10 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/Cargo.lock +59 -6
- {sigit_code-1.1.0 → sigit_code-1.2.0}/Cargo.toml +5 -2
- {sigit_code-1.1.0 → sigit_code-1.2.0}/PKG-INFO +1 -1
- sigit_code-1.2.0/src/account.rs +158 -0
- sigit_code-1.2.0/src/backend.rs +444 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/src/chat.rs +120 -29
- sigit_code-1.2.0/src/credentials.rs +107 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/src/main.rs +109 -30
- {sigit_code-1.1.0 → sigit_code-1.2.0}/src/models.rs +44 -1
- sigit_code-1.2.0/src/provider.rs +239 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.agents/AGENTS.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.agents/skills/agent-client-protocol/SKILL.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.agents/skills/ai-assisted-coding/SKILL.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.agents/skills/branding/SKILL.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.agents/skills/sigit-code-release/SKILL.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.agents/skills/tool-calling/SKILL.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.github/workflows/ci.yml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.github/workflows/release-crates.yml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.github/workflows/release-github.yml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.github/workflows/release-homebrew.yml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.github/workflows/release-npm.yml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.github/workflows/release-pypi.yml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.gitignore +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/.nvmrc +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/LICENSE +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/README.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/README.md.tmpl +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/package-main.json.tmpl +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/package.json.tmpl +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/scripts/render-main-package.cjs +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/scripts/render-platform-package.cjs +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/sigit/.gitignore +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/sigit/README.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/sigit/package.json +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/sigit/src/index.ts +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/npm/sigit/tsconfig.json +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/pypi/README.md +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/pypi/pyproject.toml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/pyproject.toml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/rust-toolchain.toml +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/src/setup.rs +0 -0
- {sigit_code-1.1.0 → sigit_code-1.2.0}/src/tools.rs +0 -0
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
Adds siGit Code Cloud — a hosted inference tier alongside on-device models.
|
|
6
|
+
|
|
7
|
+
### What changed
|
|
8
|
+
|
|
9
|
+
- Added siGit Code Cloud with cloud-tier routing, pointed at `sigit.si`
|
|
10
|
+
- Added account management slash commands and surfaced cloud tiers in `/models`
|
|
11
|
+
- Carried forward from 1.1.0: ACP SDK v0.13, refreshed dependencies and branding
|
|
12
|
+
|
|
3
13
|
## 1.1.0
|
|
4
14
|
|
|
5
15
|
Bumps the ACP SDK to v0.13 and pulls in updated dependencies.
|
|
@@ -3647,7 +3647,7 @@ dependencies = [
|
|
|
3647
3647
|
"tokio-tungstenite",
|
|
3648
3648
|
"toktrie",
|
|
3649
3649
|
"toktrie_hf_tokenizers",
|
|
3650
|
-
"toml",
|
|
3650
|
+
"toml 0.9.12+spec-1.1.0",
|
|
3651
3651
|
"tracing",
|
|
3652
3652
|
"tracing-subscriber",
|
|
3653
3653
|
"urlencoding",
|
|
@@ -5073,6 +5073,15 @@ dependencies = [
|
|
|
5073
5073
|
"syn 2.0.117",
|
|
5074
5074
|
]
|
|
5075
5075
|
|
|
5076
|
+
[[package]]
|
|
5077
|
+
name = "serde_spanned"
|
|
5078
|
+
version = "0.6.9"
|
|
5079
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5080
|
+
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
|
5081
|
+
dependencies = [
|
|
5082
|
+
"serde",
|
|
5083
|
+
]
|
|
5084
|
+
|
|
5076
5085
|
[[package]]
|
|
5077
5086
|
name = "serde_spanned"
|
|
5078
5087
|
version = "1.1.1"
|
|
@@ -5180,10 +5189,11 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
|
|
5180
5189
|
|
|
5181
5190
|
[[package]]
|
|
5182
5191
|
name = "sigit"
|
|
5183
|
-
version = "1.
|
|
5192
|
+
version = "1.2.0"
|
|
5184
5193
|
dependencies = [
|
|
5185
5194
|
"agent-client-protocol",
|
|
5186
5195
|
"anyhow",
|
|
5196
|
+
"async-trait",
|
|
5187
5197
|
"crossterm 0.29.0",
|
|
5188
5198
|
"futures",
|
|
5189
5199
|
"libc",
|
|
@@ -5192,9 +5202,11 @@ dependencies = [
|
|
|
5192
5202
|
"ratatui",
|
|
5193
5203
|
"regex",
|
|
5194
5204
|
"reqwest 0.12.28",
|
|
5205
|
+
"serde",
|
|
5195
5206
|
"serde_json",
|
|
5196
5207
|
"tokio",
|
|
5197
5208
|
"tokio-util",
|
|
5209
|
+
"toml 0.8.23",
|
|
5198
5210
|
"tracing-subscriber",
|
|
5199
5211
|
"uuid 1.23.3",
|
|
5200
5212
|
]
|
|
@@ -6179,6 +6191,18 @@ dependencies = [
|
|
|
6179
6191
|
"toktrie",
|
|
6180
6192
|
]
|
|
6181
6193
|
|
|
6194
|
+
[[package]]
|
|
6195
|
+
name = "toml"
|
|
6196
|
+
version = "0.8.23"
|
|
6197
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6198
|
+
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
|
6199
|
+
dependencies = [
|
|
6200
|
+
"serde",
|
|
6201
|
+
"serde_spanned 0.6.9",
|
|
6202
|
+
"toml_datetime 0.6.11",
|
|
6203
|
+
"toml_edit",
|
|
6204
|
+
]
|
|
6205
|
+
|
|
6182
6206
|
[[package]]
|
|
6183
6207
|
name = "toml"
|
|
6184
6208
|
version = "0.9.12+spec-1.1.0"
|
|
@@ -6187,13 +6211,22 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
|
|
|
6187
6211
|
dependencies = [
|
|
6188
6212
|
"indexmap 2.14.0",
|
|
6189
6213
|
"serde_core",
|
|
6190
|
-
"serde_spanned",
|
|
6191
|
-
"toml_datetime",
|
|
6214
|
+
"serde_spanned 1.1.1",
|
|
6215
|
+
"toml_datetime 0.7.5+spec-1.1.0",
|
|
6192
6216
|
"toml_parser",
|
|
6193
6217
|
"toml_writer",
|
|
6194
6218
|
"winnow 0.7.15",
|
|
6195
6219
|
]
|
|
6196
6220
|
|
|
6221
|
+
[[package]]
|
|
6222
|
+
name = "toml_datetime"
|
|
6223
|
+
version = "0.6.11"
|
|
6224
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6225
|
+
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
|
6226
|
+
dependencies = [
|
|
6227
|
+
"serde",
|
|
6228
|
+
]
|
|
6229
|
+
|
|
6197
6230
|
[[package]]
|
|
6198
6231
|
name = "toml_datetime"
|
|
6199
6232
|
version = "0.7.5+spec-1.1.0"
|
|
@@ -6203,6 +6236,20 @@ dependencies = [
|
|
|
6203
6236
|
"serde_core",
|
|
6204
6237
|
]
|
|
6205
6238
|
|
|
6239
|
+
[[package]]
|
|
6240
|
+
name = "toml_edit"
|
|
6241
|
+
version = "0.22.27"
|
|
6242
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6243
|
+
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
|
6244
|
+
dependencies = [
|
|
6245
|
+
"indexmap 2.14.0",
|
|
6246
|
+
"serde",
|
|
6247
|
+
"serde_spanned 0.6.9",
|
|
6248
|
+
"toml_datetime 0.6.11",
|
|
6249
|
+
"toml_write",
|
|
6250
|
+
"winnow 0.7.15",
|
|
6251
|
+
]
|
|
6252
|
+
|
|
6206
6253
|
[[package]]
|
|
6207
6254
|
name = "toml_parser"
|
|
6208
6255
|
version = "1.1.2+spec-1.1.0"
|
|
@@ -6212,6 +6259,12 @@ dependencies = [
|
|
|
6212
6259
|
"winnow 1.0.3",
|
|
6213
6260
|
]
|
|
6214
6261
|
|
|
6262
|
+
[[package]]
|
|
6263
|
+
name = "toml_write"
|
|
6264
|
+
version = "0.1.2"
|
|
6265
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6266
|
+
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
|
6267
|
+
|
|
6215
6268
|
[[package]]
|
|
6216
6269
|
name = "toml_writer"
|
|
6217
6270
|
version = "1.1.1+spec-1.1.0"
|
|
@@ -6528,7 +6581,7 @@ dependencies = [
|
|
|
6528
6581
|
"serde",
|
|
6529
6582
|
"tempfile",
|
|
6530
6583
|
"textwrap 0.16.2",
|
|
6531
|
-
"toml",
|
|
6584
|
+
"toml 0.9.12+spec-1.1.0",
|
|
6532
6585
|
"uniffi_internal_macros",
|
|
6533
6586
|
"uniffi_meta",
|
|
6534
6587
|
"uniffi_pipeline",
|
|
@@ -6585,7 +6638,7 @@ dependencies = [
|
|
|
6585
6638
|
"quote",
|
|
6586
6639
|
"serde",
|
|
6587
6640
|
"syn 2.0.117",
|
|
6588
|
-
"toml",
|
|
6641
|
+
"toml 0.9.12+spec-1.1.0",
|
|
6589
6642
|
"uniffi_meta",
|
|
6590
6643
|
]
|
|
6591
6644
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "sigit"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.2.0"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
description = "siGit Code — ACP-compatible AI coding agent. Sí, git."
|
|
6
6
|
documentation = "https://github.com/getsigit/sigit"
|
|
@@ -38,7 +38,10 @@ anyhow = "1"
|
|
|
38
38
|
libc = "0.2"
|
|
39
39
|
log = "0.4"
|
|
40
40
|
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
|
|
41
|
+
serde = { version = "1", features = ["derive"] }
|
|
41
42
|
serde_json = "1"
|
|
43
|
+
toml = "0.8"
|
|
44
|
+
async-trait = "0.1"
|
|
42
45
|
regex = "1"
|
|
43
|
-
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] }
|
|
46
|
+
reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls"] }
|
|
44
47
|
uuid = { version = "1", features = ["v4"] }
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
//! Account access for siGit Code Cloud, surfaced as the `/login`, `/logout`,
|
|
2
|
+
//! and `/whoami` slash commands in both the TUI and ACP sessions.
|
|
3
|
+
//!
|
|
4
|
+
//! These functions authenticate against the siGit account API and store a
|
|
5
|
+
//! session token locally. The token is the credential used for siGit Code Cloud
|
|
6
|
+
//! requests. They perform no console I/O, so each slash surface can render the
|
|
7
|
+
//! returned message however it likes.
|
|
8
|
+
//!
|
|
9
|
+
//! Base URL: `$SIGIT_API_URL`, else `https://sigit.si`.
|
|
10
|
+
|
|
11
|
+
use serde::Deserialize;
|
|
12
|
+
|
|
13
|
+
use crate::credentials::{self, Credentials};
|
|
14
|
+
|
|
15
|
+
/// Default account API host. Override with `SIGIT_API_URL` (dev: `http://localhost:8088`).
|
|
16
|
+
const DEFAULT_API_URL: &str = "https://sigit.si";
|
|
17
|
+
|
|
18
|
+
fn api_base() -> String {
|
|
19
|
+
std::env::var("SIGIT_API_URL").unwrap_or_else(|_| DEFAULT_API_URL.to_string())
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Sign-in returns an `AccountStatus`, one of:
|
|
23
|
+
// "NotFound" (a bare JSON string)
|
|
24
|
+
// {"Ready":{"access_token":"…"}}
|
|
25
|
+
// {"Incomplete":{"status":<u32>}}
|
|
26
|
+
// Failures return {"error_code":<i32>,"message":"…"}. Parsed from a
|
|
27
|
+
// `serde_json::Value` rather than a struct because of the bare-string variant.
|
|
28
|
+
|
|
29
|
+
#[derive(Debug, Deserialize)]
|
|
30
|
+
struct MeResponse {
|
|
31
|
+
#[serde(default)]
|
|
32
|
+
email: Option<String>,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Authenticate with email and password, storing the session token on success.
|
|
36
|
+
/// Returns the signed-in email, or a human-readable error message.
|
|
37
|
+
pub async fn authenticate(email: &str, password: &str) -> Result<String, String> {
|
|
38
|
+
let email = email.trim();
|
|
39
|
+
if email.is_empty() || password.is_empty() {
|
|
40
|
+
return Err("email and password are required".to_string());
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let url = format!("{}/api/v1/auth/sign_in", api_base().trim_end_matches('/'));
|
|
44
|
+
let response = reqwest::Client::new()
|
|
45
|
+
.post(&url)
|
|
46
|
+
.json(&serde_json::json!({ "email": email, "password": password }))
|
|
47
|
+
.send()
|
|
48
|
+
.await
|
|
49
|
+
.map_err(|error| format!("could not reach siGit Code Cloud: {error}"))?;
|
|
50
|
+
|
|
51
|
+
let status = response.status();
|
|
52
|
+
let body: serde_json::Value = response
|
|
53
|
+
.json()
|
|
54
|
+
.await
|
|
55
|
+
.map_err(|error| format!("unexpected response from siGit Code Cloud: {error}"))?;
|
|
56
|
+
|
|
57
|
+
if status.is_success() {
|
|
58
|
+
// AccountStatus::Ready
|
|
59
|
+
if let Some(token) = body
|
|
60
|
+
.get("Ready")
|
|
61
|
+
.and_then(|ready| ready.get("access_token"))
|
|
62
|
+
.and_then(|token| token.as_str())
|
|
63
|
+
.filter(|token| !token.trim().is_empty())
|
|
64
|
+
{
|
|
65
|
+
credentials::store(&Credentials {
|
|
66
|
+
access_token: token.to_string(),
|
|
67
|
+
email: Some(email.to_string()),
|
|
68
|
+
})?;
|
|
69
|
+
return Ok(email.to_string());
|
|
70
|
+
}
|
|
71
|
+
// AccountStatus::Incomplete
|
|
72
|
+
if body.get("Incomplete").is_some() {
|
|
73
|
+
return Err(
|
|
74
|
+
"your account is not verified yet. Check your email to confirm it, then sign in again."
|
|
75
|
+
.to_string(),
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
// AccountStatus::NotFound (a bare JSON string)
|
|
79
|
+
if body.as_str() == Some("NotFound") {
|
|
80
|
+
return Err(format!("no siGit account found for {email}."));
|
|
81
|
+
}
|
|
82
|
+
return Err("unexpected sign-in response from siGit Code Cloud".to_string());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ErrorResponse { error_code, message }
|
|
86
|
+
let message = body
|
|
87
|
+
.get("message")
|
|
88
|
+
.and_then(|message| message.as_str())
|
|
89
|
+
.unwrap_or("sign-in failed");
|
|
90
|
+
Err(format!("sign-in failed: {message}"))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// Clear the local session, notifying the server best-effort. Returns a message
|
|
94
|
+
/// suitable for display.
|
|
95
|
+
pub async fn end_session() -> String {
|
|
96
|
+
if let Some(token) = credentials::load_token() {
|
|
97
|
+
let url = format!("{}/api/v1/auth/sign_out", api_base().trim_end_matches('/'));
|
|
98
|
+
// A failed server call must not block local sign-out.
|
|
99
|
+
let _ = reqwest::Client::new()
|
|
100
|
+
.delete(&url)
|
|
101
|
+
.bearer_auth(&token)
|
|
102
|
+
.send()
|
|
103
|
+
.await;
|
|
104
|
+
}
|
|
105
|
+
if credentials::clear() {
|
|
106
|
+
"Signed out of siGit Code Cloud.".to_string()
|
|
107
|
+
} else {
|
|
108
|
+
"Not signed in.".to_string()
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/// One-line description of the current session, verifying the token if reachable.
|
|
113
|
+
pub async fn status_line() -> String {
|
|
114
|
+
let Some(creds) = credentials::load() else {
|
|
115
|
+
return "Not signed in. Use `/login <email> <password>` to use siGit Code Cloud."
|
|
116
|
+
.to_string();
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
let url = format!("{}/api/v1/me", api_base().trim_end_matches('/'));
|
|
120
|
+
match reqwest::Client::new()
|
|
121
|
+
.get(&url)
|
|
122
|
+
.bearer_auth(&creds.access_token)
|
|
123
|
+
.send()
|
|
124
|
+
.await
|
|
125
|
+
{
|
|
126
|
+
Ok(response) if response.status().is_success() => {
|
|
127
|
+
let email = response
|
|
128
|
+
.json::<MeResponse>()
|
|
129
|
+
.await
|
|
130
|
+
.ok()
|
|
131
|
+
.and_then(|me| me.email)
|
|
132
|
+
.or(creds.email)
|
|
133
|
+
.unwrap_or_else(|| "(unknown)".to_string());
|
|
134
|
+
format!("Signed in to siGit Code Cloud as {email}.")
|
|
135
|
+
}
|
|
136
|
+
Ok(response) => format!(
|
|
137
|
+
"Session may be expired (HTTP {}). Use `/login` again.",
|
|
138
|
+
response.status().as_u16()
|
|
139
|
+
),
|
|
140
|
+
Err(_) => {
|
|
141
|
+
let email = creds.email.unwrap_or_else(|| "(unknown)".to_string());
|
|
142
|
+
format!("Signed in as {email} (could not reach siGit Code Cloud to verify).")
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/// Split a `/login` argument into `(email, password)`. The password is the rest
|
|
148
|
+
/// of the line after the first whitespace, so it may contain spaces.
|
|
149
|
+
pub fn parse_login_args(arg: &str) -> Option<(String, String)> {
|
|
150
|
+
let mut parts = arg.trim().splitn(2, char::is_whitespace);
|
|
151
|
+
let email = parts.next().unwrap_or("").trim();
|
|
152
|
+
let password = parts.next().unwrap_or("").trim();
|
|
153
|
+
if email.is_empty() || password.is_empty() {
|
|
154
|
+
None
|
|
155
|
+
} else {
|
|
156
|
+
Some((email.to_string(), password.to_string()))
|
|
157
|
+
}
|
|
158
|
+
}
|