Skip to content

add tasks source linear#192

Merged
0xRichardH merged 5 commits intomasterfrom
22071
Apr 11, 2026
Merged

add tasks source linear#192
0xRichardH merged 5 commits intomasterfrom
22071

Conversation

@kaiji95
Copy link
Copy Markdown
Contributor

@kaiji95 kaiji95 commented Apr 2, 2026

https://github.com/feed-mob/tracking_admin/issues/22071

What changed

Release notes

  • Add at least one release-note label: feature, fix, docs, test, chore, ci, or refactor
  • Use skip-changelog if this PR should be excluded from generated release notes

Verification

  • Tests pass locally

@0xRichardH 0xRichardH requested a review from Copilot April 3, 2026 08:37
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new first-party Linear plugin that syncs Linear issues with Peekoo tasks, plus SDK/host/UI wiring to support plugin-driven task operations and surfaced integration status in the desktop app.

Changes:

  • Introduces plugins/linear (Rust WASM plugin + panel UI) implementing API-key auth, periodic/manual sync, and a settings panel snapshot provider.
  • Extends peekoo-plugin-sdk with a tasks module and new host function bindings for task CRUD/toggle/assign.
  • Updates desktop UI to surface Linear integration status in Settings and provide entry points to the Linear panel from Tasks.

Reviewed changes

