@dboio/cli 0.19.0 → 0.19.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,210 @@
1
+ # Deploy & Push Reference
2
+
3
+ The standard workflow for getting local changes to the server uses `dbo push` and `dbo deploy`. Two config files — `.app/deploy_config.json` and `.app/scripts.json` — provide optional shorthand and automation on top of these commands.
4
+
5
+ ## Standard Commands
6
+
7
+ ### `dbo push` — Push local metadata-tracked files to server
8
+
9
+ Push works with files that have a companion `.metadata.json` (created by `dbo clone` or `dbo adopt`).
10
+
11
+ ```bash
12
+ # Push a single file
13
+ dbo push lib/bins/app/assets/css/colors.css
14
+
15
+ # Push all changed files in a directory
16
+ dbo push lib/bins/app/assets/
17
+
18
+ # Push everything in the project
19
+ dbo push
20
+
21
+ # Validate without submitting
22
+ dbo push lib/bins/app/assets/css/colors.css --confirm false
23
+
24
+ # Push only file content, skip metadata column changes
25
+ dbo push lib/bins/app/assets/css/colors.css --content-only
26
+
27
+ # Push only metadata changes, skip file content
28
+ dbo push lib/bins/app/assets/css/colors.css --meta-only
29
+ ```
30
+
31
+ Push detects changes by comparing local files against the server baseline. Records without a UID (created by `dbo adopt`) are submitted as new inserts.
32
+
33
+ ### `dbo deploy` — Push a file to a specific record by UID or shorthand
34
+
35
+ Use `dbo deploy` when you want to target a record by UID directly, or when you have a named shorthand defined in `.app/deploy_config.json`.
36
+
37
+ ```bash
38
+ # Deploy by UID directly
39
+ dbo deploy bdcaeef375f242df84760c path/to/file.css
40
+
41
+ # Deploy by shorthand name (requires deploy_config.json entry)
42
+ dbo deploy css:colors
43
+
44
+ # Deploy all entries
45
+ dbo deploy --all
46
+
47
+ # Validate without deploying
48
+ dbo deploy css:colors --confirm false
49
+ ```
50
+
51
+ ### `dbo clone` — Pull the full app from server to local files
52
+
53
+ ```bash
54
+ # Clone using AppShortName from config
55
+ dbo clone
56
+
57
+ # Clone a specific entity type only
58
+ dbo clone -e extension
59
+ dbo clone -e content
60
+ ```
61
+
62
+ ### `dbo pull` / `dbo diff` — Sync server changes locally
63
+
64
+ ```bash
65
+ # Interactive diff — compare local vs server, accept/skip per file
66
+ dbo diff assets/css/
67
+
68
+ # Pull a content record directly
69
+ dbo content pull ykqucv0eb0ggjqgcncj6dq
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Deploy Config (.app/deploy_config.json)
75
+
76
+ Optional. Defines shorthand names for `dbo deploy`. Auto-generated by `dbo clone` and `dbo adopt` — one entry per companion file.
77
+
78
+ ### Structure
79
+ ```json
80
+ {
81
+ "deployments": {
82
+ "{shorthand}": {
83
+ "uid": "{record_uid}",
84
+ "file": "lib/bins/path/to/file.ext",
85
+ "entity": "content|media",
86
+ "column": "Content|File"
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ ### Naming convention
93
+ Shorthands follow `{type}:{name}` pattern:
94
+ - `css:colors` — CSS content record
95
+ - `css:colors_media` — companion media record for same CSS file
96
+ - `css:colors.min` — minified version (content)
97
+ - `js:app.min` — minified JS bundle
98
+ - `doc:chat` — documentation/extension record
99
+ - `cs:_CurrentTicketID` — C# content execution
100
+
101
+ ### Content vs Media records
102
+ Many assets have paired records:
103
+ - **Content record** (`entity: "content"`, `column: "Content"`) — the text/code content
104
+ - **Media record** (`entity: "media"`, `column: "File"`) — the binary file reference
105
+
106
+ The `_media` suffix in the shorthand indicates the media companion record.
107
+
108
+ ---
109
+
110
+ ## Build Scripts (.app/scripts.json)
111
+
112
+ Optional. Defines build and post-push lifecycle hooks per target file.
113
+
114
+ ### Structure
115
+ ```json
116
+ {
117
+ "scripts": {
118
+ "build": []
119
+ },
120
+ "targets": {
121
+ "lib/bins/path/to/output.file": {
122
+ "build": ["command1", "command2"],
123
+ "postpush": ["command3"]
124
+ }
125
+ },
126
+ "entities": {}
127
+ }
128
+ ```
129
+
130
+ ### Script types
131
+ | Type | When it runs | Purpose |
132
+ |------|-------------|---------|
133
+ | `build` | `dbo build` or `npm run build` | Compile source → output |
134
+ | `postpush` | Automatically after `dbo push` of that target | Deploy dependent assets |
135
+
136
+ ### Common build patterns
137
+
138
+ **SASS → CSS → Minified CSS:**
139
+ ```json
140
+ {
141
+ "build": [
142
+ "sass src/sass/core/operator.scss:lib/bins/app/assets/css/operator.css",
143
+ "csso lib/bins/app/assets/css/operator.css --output lib/bins/app/assets/css/operator.min.css"
144
+ ]
145
+ }
146
+ ```
147
+
148
+ **Rollup JS bundling:**
149
+ ```json
150
+ {
151
+ "build": [
152
+ "rollup --config src/rollup.config.mjs"
153
+ ]
154
+ }
155
+ ```
156
+
157
+ **Post-push deploy chain:**
158
+ ```json
159
+ {
160
+ "postpush": [
161
+ "dbo deploy doc:chat",
162
+ "dbo deploy doc:globals"
163
+ ]
164
+ }
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Typical Workflows
170
+
171
+ ### Simple edit and push (most common)
172
+ ```bash
173
+ # Edit a file locally, then push it
174
+ dbo push lib/bins/app/assets/css/colors.css
175
+ ```
176
+
177
+ ### Source → Build → Push (compiled assets)
178
+ ```bash
179
+ # 1. Edit source in src/ (SASS, JS modules, etc.)
180
+ # 2. Build — compiles to lib/bins/
181
+ npm run build
182
+
183
+ # 3. Push compiled output to server
184
+ dbo push lib/bins/app/assets/css/operator.css
185
+ # postpush scripts in scripts.json run automatically
186
+ ```
187
+
188
+ ### New file → Adopt → Push
189
+ ```bash
190
+ # 1. Create the file locally
191
+ # 2. Create a metadata companion
192
+ dbo adopt lib/bins/app/assets/css/new-file.css -e content
193
+
194
+ # 3. Push as a new server record
195
+ dbo push lib/bins/app/assets/css/new-file.css
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Template Variables (CLI scaffolding)
201
+
202
+ When `dbo init` scaffolds this skill into a project's `.claude/`, the CLI can replace these placeholders with app-specific values:
203
+
204
+ | Variable | Replaced with |
205
+ |----------|--------------|
206
+ | `{{domain}}` | `.app/config.json` → `domain` |
207
+ | `{{appName}}` | `.app/config.json` → `AppName` |
208
+ | `{{appShortName}}` | `.app/config.json` → `AppShortName` |
209
+ | `{{appUID}}` | `.app/config.json` → `AppUID` |
210
+ | `{{appID}}` | `.app/config.json` → `AppID` |
@@ -0,0 +1,178 @@
1
+ # DBO Template & Token Syntax
2
+
3
+ Reference for the DBO template language used in outputs, content, and embeds.
4
+
5
+ ## Token Syntax
6
+
7
+ ```
8
+ #{type@reference$target!default:modifier;comment}
9
+ ```
10
+
11
+ Order: `type` → `@ref` → `$target` → `!default` → `:modifier` → `;comment`. All parts except `type` are optional.
12
+
13
+ ### Token Types
14
+
15
+ | Token | Reads from |
16
+ |-------|-----------|
17
+ | `#{value@Field}` | Current row data in render context |
18
+ | `#{request@Param}` | URL / request parameters |
19
+ | `#{session@Field}` | Authenticated session (e.g., `#{session@UserID}`) |
20
+ | `#{input@add1.id}` | ID of record created in same input batch |
21
+ | `#{payload$Target}` | Rendered output of a named embed |
22
+ | `#{unique}` | Generated unique ID |
23
+
24
+ ### Defaults
25
+ ```
26
+ #{request@Param!fallback}
27
+ #{session@CustomerID!#{request@CustomerID}} ← nested token as default
28
+ ```
29
+
30
+ ### Modifiers
31
+
32
+ | Modifier | Effect |
33
+ |----------|--------|
34
+ | `:cached$Target` | Deferred read from named embed — resolves after all embeds execute |
35
+ | `:no_escape` | Raw value, bypasses format-based escaping |
36
+ | `:raw` | Deferred injection via placeholder (final render pass) |
37
+ | `:escape_json` | Force JSON-safe escaping |
38
+ | `:url_encode` | URL percent-encode |
39
+ | `:url_decode` | URL-decode |
40
+ | `:truncate` | Truncate to 100 chars with "..." |
41
+ | `:{format}` | .NET format string (`:d` short date, `:f2` 2 decimals) |
42
+
43
+ **Rule**: Always pair `:cached` with an explicit `$Target`.
44
+
45
+ ## Tag Syntax
46
+
47
+ Three tag systems — do NOT conflate with tokens (`#{...}`):
48
+
49
+ ```html
50
+ <#_tagname attr="val"/> system tags (structural, underscore prefix)
51
+ <#CustomSection>...</#Custom> custom tags (user-defined named sections)
52
+ <@slotName>...</@slotName> slot tags (master template slots)
53
+ ```
54
+
55
+ ### System Tags
56
+
57
+ | Tag | Purpose |
58
+ |-----|---------|
59
+ | `<#_embed url="..." .../>` | Embed another output, content, or input |
60
+ | `<#_row>...</#_row>` | Repeating section — once per result row |
61
+ | `<#_header>` / `<#_footer>` | Before / after all rows |
62
+ | `<#_noresult>` | Renders when query returns zero rows |
63
+ | `<#_empty>` | Also renders on zero rows (after noresult) |
64
+ | `<#_successful>` | Inside input embed — on success |
65
+ | `<#_failed>` | Inside input embed — on failure |
66
+ | `<#_value.Field value="_null">` | Conditional: renders when Field is null |
67
+ | `<#_value.Field modifier="exclude" value="_null">` | Conditional: Field is NOT null |
68
+ | `<#_include target="name">val</#_include>` | Set named variable |
69
+
70
+ ### Parser prefixes
71
+ - **Output & Input parsers**: Accept both `#` and `#_` prefix
72
+ - **Message parser**: Only accepts `#_` prefix
73
+ - **Email parser**: Accepts `~` and `#_` prefix
74
+
75
+ Use `<#_` for system tags consistently to avoid parser ambiguity.
76
+
77
+ ## Embed System
78
+
79
+ Embeds are the primary composition mechanism — internal API call with inlined result.
80
+
81
+ ### Self-closing embed
82
+ ```html
83
+ <#_embed url="/api/output/{uid}" name="label.name" secure="false" target="MyTarget"/>
84
+ ```
85
+
86
+ ### Block embed
87
+ ```html
88
+ <#_embed.myid url="/api/output/{uid}" name="label.name">
89
+ <#_row><li>#{value@Name}</li></#_row>
90
+ <#_noresult><p>None.</p></#_noresult>
91
+ </#_embed.myid>
92
+ ```
93
+
94
+ The `.myid` serialization suffix is required for nested block embeds.
95
+
96
+ ### Embed Attributes
97
+
98
+ | Attribute | Default | Notes |
99
+ |-----------|---------|-------|
100
+ | `url` | required | Endpoint to embed |
101
+ | `name` | — | Label for debugging and payload ID |
102
+ | `target` | — | Context for `:cached` tokens and `#{payload$...}` |
103
+ | `secure` | `true` | `false` bypasses access control for this request |
104
+ | `execute` | `true` | `false` skips the call entirely |
105
+ | `hide` | `false` | `true` executes but suppresses output |
106
+ | `payload` | `true` | `false` skips caching rendered output |
107
+ | `catch_exception` | `"401,406"` | HTTP codes caught silently; `"true"` catches all |
108
+
109
+ ### URL prefixes
110
+ | Short | Full |
111
+ |-------|------|
112
+ | `/api/o/` | `/api/output/{uid}` |
113
+ | `/api/c/` | `/api/content/{uid}` |
114
+ | `/api/i/s` | `/api/input/submit` |
115
+
116
+ ## Output Template Sections
117
+
118
+ ```
119
+ [_header] → [_row × N] → [_footer]
120
+ ↘ [_noresult] + [_empty] if N = 0
121
+ ```
122
+
123
+ Custom sections (`<#SectionName>...</#SectionName>`) are named blocks for composability.
124
+
125
+ ## Common Patterns
126
+
127
+ ### Data read with inline template
128
+ ```html
129
+ <#_embed.list url="/api/output/{uid}" name="my.list">
130
+ <#_row><div>#{value@Name}</div></#_row>
131
+ <#_noresult><p>No results.</p></#_noresult>
132
+ </#_embed.list>
133
+ ```
134
+
135
+ ### Two-phase write (insert + cross-reference)
136
+ ```html
137
+ <#_embed.first url="/api/input/submit?_confirm=true
138
+ &RowID:add1;column:table.TypeID=24">
139
+ <#_successful>
140
+ <#_embed url="/api/input/submit?_confirm=true
141
+ &RowID:add2;column:table.ParentID=#{input@add1.id}"/>
142
+ </#_successful>
143
+ <#_failed>Write failed.</#_failed>
144
+ </#_embed.first>
145
+ ```
146
+
147
+ ### Read from named embed payload
148
+ ```html
149
+ <#_embed url="/api/output/{uid}" target="MyOutput"/>
150
+ #{value@SomeField:cached$MyOutput}
151
+ ```
152
+
153
+ ### Flow file (backend action, no UI)
154
+ ```html
155
+ <#_embed url="/api/output/{uid}" target="Ctx" hide="true" secure="false"/>
156
+ <#_embed.action url="/api/input/submit?_confirm=true&RowID:add1;...">
157
+ <#_successful>{"ok": true}</#_successful>
158
+ <#_failed>{"ok": false}</#_failed>
159
+ </#_embed.action>
160
+ ```
161
+
162
+ ## Input Forms (browser-side)
163
+
164
+ ```html
165
+ <form id="my-form" data-os-form="{validate: true, done: function() {...}}">
166
+ <input name="RowID:{id};column:table.Field" value="#{value@Field}" />
167
+ </form>
168
+ ```
169
+
170
+ Submit: `os.form.submit('#my-form')`
171
+
172
+ ## Security Context
173
+
174
+ - `LoggedInUser` — always used for security evaluation
175
+ - `CurrentUser` — render context, changed by impersonation (`_as`)
176
+ - `Administrator` flag — bypasses all security checks
177
+ - `secure="false"` on embed — bypasses access control for that request only
178
+ - Default: 401/406 from embeds are caught silently
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "track",
3
+ "version": "1.0.0",
4
+ "description": "Changelog and Track API logging for Claude Code — automatically logs changes to changelog.md and the remote Track task_log on every session",
5
+ "author": {
6
+ "name": "DBO.io"
7
+ },
8
+ "hooks": [
9
+ {
10
+ "path": "hooks/hooks.json"
11
+ }
12
+ ],
13
+ "skills": [
14
+ {
15
+ "path": "skills/changelog/SKILL.md",
16
+ "name": "changelog",
17
+ "description": "Changelog and Track API logging instructions — when and how to write changelog.md entries and submit to the Track task_log API after editing source files or pushing DBO assets"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,135 @@
1
+ # Track Plugin for Claude Code
2
+
3
+ Claude Code plugin that automatically logs every change to a local `changelog.md` and to the centralized Track `task_log` API. Runs on every session, across every project.
4
+
5
+ ## Why this plugin exists (and why the old approach was messy)
6
+
7
+ Before this plugin, the changelog and Track API workflow was managed by a bash setup script (`changelog-setup.sh`) that:
8
+
9
+ 1. **Mutated global `~/.claude/CLAUDE.md` in-place** — appended a large `## Changelog` section directly into the user's personal instructions file. This made the file hard to maintain, impossible to version, and fragile to update (the script used `sed` to find and remove the section before rewriting it).
10
+
11
+ 2. **Had no source of truth** — the changelog instructions lived in a generated file that no one committed, so it was unclear what version any given machine was running.
12
+
13
+ 3. **No per-project opt-out** — once installed, the behavior applied everywhere with no way to suppress it for projects where it doesn't make sense (non-manolab apps, open-source contributions, scratch projects).
14
+
15
+ 4. **Installed a skill to the wrong location** — `/changelog-summary` was written to `~/.claude/skills/`, outside any versioned repository, making it invisible to code review and hard to iterate on.
16
+
17
+ 5. **Required re-running the script to update** — any change to the instructions meant running the script again, hoping the sed cleanup worked, and restarting Claude.
18
+
19
+ ### What the plugin approach solves
20
+
21
+ | Problem | Old approach | Plugin approach |
22
+ |---------|-------------|-----------------|
23
+ | Changelog instructions | Appended to `~/.claude/CLAUDE.md` | Owned by `skills/changelog/SKILL.md` |
24
+ | Versioning | Unversioned, generated | Committed alongside the CLI source |
25
+ | Updates | Re-run bash script | `dbo install plugins` or `npm update @dboio/cli` |
26
+ | Per-project opt-out | Not possible | One line in local `CLAUDE.md` overrides globally |
27
+ | `/changelog-summary` skill | Written to `~/.claude/skills/` | Defined in the CLI package |
28
+ | Session loading | Always in context (inflates every session) | Loaded via SessionStart hook (loaded once, cleanly) |
29
+
30
+ ### Architecture: additive, not replacing
31
+
32
+ The plugin does **not** remove or replace the `## Changelog` section in `~/.claude/CLAUDE.md`. Both run in parallel:
33
+
34
+ ```
35
+ Global ~/.claude/CLAUDE.md → "always log changelog" (universal floor — fires even outside repos)
36
+ Plugin SessionStart hook → loads changelog skill (versioned, updatable delivery mechanism)
37
+ Project CLAUDE.md (opt-out) → "skip for this project" → overrides both ↑
38
+ ```
39
+
40
+ The global CLAUDE.md is the coverage guarantee — it fires unconditionally on every session including scratch files and paths outside any repository. The plugin is the delivery mechanism that keeps the instructions versioned and makes per-project opt-out possible. The two sources carry identical instructions, so duplication is invisible in practice.
41
+
42
+ A local project CLAUDE.md opt-out suppresses both sources. Claude Code's CLAUDE.md hierarchy treats the project-level file as more specific than global, and the opt-out language is explicit enough to make the override unambiguous.
43
+
44
+ ## Plugin Structure
45
+
46
+ ```
47
+ track/
48
+ ├── .claude-plugin/
49
+ │ └── plugin.json # Plugin manifest (version, hooks, skills)
50
+ ├── commands/
51
+ │ └── install.md # /track install — one-time machine setup
52
+ ├── hooks/
53
+ │ └── hooks.json # SessionStart: always loads changelog skill
54
+ ├── skills/
55
+ │ └── changelog/
56
+ │ └── SKILL.md # Full changelog + Track API logging instructions
57
+ └── README.md # This file
58
+ ```
59
+
60
+ ## Components
61
+
62
+ ### `/track install` command (`commands/install.md`)
63
+
64
+ User-invocable slash command for one-time machine setup. Run this once per machine after the CLI is installed. It:
65
+
66
+ 1. Creates `~/.claude/track-changelog` — the interactive login script that authenticates with `beta-track.dbo.io` and saves a session cookie to `~/.claude/track-cookies.txt`
67
+ 2. Prints next-step instructions
68
+
69
+ It does **not** touch `~/.claude/CLAUDE.md` — the global changelog instructions stay in place as a coverage guarantee (see Architecture above).
70
+
71
+ ### SessionStart hook (`hooks/hooks.json`)
72
+
73
+ Fires at the start of every Claude Code session. Tells Claude to load the `changelog` skill unconditionally. Also instructs Claude to honour any per-project opt-out directive found in a local CLAUDE.md.
74
+
75
+ ### Changelog skill (`skills/changelog/SKILL.md`)
76
+
77
+ The authoritative source of truth for all logging behavior. Contains:
78
+
79
+ - **When to log**: after any source file edit; additionally after DBO asset pushes
80
+ - **File format**: `changelog.md` table schema with Date, Time, Asset Type, Name, UID, Description columns
81
+ - **Track API session check**: how to verify the cookie is valid before the first log entry of each session
82
+ - **Track API write**: the `curl` command for submitting a `task_log` row, including all field semantics
83
+ - **Error handling**: what to do when the API is unreachable or the session has expired
84
+ - **Opt-out awareness**: how to detect and respect per-project suppression directives
85
+
86
+ ## Installation
87
+
88
+ The track plugin ships inside the `@dboio/cli` npm package alongside the `dbo` plugin. It is installed automatically when you run:
89
+
90
+ ```bash
91
+ dbo install plugins --local # install into the current project
92
+ dbo install plugins --global # install for all projects on this machine
93
+ ```
94
+
95
+ After installation, run the one-time machine setup:
96
+
97
+ ```
98
+ /track install
99
+ ```
100
+
101
+ This creates `~/.claude/track-changelog`. Then open a terminal and authenticate:
102
+
103
+ ```bash
104
+ ~/.claude/track-changelog
105
+ ```
106
+
107
+ ## Per-project opt-out
108
+
109
+ To suppress changelog logging and Track API calls for a specific project, add this to the project's `CLAUDE.md`:
110
+
111
+ ```markdown
112
+ ## Track Logging
113
+
114
+ **Do not write changelog entries or call the Track API for this project.**
115
+
116
+ This project is not tracked in Track. Skip all `changelog.md` writes and
117
+ `beta-track.dbo.io` API calls, even though the track plugin is installed globally.
118
+ This directive overrides both the global CLAUDE.md and the track plugin.
119
+ ```
120
+
121
+ Claude Code's CLAUDE.md hierarchy treats the project-level file as more specific than global, so this suppresses both sources. The SessionStart hook is also explicitly instructed to honour local opt-out directives.
122
+
123
+ ## Authentication
124
+
125
+ The Track API uses cookie-based session auth. The session cookie is stored at `~/.claude/track-cookies.txt` and is shared across all Claude Code sessions on the machine.
126
+
127
+ - **To log in**: run `~/.claude/track-changelog` in a terminal
128
+ - **If the session expires**: Claude will tell you "Track Access Denied" — re-run `~/.claude/track-changelog`
129
+ - Claude never attempts to log in on your behalf or store credentials
130
+
131
+ ## Version History
132
+
133
+ | Version | Changes |
134
+ |---------|---------|
135
+ | 1.0.0 | Initial release — replaces `changelog-setup.sh`. SessionStart hook, changelog skill, `/track install` command |
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: install
3
+ description: Install the Track changelog integration — creates ~/.claude/track-changelog login script.
4
+ user-invokable: true
5
+ allowed-tools: Write, Bash(chmod:*)
6
+ ---
7
+
8
+ # Track Plugin Install
9
+
10
+ Set up the Track changelog integration on this machine. Run this once per machine after installing the track plugin.
11
+
12
+ ## Steps
13
+
14
+ ### 1. Create `~/.claude/track-changelog`
15
+
16
+ Write the following script to `~/.claude/track-changelog` (use the Write tool):
17
+
18
+ ```bash
19
+ #!/bin/bash
20
+ # track-changelog — Authenticate with Track (beta-track.dbo.io) and store session cookie
21
+ # Usage: ~/.claude/track-changelog
22
+ # Cookie is saved to ~/.claude/track-cookies.txt for use by the Track Claude plugin
23
+
24
+ TRACK_DOMAIN="beta-track.dbo.io"
25
+ COOKIE_FILE="$HOME/.claude/track-cookies.txt"
26
+ SESSION_API="https://$TRACK_DOMAIN/api/o/asqor6nmxuiwqbhldlki7g"
27
+
28
+ echo "=== Track Login ==="
29
+ echo "Domain: $TRACK_DOMAIN"
30
+ echo ""
31
+
32
+ # Prompt for credentials (password hidden)
33
+ read -p "Email: " email
34
+ read -s -p "Password: " password
35
+ echo ""
36
+
37
+ # Authenticate
38
+ response=$(curl -s -c "$COOKIE_FILE" -w "\n%{http_code}" \
39
+ "https://$TRACK_DOMAIN/api/input/submit" \
40
+ --data-urlencode "_username=$email" \
41
+ --data-urlencode "_password=$password" \
42
+ --data-urlencode "_confirm=true")
43
+
44
+ http_code=$(echo "$response" | tail -1)
45
+
46
+ if [ "$http_code" = "307" ] || [ "$http_code" = "403" ]; then
47
+ echo "Login failed (HTTP $http_code). Check your credentials."
48
+ rm -f "$COOKIE_FILE"
49
+ exit 1
50
+ fi
51
+
52
+ # Verify session
53
+ session=$(curl -s -b "$COOKIE_FILE" "$SESSION_API")
54
+
55
+ if [ "$session" = "[]" ] || [ -z "$session" ]; then
56
+ echo "Login failed — session not established."
57
+ rm -f "$COOKIE_FILE"
58
+ exit 1
59
+ fi
60
+
61
+ # Extract user info
62
+ name=$(echo "$session" | grep -o '"FirstName":"[^"]*"' | head -1 | cut -d'"' -f4)
63
+ contact_id=$(echo "$session" | grep -o '"ContactID":"[^"]*"' | head -1 | cut -d'"' -f4)
64
+
65
+ echo ""
66
+ echo "Logged in as: $name (ContactID: $contact_id)"
67
+ echo "Cookie saved: $COOKIE_FILE"
68
+ echo ""
69
+ echo "Session is ready for the Track Claude plugin."
70
+ ```
71
+
72
+ After writing the file, make it executable:
73
+ ```bash
74
+ chmod +x ~/.claude/track-changelog
75
+ ```
76
+
77
+ ### 2. Confirm and show next steps
78
+
79
+ Tell the user:
80
+
81
+ ```
82
+ Track plugin installed.
83
+
84
+ Next steps:
85
+ 1. Open a new terminal and run: ~/.claude/track-changelog
86
+ (Enter your Track email and password to establish a session)
87
+
88
+ 2. Restart any open Claude Code sessions to pick up the plugin
89
+
90
+ 3. Claude will now automatically:
91
+ - Log changes to <project-memory>/changelog.md (local)
92
+ - Write each entry to the Track task_log (remote)
93
+ - Honour per-project opt-out directives in CLAUDE.md
94
+
95
+ If you see "Track Access Denied", re-run ~/.claude/track-changelog
96
+ ```
@@ -0,0 +1,11 @@
1
+ {
2
+ "description": "Track plugin hooks — loads versioned changelog and Track API logging instructions at every session start",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "type": "prompt",
7
+ "prompt": "Invoke the /track:changelog skill to load the versioned changelog and Track API logging instructions. If a local CLAUDE.md in the current project contains an explicit directive to skip changelog logging or Track API calls (e.g. 'Do not write changelog entries or call the Track API for this project'), honour that override — it supersedes both this skill and the global CLAUDE.md changelog instructions."
8
+ }
9
+ ]
10
+ }
11
+ }