Import - commands and agent skill#493
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a deterministic, artifact-driven CSV import workflow to the Basecamp CLI, enabling safer imports of external task data as Basecamp todos or cards with explicit planning, preflight validation, approval gating, and recovery support.
Changes:
- Adds the
basecamp importcommand group to support inspect → compile → plan → preflight → execute (plus status/repair/followup). - Introduces importer support for local artifact status, repair summaries, and follow-up artifact generation after partial failures.
- Adds extensive CSV fixtures, demo assets, and embeds/installs a new
basecamp-importskill bundle; updates skill drift validation and CLI surface metadata.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Reviewed changes
Copilot reviewed 101 out of 101 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| testdata/import/csv/synthetic/random/sample-30.csv | Synthetic random CSV fixture (duplicate headers, dates, URLs) |
| testdata/import/csv/synthetic/random/sample-29.csv | Synthetic random CSV fixture (mixed date formats, blanks) |
| testdata/import/csv/synthetic/random/sample-28.csv | Synthetic random CSV fixture (multiline quoted fields) |
| testdata/import/csv/synthetic/random/sample-27.csv | Synthetic random CSV fixture (duplicate headers, missing values) |
| testdata/import/csv/synthetic/random/sample-26.csv | Synthetic random CSV fixture (RFC3339 timestamps) |
| testdata/import/csv/synthetic/random/sample-25.csv | Synthetic random CSV fixture (money-ish fields, notes) |
| testdata/import/csv/synthetic/random/sample-24.csv | Synthetic random CSV fixture (duplicate headers, nullable tenant) |
| testdata/import/csv/synthetic/random/sample-23.csv | Synthetic random CSV fixture (TSV-like headers/rows) |
| testdata/import/csv/synthetic/random/sample-22.csv | Synthetic random CSV fixture (mixed date formats) |
| testdata/import/csv/synthetic/random/sample-21.csv | Synthetic random CSV fixture (duplicate headers) |
| testdata/import/csv/synthetic/random/sample-20.csv | Synthetic random CSV fixture (UTM URLs, briefs) |
| testdata/import/csv/synthetic/random/sample-19.csv | Synthetic random CSV fixture (semicolon delimiter) |
| testdata/import/csv/synthetic/random/sample-18.csv | Synthetic random CSV fixture (duplicate headers, dependency refs) |
| testdata/import/csv/synthetic/random/sample-17.csv | Synthetic random CSV fixture (tags field, blanks) |
| testdata/import/csv/synthetic/random/sample-16.csv | Synthetic random CSV fixture (quoted lists, notes) |
| testdata/import/csv/synthetic/random/sample-15.csv | Synthetic random CSV fixture (duplicate headers) |
| testdata/import/csv/synthetic/random/sample-14.csv | Synthetic random CSV fixture (epoch timestamps) |
| testdata/import/csv/synthetic/random/sample-13.csv | Synthetic random CSV fixture (multiline quoted notes) |
| testdata/import/csv/synthetic/random/sample-12.csv | Synthetic random CSV fixture (duplicate headers, blanks) |
| testdata/import/csv/synthetic/random/sample-11.csv | Synthetic random CSV fixture (semicolon delimiter, currency) |
| testdata/import/csv/synthetic/random/sample-10.csv | Synthetic random CSV fixture (contracts-style fields) |
| testdata/import/csv/synthetic/random/sample-09.csv | Synthetic random CSV fixture (date variants with slashes) |
| testdata/import/csv/synthetic/random/sample-08.csv | Synthetic random CSV fixture (multiline quoted resolution) |
| testdata/import/csv/synthetic/random/sample-07.csv | Synthetic random CSV fixture (tab-delimited rows) |
| testdata/import/csv/synthetic/random/sample-06.csv | Synthetic random CSV fixture (duplicate headers, blanks) |
| testdata/import/csv/synthetic/random/sample-05.csv | Synthetic random CSV fixture (natural-language dates) |
| testdata/import/csv/synthetic/random/sample-04.csv | Synthetic random CSV fixture (semicolon delimiter, quoted cells) |
| testdata/import/csv/synthetic/random/sample-03.csv | Synthetic random CSV fixture (duplicate headers) |
| testdata/import/csv/synthetic/random/sample-02.csv | Synthetic random CSV fixture (multiline description, escaping) |
| testdata/import/csv/synthetic/random/sample-01.csv | Synthetic random CSV fixture (duplicate headers, metadata) |
| testdata/import/csv/synthetic/linear-simple.csv | Synthetic Linear-shaped fixture (core mapping roles) |
| testdata/import/csv/synthetic/linear-relationships.csv | Synthetic Linear fixture (relationship columns) |
| testdata/import/csv/synthetic/linear-ambiguous-assignees.csv | Synthetic Linear fixture (ambiguous assignee values) |
| testdata/import/csv/synthetic/jira-simple.csv | Synthetic Jira-shaped fixture (duplicate Labels headers) |
| testdata/import/csv/synthetic/jira-attachments-custom-fields.csv | Synthetic Jira fixture (custom fields + duplicates) |
| testdata/import/csv/synthetic/clickup-subtasks-comments.csv | Synthetic ClickUp fixture (comments/attachments-like fields) |
| testdata/import/csv/synthetic/clickup-simple.csv | Synthetic ClickUp fixture (baseline shape) |
| testdata/import/csv/synthetic/asana-simple.csv | Synthetic Asana fixture (baseline shape) |
| testdata/import/csv/synthetic/asana-dependencies-custom-fields.csv | Synthetic Asana fixture (deps + custom fields) |
| testdata/import/csv/README.md | Documents CSV fixture layout, privacy notes, and intended profiler behavior |
| testdata/import/csv/canonical/trello/sample-01.csv | Canonical Trello-shaped fixture (multiline markdown-like content) |
| testdata/import/csv/canonical/linear/sample-03.csv | Canonical Linear-shaped fixture (non-English content, hierarchy refs) |
| testdata/import/csv/canonical/jira/sample-06.csv | Canonical Jira fixture (duplicate components headers) |
| testdata/import/csv/canonical/jira/sample-04.csv | Canonical Jira fixture (very wide export, multiline descriptions) |
| testdata/import/csv/canonical/jira/sample-02.csv | Canonical Jira fixture (large multiline acceptance criteria) |
| testdata/import/csv/canonical/jira/sample-01.csv | Canonical Jira fixture (security findings-style content) |
| testdata/import/csv/canonical/clickup/sample-04.csv | Canonical ClickUp fixture (legacy export shapes) |
| testdata/import/csv/canonical/clickup/sample-02.csv | Canonical ClickUp fixture (complex JSON-in-CSV content) |
| testdata/import/csv/canonical/asana/sample-04.csv | Canonical Asana fixture (wide export with repeated fields) |
| testdata/import/csv/canonical/asana/sample-03.csv | Canonical Asana fixture (older timestamps + URLs) |
| testdata/import/csv/canonical/asana/sample-01.csv | Canonical Asana fixture (baseline export) |
| skills/embed.go | Embeds basecamp + basecamp-import skill directories |
| skills/basecamp/SKILL.md | Updates Basecamp skill guidance/triggers to include imports |
| skills/basecamp-import/SKILL.md | Adds dedicated deterministic CSV import skill bundle |
| scripts/demo-import.sh | Adds end-to-end demo script for dry-run/execute/recovery flows |
| scripts/check-skill-drift.sh | Extends drift check to iterate all skills by default |
| internal/importer/status.go | Implements local artifact status reporting (incl. ledger handling) |
| internal/importer/status_test.go | Adds unit tests for status behavior |
| internal/importer/repair.go | Implements repair/recovery summary generation from execution ledger |
| internal/importer/repair_test.go | Adds unit tests for repair summaries |
| internal/importer/preflight_test.go | Adds unit tests for preflight collision checks and ledger blocking |
| internal/importer/followup.go | Implements reviewed follow-up artifact generation for pending rows |
| internal/importer/followup_test.go | Adds unit tests for follow-up artifact generation |
| internal/importer/executor_test.go | Expands execution tests (todos/cards, replay refusal, skipped assignees) |
| internal/importer/dates.go | Adds deterministic due-date normalization + slash-order inference |
| internal/importer/csvprofiler_test.go | Ensures CSV inspection works across all fixtures and duplicate headers |
| internal/importer/artifact_test.go | Adds artifact compile/read/plan tests and tamper detection |
| internal/commands/skill.go | Installs/links embedded skill bundle (basecamp + basecamp-import) |
| internal/commands/skill_test.go | Updates tests for multi-skill installation/linking/refresh |
| internal/commands/commands.go | Registers import command metadata in command catalog |
| internal/commands/commands_test.go | Registers NewImportCmd() in command test root |
| internal/cli/root.go | Adds basecamp import to the CLI root command |
| e2e/test_helper.bash | Allows optional per-test teardown_extra cleanup hook |
| e2e/smoke/smoke_import.bats | Adds smoke coverage for inspect/compile/plan and required flags |
| demos/import/tasks.csv | Demo CSV input for the import workflow |
| demos/import/README.md | Documents demo flows (dry-run, execute, recovery review) |
| demos/import/mapping.json | Demo confirmed mapping input |
| demos/import/destination.example.json | Demo destination example (existing project) |
| demos/import/destination-new-project.example.json | Demo destination example (new project) |
| demos/import/board-export.mapping.json | Demo mapping for board-export card import |
| demos/import/board-export.destination.example.json | Demo card destination example (existing project) |
| demos/import/board-export.destination-new-project.example.json | Demo card destination example (new project) |
| demos/import/board-export.csv | Demo Trello-shaped board export fixture |
| .surface | Updates recorded CLI surface to include new import commands/flags |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
7 issues found across 101 files
Note: This PR contains a large number of files. cubic only reviews up to 100 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.
Re-trigger cubic
|
Fixed — addressed the automated review findings identified by cubic: smoke setup now asserts import setup commands, the approval test creates its artifact inline, status/repair messaging handles card artifacts, the unreadable-ledger guidance preserves one-shot safety, and the CSV fixtures were corrected. |
|
Fixed — addressed Copilot's import review comments: status output now names the correct artifact CSV, unreadable-ledger guidance no longer suggests removal, and pending repair/follow-up records use a resource-neutral group_name field. |
There was a problem hiding this comment.
1 issue found across 10 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Fixed — addressed the latest issue identified by cubic: compile now enforces 0750/0600 permissions on existing artifact directories and files, with test coverage. Also handled the CodeQL close-error findings for writable artifact CSV files. |
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
|
Fixed — addressed the latest review findings: follow-up output directories must now be empty/nonexistent, SharePoint fixture URLs were redacted to example.com, and artifact CSV writers close files on every return path with close-error handling. |
|
Fixed — addressed the latest Copilot review comments: redacted remaining Trello/Jira/demo external URLs to example.com placeholders and added guarded demo output deletion before rm -rf. |
Summary
This PR adds a CSV import workflow to the Basecamp CLI for bringing external task data into Basecamp as todos or cards.
The workflow is built around a durable, deterministic import artifact. Users inspect a source CSV, confirm a mapping and destination, compile those inputs into a validated artifact, review the plan, run preflight checks, and then explicitly approve execution. The same artifact can also report status, support repair review, and produce follow-up artifacts after partial failures.
This gives reviewers and operators a safer import path than a one-shot CSV command: every Basecamp write is planned, validated, approved, and recorded.
Details
Core workflow
Adds the
basecamp importcommand group with:inspect <csv-path>— profiles CSV columns, value shapes, mapping candidates, warnings, and questionscompile— validates inspection, mapping, destination, source fingerprint, and writes the import artifactplan— summarizes what the artifact will create without touching Basecamppreflight— checks Basecamp readiness before executionexecute --approved— performs the planned writes after explicit approvalstatus— reports local execution state from the artifactrepair— summarizes completed, failed, and pending operations after a failed runfollowup --reviewed— creates a fresh artifact for reviewed pending rowsCore concepts
Deterministic artifact as the source of truth
The import process compiles CSV data into a stable
basecamp-import-csv-v1artifact containing:import.jsontodos.csvorcards.csvexecution.jsonafter execution startsThe artifact records the source CSV fingerprint, destination, normalized rows, counts, and preserved source metadata. Later commands read the artifact instead of reinterpreting the original CSV.
Separation of planning and writing
Inspection, compilation, planning, status, repair, and follow-up are local artifact operations. Basecamp writes only happen during
execute --approved, and execution first runs preflight checks.Safer execution and recovery
Execution writes a ledger before creating records and records each completed or failed operation with source-row provenance and created Basecamp IDs. Artifacts are one-shot: an artifact with an execution ledger will not execute again. Failed imports can be reviewed with
repairand continued through a fresh follow-up artifact.Todo and card support
The importer supports:
Metadata preservation
Source fields that do not map directly to Basecamp native fields can be preserved as metadata, including assignee names/emails, status, attachment URLs, comments, and custom fields.
Supporting changes
basecamp-importskill bundleTests
GOWORK=off bin/ciSummary by cubic
Adds a deterministic CSV import workflow to the Basecamp CLI to safely bring external tasks in as todos or cards. Imports compile into a repeatable
basecamp-import-csv-v1artifact, are planned and preflighted, and only write on explicit approval with clear recovery paths.Refactors
basecamp skill installnow installs both embedded skills (basecampandbasecamp-import);scripts/check-skill-drift.shvalidates all skills by default.basecamp import followupenforces--reviewedand improves guidance/error messages for safer recovery.Bug Fixes
import.json,todos.csv/cards.csv,execution.json) to protect source data and ledgers.Written for commit 711986d. Summary will update on new commits.