Copilot reviewed 22 out of 25 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
plugins/linear/ui/panel.js Implements Linear panel behavior (snapshot refresh, API key autosave, sync/settings controls).
plugins/linear/ui/panel.html Adds Linear plugin panel UI markup.
plugins/linear/ui/panel.css Adds styling for the Linear plugin panel.
plugins/linear/src/lib.rs Implements Linear API integration, state, syncing, and tool/data provider endpoints.
plugins/linear/peekoo-plugin.toml Declares Linear plugin metadata, permissions, tools, data providers, and panel entry.
plugins/linear/Cargo.toml Defines the Linear plugin crate for WASM build.
justfile Adds linear to plugin-build-all.
docs/plans/2026-03-31-linear-task-plugin-integration-design.md Adds design doc for Linear integration approach and scope.
docs/plans/2026-03-31-linear-integration-manual-qa.md Adds manual QA checklist for Linear integration.
crates/peekoo-plugin-sdk/src/tasks.rs Adds safe SDK wrappers around host task APIs for plugins.
crates/peekoo-plugin-sdk/src/lib.rs Exports the new tasks module in the SDK and peekoo namespace.
crates/peekoo-plugin-sdk/src/host_fns.rs Adds raw host function bindings for task operations.
crates/peekoo-plugin-sdk/Cargo.lock Adds a workspace-local lockfile for the SDK crate.
crates/peekoo-plugin-host/src/registry.rs Increases default plugin runtime timeout.
apps/desktop-ui/src/features/tasks/TasksPanel.tsx Adds a “Sources -> Linear” button to open the Linear panel when available.
apps/desktop-ui/src/features/tasks/components/TaskLabelPills.tsx Adjusts label pill coloring logic.
apps/desktop-ui/src/features/settings/useLinearIntegrationStatus.ts Adds a hook to poll Linear connection status via plugin data provider.
apps/desktop-ui/src/features/settings/SettingsPanel.tsx Adds an Integrations section showing Linear status details.
apps/desktop-ui/src/components/sprite/SpriteActionMenu.tsx Excludes Linear from the sprite action menu plugin list.
apps/desktop-tauri/src-tauri/Cargo.toml Enables the macos-private-api Tauri feature.
ai/memories/changelogs/202603311740-feat-linear-plugin-foundation.md Adds an internal changelog entry for the Linear plugin foundation.
ai/memories/changelogs/202603311644-feat-linear-api-key-auth.md Adds an internal changelog entry for switching Linear auth to API key.
ai/memories/changelogs/202603311620-docs-linear-task-plugin-integration-design.md Adds an internal changelog entry for the Linear design doc.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@kaiji95 kaiji95 added the feature label Apr 7, 2026
{visibleLabels.map((label) => {
const predefined = PREDEFINED_LABELS.find((l) => l.name === label);
const color = predefined?.color ?? getLabelColor(label);
const backgroundColor = withAlpha(color, 0.18);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0xRichardH 这个文件的修改,主要是解决 tasks 插件已有的一个错误,同步下来的 linear task, 在 task 标签显示存在背景色和文字颜色一样的问题

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 15 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

[[tools.definitions]]
name = "linear_set_sync_settings"
description = "Update Linear sync settings"
parameters = '{"type":"object","properties":{"defaultTeamId":{"type":"string"},"autoPushNewTasks":{"type":"boolean"}},"required":[]}'
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linear_set_sync_settings tool schema doesn’t include fields that the panel actually sends (assigneeId and syncStateNames). If the host validates tool arguments against this JSON schema, the panel’s auto-save calls can fail/reject. Update the parameters schema to include these properties (and their types) so it matches the Rust handler/panel payload.

Suggested change
parameters = '{"type":"object","properties":{"defaultTeamId":{"type":"string"},"autoPushNewTasks":{"type":"boolean"}},"required":[]}'
parameters = '{"type":"object","properties":{"defaultTeamId":{"type":"string"},"autoPushNewTasks":{"type":"boolean"},"assigneeId":{"type":"string"},"syncStateNames":{"type":"array","items":{"type":"string"}}},"required":[]}'

Copilot uses AI. Check for mistakes.
Comment on lines +651 to +658
let sync_result = run_sync_cycle(force, mode, &api_key, &mut state);
match sync_result {
Ok(summary) => {
let now = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true);
state.connection.status = "connected".to_string();
state.sync.last_sync_at = Some(now.clone());
state.sync.last_pull_cursor = Some(now.clone());
state.sync.last_push_cursor = Some(now.clone());
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On successful sync you set both last_pull_cursor and last_push_cursor to now regardless of SyncMode. A manual PushOnly sync will advance last_pull_cursor without pulling, which can cause subsequent pulls to skip remote updates. Only advance the cursor(s) for the operations that actually ran (and consider keeping the other cursor unchanged).

Suggested change
let sync_result = run_sync_cycle(force, mode, &api_key, &mut state);
match sync_result {
Ok(summary) => {
let now = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true);
state.connection.status = "connected".to_string();
state.sync.last_sync_at = Some(now.clone());
state.sync.last_pull_cursor = Some(now.clone());
state.sync.last_push_cursor = Some(now.clone());
let ran_pull = !matches!(mode, SyncMode::PushOnly);
let ran_push = !matches!(mode, SyncMode::PullOnly);
let sync_result = run_sync_cycle(force, mode, &api_key, &mut state);
match sync_result {
Ok(summary) => {
let now = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true);
state.connection.status = "connected".to_string();
state.sync.last_sync_at = Some(now.clone());
if ran_pull {
state.sync.last_pull_cursor = Some(now.clone());
}
if ran_push {
state.sync.last_push_cursor = Some(now.clone());
}

Copilot uses AI. Check for mistakes.
Comment on lines +726 to +728
};

summary.pulled = pull_remote_into_local(&filtered_issues, state, &mut local_tasks)?;
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using now as the pull/push cursor can permanently skip work when the run is capped by page_limit/issue_limit (e.g., if >200 issues changed since the last cursor, you truncate but still advance the cursor past the unprocessed changes). Instead, advance the cursor to the max updatedAt you actually processed (or persist/paginate using a Linear page cursor) so remaining updates are picked up in the next run.

Suggested change
};
summary.pulled = pull_remote_into_local(&filtered_issues, state, &mut local_tasks)?;
};
let last_processed_pull_cursor = filtered_issues
.iter()
.map(|issue| issue.updated_at.as_str())
.max()
.map(str::to_owned);
summary.pulled = pull_remote_into_local(&filtered_issues, state, &mut local_tasks)?;
if let Some(cursor) = last_processed_pull_cursor {
state.sync.last_pull_cursor = Some(cursor);
}

Copilot uses AI. Check for mistakes.
Comment on lines +408 to +409
state.connection = ConnectionState::default();
state.sync = SyncState::default();
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linear_disconnect resets connection/sync state but keeps mappings (and cached teams/users/preferences). If the user reconnects with a different Linear account/workspace, stale mappings can cause updates/creates to target non-existent issues or leak cross-account linkage. Clear mappings and cached remote data (and potentially preferences) on disconnect.

Suggested change
state.connection = ConnectionState::default();
state.sync = SyncState::default();
state = Default::default();

Copilot uses AI. Check for mistakes.
@0xRichardH 0xRichardH self-assigned this Apr 9, 2026
@0xRichardH
Copy link
Copy Markdown
Collaborator

  • 还是有依赖的问题
  • AI 建议用 rust 重写
image image

@0xRichardH 0xRichardH merged commit 9fdfedb into master Apr 11, 2026
10 of 11 checks passed
@0xRichardH 0xRichardH deleted the 22071 branch April 11, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants