Add a plugin-owned Linear importer that creates Fusion tasks from Linear issues. - Add the fusion-plugin-linear-import package with settings, Linear GraphQL client, import routes, tools, and dashboard UI. - Bundle and register the Linear import plugin in the CLI and dashboard plugin view registry. - Document bundled plugin authoring details and cover duplicate detection, routes, tools, UI, and packaging with tests. Files changed: .changeset/fn-7443-linear-import-plugin.md | 7 + docs/PLUGIN_AUTHORING.md | 7 + docs/task-management.md | 2 + packages/cli/src/__tests__/bundle-output.test.ts | 22 ++ .../__tests__/bundled-plugin-install.test.ts | 29 +++ packages/cli/src/plugins/bundled-plugin-install.ts | 1 + .../cli/src/plugins/staged-bundled-plugin-ids.ts | 1 + packages/cli/tsup.config.ts | 8 + .../__tests__/registerBundledPluginViews.test.tsx | 9 +- .../app/plugins/registerBundledPluginViews.ts | 18 ++ .../app/types/plugin-dashboard-views.d.ts | 9 + .../src/__tests__/routes-plugin-registry.test.ts | 5 + .../runtime-plugin-alias-regression.test.ts | 12 + packages/dashboard/src/registry-manifest.json | 10 + packages/dashboard/vite.config.ts | 8 + packages/dashboard/vitest.config.ts | 8 + plugins/fusion-plugin-linear-import/README.md | 75 ++++++ plugins/fusion-plugin-linear-import/manifest.json | 48 ++++ plugins/fusion-plugin-linear-import/package.json | 38 +++ .../scripts/copy-css.mjs | 11 + .../src/LinearImportView.css | 167 +++++++++++++ .../src/LinearImportView.tsx | 263 +++++++++++++++++++++ .../src/__tests__/LinearImportView.test.tsx | 124 ++++++++++ .../src/__tests__/import-linear.test.ts | 78 ++++++ .../src/__tests__/linear-client.test.ts | 81 +++++++ .../src/__tests__/routes.test.ts | 90 +++++++ .../src/__tests__/tools.test.ts | 79 +++++++ .../src/dashboard-interop.d.ts | 13 + .../src/dashboard-view.tsx | 10 + .../src/import-linear.ts | 154 ++++++++++++ plugins/fusion-plugin-linear-import/src/index.ts | 45 ++++ .../src/linear-client.ts | 247 +++++++++++++++++++ plugins/fusion-plugin-linear-import/src/routes.ts | 149 ++++++++++++ .../fusion-plugin-linear-import/src/settings.ts | 68 ++++++ plugins/fusion-plugin-linear-import/src/tools.ts | 138 +++++++++++ plugins/fusion-plugin-linear-import/tsconfig.json | 14 ++ .../fusion-plugin-linear-import/vitest.config.ts | 40 ++++ pnpm-lock.yaml | 40 ++++ pnpm-workspace.yaml | 1 + 39 files changed, 2128 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7443 Fusion-Task-Lineage: a016a9d4-84a4-4a0b-b9b6-b9a2886da49a Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
168 lines
4.1 KiB
CSS
168 lines
4.1 KiB
CSS
.linear-import-view {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-lg);
|
|
padding: var(--space-lg);
|
|
min-height: 0;
|
|
}
|
|
|
|
.linear-import-view__header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: var(--space-md);
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.linear-import-view__eyebrow,
|
|
.linear-import-view__meta,
|
|
.linear-import-view__empty,
|
|
.linear-import-view__helper {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.linear-import-view__title {
|
|
margin: 0;
|
|
}
|
|
|
|
.linear-import-view__subtitle {
|
|
margin: var(--space-xs) 0 0;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.linear-import-view__status {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-xs);
|
|
border: var(--border-width) solid var(--border-color);
|
|
border-radius: var(--radius-pill);
|
|
padding: var(--space-xs) var(--space-sm);
|
|
font-size: var(--font-size-sm);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.linear-import-view__status--auth { color: var(--color-success); border-color: color-mix(in srgb, var(--color-success) 40%, var(--border-color)); }
|
|
.linear-import-view__status--warning { color: var(--color-warning); border-color: color-mix(in srgb, var(--color-warning) 40%, var(--border-color)); }
|
|
.linear-import-view__status--error { color: var(--color-error); border-color: color-mix(in srgb, var(--color-error) 40%, var(--border-color)); }
|
|
.linear-import-view__status--info { color: var(--color-info); border-color: color-mix(in srgb, var(--color-info) 40%, var(--border-color)); }
|
|
|
|
.linear-import-view__filters {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
gap: var(--space-md);
|
|
align-items: end;
|
|
}
|
|
|
|
.linear-import-view__field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-xs);
|
|
}
|
|
|
|
.linear-import-view__actions,
|
|
.linear-import-view__issue-actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-sm);
|
|
}
|
|
|
|
.linear-import-view__content {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) minmax(18rem, 0.75fr);
|
|
gap: var(--space-lg);
|
|
min-height: 0;
|
|
}
|
|
|
|
.linear-import-view__issue-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-sm);
|
|
max-height: 55vh;
|
|
overflow: auto;
|
|
}
|
|
|
|
.linear-import-view__issue {
|
|
display: grid;
|
|
grid-template-columns: auto minmax(0, 1fr);
|
|
gap: var(--space-sm);
|
|
align-items: start;
|
|
text-align: left;
|
|
width: 100%;
|
|
}
|
|
|
|
.linear-import-view__issue-main {
|
|
min-width: 0;
|
|
}
|
|
|
|
.linear-import-view__issue-title {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-xs);
|
|
align-items: baseline;
|
|
margin: 0;
|
|
}
|
|
|
|
.linear-import-view__identifier {
|
|
color: var(--color-info);
|
|
font-weight: var(--font-weight-semibold, 600);
|
|
}
|
|
|
|
.linear-import-view__badges {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-xs);
|
|
margin-top: var(--space-xs);
|
|
}
|
|
|
|
.linear-import-view__badge {
|
|
border: var(--border-width) solid var(--border-color);
|
|
border-radius: var(--radius-pill);
|
|
padding: 0 var(--space-xs);
|
|
color: var(--text-muted);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.linear-import-view__preview {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-md);
|
|
min-width: 0;
|
|
}
|
|
|
|
.linear-import-view__preview-body {
|
|
white-space: pre-wrap;
|
|
overflow: auto;
|
|
max-height: 45vh;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.linear-import-view__message {
|
|
border-radius: var(--radius-md);
|
|
padding: var(--space-md);
|
|
border: var(--border-width) solid var(--border-color);
|
|
}
|
|
|
|
.linear-import-view__message--error { color: var(--color-error); border-color: color-mix(in srgb, var(--color-error) 45%, var(--border-color)); }
|
|
.linear-import-view__message--success { color: var(--color-success); border-color: color-mix(in srgb, var(--color-success) 45%, var(--border-color)); }
|
|
.linear-import-view__message--info { color: var(--color-info); border-color: color-mix(in srgb, var(--color-info) 45%, var(--border-color)); }
|
|
|
|
@media (max-width: 48rem) {
|
|
.linear-import-view {
|
|
padding: var(--space-md);
|
|
}
|
|
|
|
.linear-import-view__header,
|
|
.linear-import-view__content {
|
|
grid-template-columns: 1fr;
|
|
display: grid;
|
|
}
|
|
|
|
.linear-import-view__filters {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.linear-import-view__issue-list,
|
|
.linear-import-view__preview-body {
|
|
max-height: none;
|
|
}
|
|
}
|