chore: import upstream snapshot with attribution
FreeBSD Smoke / FreeBSD Smoke (x86_64) (push) Has been cancelled
CI / Quality Guardrails (push) Has been cancelled
CI / Build & Test (macos-latest) (push) Has been cancelled
CI / Build & Test (ubuntu-latest) (push) Has been cancelled
CI / Build & Test (windows-latest) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / PowerShell Syntax (push) Has been cancelled
CI / Windows Cross-Target Check (Linux) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:10:34 +08:00
commit a789495a98
1551 changed files with 718128 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
[package]
name = "jcode-task-types"
version = "0.1.0"
edition = "2024"
publish = false
[dependencies]
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1", features = ["derive"] }
+281
View File
@@ -0,0 +1,281 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "snake_case")]
pub enum GoalScope {
Global,
#[default]
Project,
}
impl GoalScope {
pub fn parse(value: &str) -> Option<Self> {
match value.trim().to_ascii_lowercase().as_str() {
"global" => Some(Self::Global),
"project" => Some(Self::Project),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Global => "global",
Self::Project => "project",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "snake_case")]
pub enum GoalStatus {
Draft,
#[default]
Active,
Paused,
Blocked,
Completed,
Archived,
Abandoned,
}
impl GoalStatus {
pub fn parse(value: &str) -> Option<Self> {
match value.trim().to_ascii_lowercase().as_str() {
"draft" => Some(Self::Draft),
"active" => Some(Self::Active),
"paused" => Some(Self::Paused),
"blocked" => Some(Self::Blocked),
"completed" => Some(Self::Completed),
"archived" => Some(Self::Archived),
"abandoned" => Some(Self::Abandoned),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Draft => "draft",
Self::Active => "active",
Self::Paused => "paused",
Self::Blocked => "blocked",
Self::Completed => "completed",
Self::Archived => "archived",
Self::Abandoned => "abandoned",
}
}
pub fn sort_rank(self) -> u8 {
match self {
Self::Active => 0,
Self::Blocked => 1,
Self::Draft => 2,
Self::Paused => 3,
Self::Completed => 4,
Self::Archived => 5,
Self::Abandoned => 6,
}
}
pub fn is_resumable(self) -> bool {
matches!(self, Self::Active | Self::Blocked | Self::Draft)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct GoalStep {
pub id: String,
pub content: String,
#[serde(default = "default_pending_status")]
pub status: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct GoalMilestone {
pub id: String,
pub title: String,
#[serde(default = "default_pending_status")]
pub status: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub steps: Vec<GoalStep>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct GoalUpdate {
pub at: DateTime<Utc>,
pub summary: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Goal {
pub id: String,
pub title: String,
#[serde(default)]
pub scope: GoalScope,
#[serde(default)]
pub status: GoalStatus,
#[serde(default)]
pub description: String,
#[serde(default)]
pub why: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub success_criteria: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub milestones: Vec<GoalMilestone>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub next_steps: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub blockers: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_milestone_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub progress_percent: Option<u8>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub updates: Vec<GoalUpdate>,
}
impl Goal {
pub fn new(title: &str, scope: GoalScope) -> Self {
let now = Utc::now();
let trimmed = title.trim();
Self {
id: sanitize_goal_id(trimmed),
title: trimmed.to_string(),
scope,
status: GoalStatus::Active,
description: String::new(),
why: String::new(),
success_criteria: Vec::new(),
milestones: Vec::new(),
next_steps: Vec::new(),
blockers: Vec::new(),
current_milestone_id: None,
progress_percent: None,
created_at: now,
updated_at: now,
updates: Vec::new(),
}
}
pub fn current_milestone(&self) -> Option<&GoalMilestone> {
let current_id = self.current_milestone_id.as_deref()?;
self.milestones.iter().find(|m| m.id == current_id)
}
}
pub fn sanitize_goal_id(id: &str) -> String {
let slug = slugify(id);
if slug.is_empty() {
"goal".to_string()
} else {
slug
}
}
fn slugify(input: &str) -> String {
let mut slug = String::new();
let mut prev_dash = false;
for ch in input.chars() {
let lower = ch.to_ascii_lowercase();
if lower.is_ascii_alphanumeric() {
slug.push(lower);
prev_dash = false;
} else if !prev_dash {
slug.push('-');
prev_dash = true;
}
}
slug.trim_matches('-').to_string()
}
fn default_pending_status() -> String {
"pending".to_string()
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TodoItem {
pub content: String,
pub status: String,
pub priority: String,
pub id: String,
/// Optional group label. Todos that share a group are displayed together
/// under a single header. Use one group per coherent goal; when work is
/// steered into a new area, start a new group instead of renaming.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
/// Forward-looking confidence, from 0-100, that this todo can be completed correctly.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub confidence: Option<u8>,
/// Confidence, from 0-100, recorded when the todo is marked completed.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub completion_confidence: Option<u8>,
/// Every distinct confidence value this todo has carried, oldest first,
/// ending with the current one. Maintained by the todo tool (not the
/// model): the first entry is the planning-time confidence, later entries
/// record how the assessment evolved while the item was worked on. This
/// preserves the planning signal even after the model overwrites
/// `confidence` when marking the item done.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub confidence_history: Vec<u8>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub blocked_by: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub assigned_to: Option<String>,
}
/// A goal-level assessment attached to a todo group (or, for an ungrouped
/// flat list, the whole list as one implicit goal with `group: None`).
///
/// Hill-climbability is a property of an objective, not of individual steps:
/// "optimize grep latency" is hill-climbable because progress has a metric,
/// while "design an onboarding screen" is not because success is a taste
/// judgment. Items like "read the auth code" have no meaningful score of
/// their own, so the score lives here instead of on `TodoItem`.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TodoGoal {
/// Group label this goal describes. `None` covers the ungrouped list.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
/// How hill-climbable this goal is, from 0-100: can progress be measured
/// against a quantifiable, verifiable objective and iterated on?
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hill_climbability: Option<u8>,
/// The measurable objective progress is climbing toward, when one exists
/// (e.g. "p50 grep latency under 50ms on the repo corpus"). A stated
/// objective is what makes a high score credible.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub objective: Option<String>,
/// The concrete feedback loop used to judge whether each iteration improves
/// the outcome (e.g. a benchmark command and the metric it reports).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub feedback_loop: Option<String>,
/// How completely the agent owned the goal's full outcome, including the
/// requested work, reasonably necessary adjacent work, end-to-end
/// validation, cleanup, and explicit disclosure of remaining gaps.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub end_to_end_ownership: Option<u8>,
}
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PersistedCatchupState {
#[serde(default)]
pub seen_at_ms_by_session: HashMap<String, i64>,
}
#[derive(Debug, Clone)]
pub struct CatchupBrief {
pub reason: String,
pub tags: Vec<String>,
pub last_user_prompt: Option<String>,
pub activity_steps: Vec<String>,
pub files_touched: Vec<String>,
pub tool_counts: Vec<(String, usize)>,
pub validation_notes: Vec<String>,
pub latest_agent_response: Option<String>,
pub needs_from_user: String,
pub updated_at: DateTime<Utc>,
}