- Edit an application's full stage history, with a date per step, so an
application logged after the fact keeps its whole path
- `kareer history` to show or replace a stage history
- Mark applications with no response as Ghosted after 30 days,
adjustable or off in Preferences
- New app icon, installed under the app ID so launchers and the Flatpak
show it
- Fix the Add Application form filling empty fields with "undefined"
- Bump the version, add the 0.1.5 metainfo release, and update the
manifest's pinned tag
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
Stage history editor:
- The edit form's Pipeline section is now the application's history:
one row per step (stage + date), Add Step and Remove Step, kept in
date order. The last step is the current stage and the first step's
date the date applied, replacing the separate Stage and Date Applied
fields. An application logged after the fact (applied, interviewed,
rejected) keeps its whole path.
- JobsDatabase::replaceStageHistory() rewrites a job's history in one
transaction (sorted, repeats collapsed, stage and date applied kept in
step); StageHistoryModel backs the section; JobsModel::addJob() now
returns the new id so a new application's history can be saved.
- `kareer history <id> [Stage=YYYY-MM-DD ...]` shows or replaces it.
Auto-ghosting:
- Applications still at Applied with no activity (the later of the
date applied and the last stage change) for more than 30 days move to
Ghosted, recorded like any stage change. Runs at startup for GUI and
CLI, after switching databases, and shortly after the setting changes.
- Preferences gains an Applications section: on/off and the number of
days (kareerrc [AutoGhost]). The GUI shows a passive notification; the
CLI notes it on stderr so --json output stays clean.
Fixes:
- The Add Application form pre-filled empty text fields with the word
"undefined" (typing "a" gave "undefineda"): fields with no value
reached QML as undefined. Every field now gets a typed default.
- Embed the app icon as the window icon fallback, so the window and
About page show it when running uninstalled.
Tests: history replacement and the after-the-fact Allstate case, the
ghosting rules (fresh/stale/logged-late/reopened/threshold), and empty
new-form fields.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
The stem is every application, splitting into a green success path
rising to an outcome and a drop-off falling away, on a Breeze-blue
rounded square. Plain shapes and gradients only, so QtSvg renders it
exactly; PNGs from 16 to 128 px are rendered from the SVG.
The icon set is now named after the app ID (io.github.toservetheking.
Kareer). It was installed as "kareer", which nothing looked up: the
desktop file and the window ask for the app ID, so launchers fell back
to a generic icon, and Flatpak (which only exports icons prefixed with
the app ID) shipped none.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
- Fix Save on the edit form silently dropping stage changes; report a
missing company or title instead of saving a blank field
- Rework the pipeline Sankey: drop-offs split off each stage in level
lanes and rejoin their outcome without braiding
- Count each application once as a forward path, so back moves and
ghosted-then-rejected no longer draw extra ribbons
- First-run choice of database location (default, a folder, or an
existing file used in place), plus a Database section in Preferences
- --db <path> for the GUI and every subcommand
- Bump the version, add the 0.1.4 metainfo release, and update the
manifest's pinned tag
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
Covers the build/test/lint commands (including running one test
function and a throwaway --db database), the CLI/GUI split, database
location resolution, the setStage rule, the stage vocabulary, the lane
-based Sankey layout and its geometric test, and the data-driven edit
form. REUSE.toml annotates it as CC0 like the other docs.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
Ribbons crossed over each other on their way to the outcome column.
Every funnel stage sits alone in its column at the same height, so
ordering a node's ribbon slots by the other end's node height tied,
and the tie-break ordered them against the geometry. Early drop-offs
also left from mid-node, above later stages' drop-offs, and backward
history moves were drawn right to left over everything.
- Count one left-to-right path per application: the funnel stages it
reached, then its current stage if that is an outcome. Ghosted then
Rejected counts only as Rejected; moving back from Offer keeps Offer.
- Lane-based routing: drop-offs travel in lanes below each column's
node, links skipping a stage travel above it; stacks are top-aligned
and the whole block is centered. Every ribbon crossing a gap between
columns shares its x endpoints, and slot/lane orders are kept equal at
both ends of every gap, so ribbons can only cross where they rejoin
the outcome nodes. Drop-off lanes stay level rather than rising.
- Outcomes are ordered by the average stage their ribbons come from,
which keeps those last crossings to a minimum.
- sankeylayouttest now parses the drawn pathData and fails if any two
ribbons overlap (the previous layout overlapped by up to 150px on the
same data); adds forward-path counting and content-centering tests,
replacing the slot-order and per-column-centering tests.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
- `kareer --db <path>` works for the GUI and every subcommand, before
or after the subcommand name, and creates the file if missing. main()
strips it from argv before CLI/GUI routing; every parser declares it
so it shows in --help.
- Path precedence: --db > KAREER_DB_PATH > the location chosen in the
GUI (kareerrc [Database] Path, read at startup for GUI and CLI alike)
> $XDG_DATA_HOME/kareer/kareer.sqlite.
- First GUI run (nothing forced, no file yet, or the configured file
has gone missing): DatabaseSetupDialog offers the default location, a
folder of the user's choice, or an existing database used in place.
Until then JobsDatabase opens nothing.
- Preferences gains a Database section: Move to... (copies, leaves the
original), Open Existing..., Use Default Location. Refuses foreign
SQLite files and unwritable ones.
- Models call JobsDatabase::reopenIfPathChanged() on refresh, so
switching databases needs no restart.
- Link KF6::ConfigCore; add a QuickDialogs2 configure-time guard; add
kconfig to the Arch dependencies and a note to the Flatpak manifest.
- README documents --db, the precedence, and the first-run choice, and
gains Fedora 44 build dependencies; CONTRIBUTING gets a dev recipe.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
Changing an application's stage and pressing Save closed the form
without saving the stage: JobsDatabase::updateJob() deliberately skips
the stage column so every move lands in stage_history, but
JobEditModel::save() never followed up with setStage(). It now does,
as the CLI's update command always has.
Also:
- Validate that company and title are non-empty and say so, instead of
saving a blank field
- Always set lastError on failure, clear it on the next attempt, and
bind the page's error message to it
- Reload the form's values when jobsModel is assigned, since QML does
not guarantee it is set before editingJobId
- Bind the salary spin boxes to the model and write back only on user
edits; guard the notes field the same way
- Add jobeditmodeltest covering load order, edits, stage history,
salaries round-tripping, adding, and validation errors
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
reuse-action@v3 runs reuse 3.x, which predates REUSE.toml and flagged
every file the annotations cover - the actual reason the REUSE job
never passed. v5 matches the reuse 5.x used to verify locally.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019FXfh48mASRsE1WEhy9jcM
clang-format job: the flatpak CI image has no ECM on the host, so the
configure step that generated .clang-format could never run. Commit the
ECM-generated .clang-format instead (it is MIT, LICENSES/MIT.txt added),
drop the container, pin clang-format 22.1.8 from PyPI to match the
version the tree is formatted with, and reformat the sources to match.
REUSE job: add the missing CC0-1.0 license text, a copyright line for
the metainfo, REUSE.toml coverage for README/CONTRIBUTING/.gitignore,
and REUSE-Ignore markers around CONTRIBUTING.md's SPDX example so the
parser stops reading prose as a license declaration. reuse lint now
passes locally (54/54 files).
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019FXfh48mASRsE1WEhy9jcM
The AUR is not accepting new accounts at the moment, so the package
(tested with makepkg, check() runs the full test suite) lives in-repo
until it can be pushed to aur.archlinux.org as 'kareer'.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019FXfh48mASRsE1WEhy9jcM
- Spread columns by rank among the stages actually present, so sparse
pipelines fill the width instead of leaving dead stretches
- Top-align columns: the funnel's success path runs level along the top
and drop-off ribbons only ever descend
- Give each ribbon its slot per node side (outgoing by target height,
incoming by source height) so ribbons stop braiding over each other
- Move the last column's labels to its left so they always stay
on-screen, with a theme halo to stay legible over ribbons
- Never hide small-node labels; elide with tooltip instead
- Guarantee columns and ribbons fit the viewport (clamp-aware scale,
spill-proof ribbon thickness)
- Debounce resize relayouts and stop re-querying SQLite on resize
- Canonicalize stage names on write (CLI "rejected" -> "Rejected") and
repair pre-existing rows on database open
- Take Sankey node width/padding from Kirigami units
- Add QuickShapesPrivate configure-time guard for QtQuick.Shapes
- Extend sankeylayouttest: viewport fit, ribbon containment, slot
ordering, sparse-column spread, canonicalization, degenerate sizes
- README: build-dependency and generator fixes, document SettingsPage
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019FXfh48mASRsE1WEhy9jcM
- Rework the add/edit form onto a generic, catalog-driven field model
(JobFieldCatalog + JobEditModel), replacing the old hand-written
ApplicationEditDialog with ApplicationEditPage
- Add a Preferences page (reachable from the hamburger menu) with a
KColorSchemeManager-backed color scheme switcher
- Add an About page reading from KAboutData
- Ship a full hicolor icon set (16-128px + scalable) via ecm_install_icons
instead of a single flat SVG
- Restyle the edit form after KDE System Settings' Audio page:
Kirigami.ListSectionHeader per category, flat separated rows, no card
borders
- Explicitly declare Kirigami/KirigamiAddons/ColorScheme as CMake
dependencies instead of relying on the QML import scanner alone
- Add KDEClangFormat/KDEGitCommitHooks, a CMakePresets.json, and a
REUSE + clang-format lint CI workflow
- Reformat SPDX headers to include copyright, remove debug screenshot
scaffolding
- Add .github/workflows/test.yml, using flatpak-builder's run-tests
option so PRs and pushes exercise ctest inside the same KDE SDK
sandbox as release builds.
- Add REUSE.toml covering files that can't carry an inline SPDX header
(.desktop, keys/*.asc).
- Add CONTRIBUTING.md documenting build/test/release steps.
C++/Qt6/KDE Frameworks 6 app with a SQLite-backed data layer, a
Sankey-diagram dashboard, and a full CLI (add/list/show/update/stage/
delete/stats/stages) for scripting from other tools.