@bluestep-systems/bspecs 0.12.0 → 0.14.0
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.
- package/package.json +1 -1
- package/templates/claude/instructions/b6p-platform.md.template +7 -8
- package/templates/claude/instructions/bsjs-development.md.template +1 -1
- package/templates/claude/instructions/index.md.template +2 -4
- package/templates/claude/instructions/reference/b-include-element.md.template +46 -0
- package/templates/claude/instructions/reference/csv-parsing.md.template +1 -1
- package/templates/claude/instructions/reference/endpoint-urls.md.template +1 -1
- package/templates/claude/instructions/reference/file-execution.md.template +1 -1
- package/templates/claude/instructions/reference/merge-report-async-loading.md.template +41 -0
- package/templates/claude/instructions/reference/merge-report-memo-json.md.template +1 -1
- package/templates/claude/skills/b6p-audit/SKILL.md +1 -1
- package/templates/claude/skills/b6p-pull/SKILL.md +2 -3
- package/templates/claude/skills/b6p-push/SKILL.md +3 -3
- package/templates/claude/instructions/conventions/always-snapshot.md.template +0 -25
- package/templates/claude/instructions/conventions/push-inner-draft.md.template +0 -21
- package/templates/claude/instructions/conventions/snapshot-integrity.md.template +0 -23
- package/templates/claude/instructions/conventions/tsc-rootdir.md.template +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: BlueStep Platform overview — architecture (Relate/Connect/Manage/BsJs), the b6p CLI, sync, and component lifecycle. Read when orienting on the platform, working with the b6p CLI, or troubleshooting pull/push sync.
|
|
3
|
-
applyTo: "**/.b6p_metadata.json"
|
|
4
3
|
---
|
|
5
4
|
|
|
6
5
|
# B6P Platform Workflow
|
|
@@ -14,7 +13,7 @@ Platform orientation plus the workflow reference for sync, lifecycle, and the b6
|
|
|
14
13
|
- [Data hierarchy](#data-hierarchy)
|
|
15
14
|
- [Script types](#script-types)
|
|
16
15
|
- [b6p CLI workflow](#b6p-cli-workflow)
|
|
17
|
-
- [
|
|
16
|
+
- [Sync metadata](#sync-metadata)
|
|
18
17
|
- [Files Claude must never edit](#files-claude-must-never-edit)
|
|
19
18
|
- [Imports — verification flow](#imports--verification-flow)
|
|
20
19
|
- [When the CLI fails](#when-the-cli-fails)
|
|
@@ -113,27 +112,27 @@ A successful first pull:
|
|
|
113
112
|
- Creates the `U######/` folder (if not present) and the `<ComponentName>/` subfolder under it
|
|
114
113
|
- Populates `draft/scripts/`, `draft/info/`, and (in older modules) `draft/objects/`
|
|
115
114
|
- Populates `declarations/` with the platform-generated `.d.ts` files, including `declarations/index.d.ts` (field/query/form declarations)
|
|
116
|
-
-
|
|
115
|
+
- Records the component's sync metadata (WebDAV id, file hashes, script key) so future pulls/pushes can resolve it
|
|
117
116
|
|
|
118
117
|
Subsequent pulls verify per-file integrity and only rewrite files whose content changed.
|
|
119
118
|
|
|
120
119
|
### Push a component
|
|
121
120
|
|
|
122
|
-
The cleanest way to push an already-pulled component is `--file`, which lets the CLI derive the destination DAV URL from
|
|
121
|
+
The cleanest way to push an already-pulled component is `--file`, which lets the CLI derive the destination DAV URL from the recorded sync metadata:
|
|
123
122
|
|
|
124
123
|
```
|
|
125
124
|
npx b6p push --file "U######/<Component>/draft/scripts/app.ts"
|
|
126
125
|
```
|
|
127
126
|
|
|
128
|
-
Any file inside the component works as the `--file` argument; the CLI walks up to find
|
|
127
|
+
Any file inside the component works as the `--file` argument; the CLI walks up to find the component root and looks up its recorded sync metadata. Same per-file integrity check applies — only changed files are uploaded. The platform compiles after receiving the push.
|
|
129
128
|
|
|
130
129
|
### Fallback: VS Code extension
|
|
131
130
|
|
|
132
131
|
If the `b6p` CLI fails (network, lock, auth), the VS Code **b6p extension** is an equivalent fallback for pull/push operations.
|
|
133
132
|
|
|
134
|
-
##
|
|
133
|
+
## Sync metadata
|
|
135
134
|
|
|
136
|
-
Auto-managed by the CLI. Tracks WebDAV IDs, last-pull / last-push timestamps, file hashes, and script keys.
|
|
135
|
+
Auto-managed by the CLI and stored internally (no longer a `.b6p_metadata.json` file in the workspace; legacy files are migrated on first run). Tracks WebDAV IDs, last-pull / last-push timestamps, file hashes, and script keys, so pull/push/audit can resolve each component. Not something you edit.
|
|
137
136
|
|
|
138
137
|
## Files Claude must never edit
|
|
139
138
|
|
|
@@ -173,7 +172,7 @@ Common causes:
|
|
|
173
172
|
Fallbacks:
|
|
174
173
|
|
|
175
174
|
1. The VS Code b6p extension provides the same pull/push operations through the editor UI.
|
|
176
|
-
2. As a last resort, the platform UI lets you download/upload component files manually — but
|
|
175
|
+
2. As a last resort, the platform UI lets you download/upload component files manually — but manual uploads bypass the CLI's recorded sync metadata, making future CLI sync fragile.
|
|
177
176
|
|
|
178
177
|
## When `B.commit()` is required
|
|
179
178
|
|
|
@@ -327,7 +327,7 @@ Each project root has a `tsconfig.json`. BlueStep projects run with **`strict: f
|
|
|
327
327
|
}
|
|
328
328
|
```
|
|
329
329
|
|
|
330
|
-
Do not run `tsc` locally — the platform compiles on push (a hook blocks local `tsc`).
|
|
330
|
+
Do not run `tsc` locally — the platform compiles on push (a hook blocks local `tsc`).
|
|
331
331
|
|
|
332
332
|
### Graal compatibility (server-side)
|
|
333
333
|
|
|
@@ -11,6 +11,7 @@ Entries read: `path — what it covers. Load when <trigger>.` Match the trigger
|
|
|
11
11
|
## reference/ — single-topic platform and API detail
|
|
12
12
|
|
|
13
13
|
- [reference/api-patterns.md](reference/api-patterns.md) — B API usage: Java optionals (`.opt()/.orElse()`), field types and access, `mergeTag()` L/F/I/H codes, multi-entry-form (MEF) entries, query access, Java collections, writing date/datetime fields, `B.commit()` and formula triggers, endpoint request/response, base64, user/session. Load when calling the `B` API, reading or writing fields, or wiring an endpoint's request/response.
|
|
14
|
+
- [reference/b-include-element.md](reference/b-include-element.md) — `<b-include>` browser custom element that fetches HTML from a URL and renders it inline (client-side `<jsp:include>`/SSI); `src`/`run-scripts`/`csrf` attrs, spinner/error behavior, trusted-template-only (neutralized in user HTML). Load when injecting a dynamic async HTML fragment in the browser.
|
|
14
15
|
- [reference/blueiq-credit-integration-playbook.md](reference/blueiq-credit-integration-playbook.md) — step-by-step playbook for wiring a new OpenAI/AI feature into the BlueIQ credit gate and ledger. Load when adding an AI feature that must consume BlueIQ credits.
|
|
15
16
|
- [reference/chronounit-months.md](reference/chronounit-months.md) — `ChronoUnit.MONTHS.between` counts elapsed (day-aware) months, not calendar-month boundaries. Load when computing a month difference or porting SQL `DATEDIFF(MONTH)`.
|
|
16
17
|
- [reference/code-patterns.md](reference/code-patterns.md) — working BsJs skeletons: queries, MergeReport server/client bridge, endpoints, error handling, performance (per-row queue, lazy init), component import, debugging. Load when starting a query, MergeReport, or endpoint and you want a known-good pattern.
|
|
@@ -31,6 +32,7 @@ Entries read: `path — what it covers. Load when <trigger>.` Match the trigger
|
|
|
31
32
|
- [reference/id-full-vs-short.md](reference/id-full-vs-short.md) — `Id.toString()` is the full `ClassID___ShortID`; `shortId()` is just the trailing number; `optById` needs the full form. Load when round-tripping an entry id or calling `optById`.
|
|
32
33
|
- [reference/internal-loopback-fetch.md](reference/internal-loopback-fetch.md) — endpoint-to-endpoint loopback within an org uses `B.net.fetch` on a relative path with `credentials:true`, not the external `httpRequester`. Load when one endpoint calls another in the same org.
|
|
33
34
|
- [reference/localdate-parse.md](reference/localdate-parse.md) — `Java.Time.LocalDate` is a TypeScript namespace only; use `B.time.LocalDate` for runtime `parse()`/`now()`. Load when parsing or creating a LocalDate.
|
|
35
|
+
- [reference/merge-report-async-loading.md](reference/merge-report-async-loading.md) — the "Asynchronous Loading" option on a Data Merge Report lazy-loads it AFTER the page resolves (BSJS used an `async` metadata property, not the checkbox); parent→child fan-out, the obsolete `formFooter` hack, and the script-timing gotcha. Load when a merge report is slow or should lazy-load, or page script depends on async merge content.
|
|
34
36
|
- [reference/merge-report-memo-json.md](reference/merge-report-memo-json.md) — the "MergeReport + memo field JSON" framework: embed a custom interactive widget on a form that persists its state as JSON in a hidden memo field. Load when building a stateful custom widget on a form.
|
|
35
37
|
- [reference/merge-report-static-index.md](reference/merge-report-static-index.md) — with a `static/` bundle, `static/index.html` is the page and `app.ts` `B.out` is NOT injected; put the mount + config island in `index.html` and run the client on `DOMContentLoaded`. Load when a MergeReport has a `static/` bundle.
|
|
36
38
|
- [reference/merge-report-urls.md](reference/merge-report-urls.md) — BSJS equivalents of relatescript `lookupMergeReport`/`lookupMergeReportScript`, and how to get `viewUrl`/`printUrl`. Load when looking up a MergeReport URL in code.
|
|
@@ -47,19 +49,15 @@ Entries read: `path — what it covers. Load when <trigger>.` Match the trigger
|
|
|
47
49
|
|
|
48
50
|
## conventions/ — build, deploy, and workflow directives
|
|
49
51
|
|
|
50
|
-
- [conventions/always-snapshot.md](conventions/always-snapshot.md) — pull/push/snapshot workflow: use the CLI scripts (never fetch manually) and snapshot after every change via push → pull → snapshot. Load when syncing a component or unsure of the snapshot routine.
|
|
51
52
|
- [conventions/blueiq-no-ai-branding.md](conventions/blueiq-no-ai-branding.md) — never put "AI" in front-facing BlueIQ text; the brand is always "BlueIQ". Load when writing user-visible BlueIQ copy.
|
|
52
53
|
- [conventions/date-format.md](conventions/date-format.md) — `addSearch` needs `MM/DD/YYYY` for date fields; `YYYY/MM/DD` passes validation but silently fails to filter, and raw Java `LocalDate` objects also fail. Load when filtering a query by a date field.
|
|
53
54
|
- [conventions/endpoint-approach.md](conventions/endpoint-approach.md) — research-first: gather API docs, read type declarations, and study existing examples before writing an endpoint. Load when starting a new endpoint.
|
|
54
55
|
- [conventions/formula-patterns.md](conventions/formula-patterns.md) — correct BSJS formula patterns: form access, field reads/writes, HTTP, error handling, `B.*` utilities, DocumentLinkField. Load when writing a Formula or Post-Save script.
|
|
55
56
|
- [conventions/no-global-dollar.md](conventions/no-global-dollar.md) — never define a global `$` in MergeReport scripts; pages use jQuery and you will silently break Save and all page interactivity. Load when adding client JS to a MergeReport.
|
|
56
|
-
- [conventions/push-inner-draft.md](conventions/push-inner-draft.md) — pass the inner `draft/` folder (not the component root) to `push.js`, or files land in a `draft/draft/*` dead zone. Load when pushing a component with `push.js`.
|
|
57
57
|
- [conventions/separate-files.md](conventions/separate-files.md) — don't pile CSS/HTML/JS into `app.ts`; use the `styles.css`/`index.html`/`script.ts` files the pulled folder already has. Load when structuring MergeReport files.
|
|
58
58
|
- [conventions/single-script.md](conventions/single-script.md) — the server-side build compiles only root `static/script.ts` to `.build/script.js`; subdirectory `.ts` files are NOT compiled. Load when splitting client scripts into multiple files.
|
|
59
|
-
- [conventions/snapshot-integrity.md](conventions/snapshot-integrity.md) — snapshots register cleanly only when `push.js` sends locally-compiled `.build/*` alongside source, otherwise a manual re-snapshot is needed. Load when a push leaves the snapshot needing manual re-registration.
|
|
60
59
|
- [conventions/top-level-const-tdz.md](conventions/top-level-const-tdz.md) — endpoint/MergeReport scripts run top-down; declare every `const`/`let` above the entry `try` block or they are in TDZ when the handler fires. Load when ordering declarations in an endpoint or MergeReport.
|
|
61
60
|
- [conventions/ts-in-template-literal.md](conventions/ts-in-template-literal.md) — the inline `<script>` inside a `B.out` template literal must be plain JS; any TypeScript syntax ships verbatim to the browser and breaks parsing. Load when emitting client JS through a `B.out` string.
|
|
62
|
-
- [conventions/tsc-rootdir.md](conventions/tsc-rootdir.md) — compile endpoints with `--rootDir .` so output mirrors `scripts/app.ts` → `.build/scripts/app.js`; `--rootDir ./scripts` emits to `.build/app.js`, which the runtime ignores. Load when configuring the local TypeScript build for an endpoint.
|
|
63
61
|
|
|
64
62
|
## gotchas/ — sharp edges
|
|
65
63
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "`<b-include>` is a browser custom element that fetches HTML from a URL and renders it inline — client-side `<jsp:include>`/SSI for dynamic async content; trusted-template only (neutralized in user-supplied HTML)"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
`<b-include>` is a **browser custom element** (defined in `dom.ts:432-560`) that
|
|
6
|
+
**fetches HTML from a URL and renders it inline** — think client-side `<jsp:include>`
|
|
7
|
+
/ server-side-include for the browser. Use it for dynamic, async page fragments.
|
|
8
|
+
|
|
9
|
+
**Syntax** — must use an explicit closing tag (it is **not** self-closing):
|
|
10
|
+
```html
|
|
11
|
+
<b-include src="/path/to/fragment.jsp"></b-include>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Attributes**
|
|
15
|
+
|
|
16
|
+
| Attribute | Values | Purpose |
|
|
17
|
+
| ------------- | --------------------- | ------- |
|
|
18
|
+
| `src` | URL | Content to fetch. **Reactive** — changing it re-fetches automatically. |
|
|
19
|
+
| `run-scripts` | `"true"` \| (omit) | When `"true"`, `<script>` tags in the fetched HTML are re-inserted so the browser executes them. Default: scripts are inert. |
|
|
20
|
+
| `csrf` | `"true"` \| `"false"` \| (omit) | Force CSRF handling. Omit for auto-detect: same-origin → `csrf.fetch`, cross-origin → plain fetch. |
|
|
21
|
+
|
|
22
|
+
**Examples**
|
|
23
|
+
```html
|
|
24
|
+
<!-- Basic same-origin include (CSRF token auto-attached) -->
|
|
25
|
+
<b-include src="/shared/content/fragment.jsp"></b-include>
|
|
26
|
+
|
|
27
|
+
<!-- Include a fragment and run its <script> tags -->
|
|
28
|
+
<b-include src="/path/with/scripts.html" run-scripts="true"></b-include>
|
|
29
|
+
|
|
30
|
+
<!-- Cross-origin with forced CSRF off (remote must send CORS headers) -->
|
|
31
|
+
<b-include src="https://other.example.com/widget" csrf="false"></b-include>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Behavior**
|
|
35
|
+
- Shows a spinner while loading; shows an error box with a **"Reload"** link on failure.
|
|
36
|
+
- Re-setting `src` aborts the in-flight request and re-fetches.
|
|
37
|
+
- Removal from the DOM aborts any pending request.
|
|
38
|
+
- Drivable from JS via properties: `el.src`, `el.runScripts`, `el.csrf`.
|
|
39
|
+
|
|
40
|
+
**Security — trusted templates only.** `<b-include>` is **neutralized in user-supplied
|
|
41
|
+
content** by `HTMLFilter.java:46` (rewritten to `<xxb-includexx>`) to prevent injection.
|
|
42
|
+
Only use it in **trusted templates**, never in user-editable HTML. The Zesty editor
|
|
43
|
+
whitelists it as `b-include[src|run-scripts|csrf]` (`zesty3.ts:130`).
|
|
44
|
+
|
|
45
|
+
For the server-side config alternative (a merge report that lazy-loads after the page),
|
|
46
|
+
see [merge-report-async-loading](merge-report-async-loading.md).
|
|
@@ -15,4 +15,4 @@ A server-side BSJS merge report CAN access and parse an uploaded CSV at runtime.
|
|
|
15
15
|
|
|
16
16
|
**Gotchas:** strip UTF-8 BOM (`` corrupts first header key on Excel/QuickBooks exports); handle `\r\n`; sanitize currency (`$`, thousands commas, `(123)` negatives) before parseFloat; pass charset if Windows-1252; streaming `.forReader()` avoids buffering huge files and sidesteps the "code 0 but real content" issue seen with `B.io.fromInputStream`.
|
|
17
17
|
|
|
18
|
-
**Relevance:** unlocks the behavioral scorecard placeholder metrics that aren't in relational data — MRR, Monthly Profitability, Avg Contribution Margin (QuickBooks exports), NPS (survey results). Pattern: upload CSV to a Document field on a settings record; in app.ts `field.forReader(r => B.csv(r).toListOfObjects())`; the metric's Verify table can show the parsed rows.
|
|
18
|
+
**Relevance:** unlocks the behavioral scorecard placeholder metrics that aren't in relational data — MRR, Monthly Profitability, Avg Contribution Margin (QuickBooks exports), NPS (survey results). Pattern: upload CSV to a Document field on a settings record; in app.ts `field.forReader(r => B.csv(r).toListOfObjects())`; the metric's Verify table can show the parsed rows.
|
|
@@ -11,5 +11,5 @@ The alias is set per-endpoint in BlueStep admin and is not derivable from the sc
|
|
|
11
11
|
|
|
12
12
|
**How to apply:**
|
|
13
13
|
- When reporting test URLs to the user, ask what the friendly alias is — do not guess from the script name or fall back to the `/files/.../draft/` URL.
|
|
14
|
-
- The
|
|
14
|
+
- The DAV `url` the CLI recorded for the component is the editor URL, not the runtime URL.
|
|
15
15
|
- If the user reports "500 / Error" on an endpoint, ask them to confirm the alias before adding script-side error handling.
|
|
@@ -79,7 +79,7 @@ The legacy `objects/imports.ts` `.require()` registration did this in code; it i
|
|
|
79
79
|
|
|
80
80
|
## Workspace Sync
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
The b6p CLI tracks sync state between the local workspace and the BlueStep server — script metadata (name, org ID, WebDAV ID), per-file last-sync timestamps, and build state — in its own internal store (no longer a `.b6p_metadata.json` file in the workspace). The `draft/` directory holds the working version of the code; the `.build/` directories hold the compiled JavaScript output from the TypeScript source.
|
|
83
83
|
|
|
84
84
|
## Common Mistakes
|
|
85
85
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: A Data Merge Report's "Asynchronous Loading" option makes it lazy-load AFTER the rest of the page resolves instead of as part of the initial request; in BSJS this was an `async` metadata property rather than the checkbox
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
A BlueStep **Data Merge Report** has an **"Asynchronous Loading"** checkbox under
|
|
6
|
+
*Advanced Usage Options* (Step 3 of the merge-report edit wizard). Turning it on
|
|
7
|
+
makes the merge report **resolve in a lazy-load rather than as part of the initial
|
|
8
|
+
page request** — the rest of the page renders first, then the merge report loads
|
|
9
|
+
in separately so a heavy merge doesn't slow everything else down.
|
|
10
|
+
|
|
11
|
+
This is **not a new feature**. It maps directly to the underlying DB object and has
|
|
12
|
+
existed for a long time. **BSJS had no toggle** — you set an `async` property in the
|
|
13
|
+
component metadata, which inserted a layer of indirection over that same DB object.
|
|
14
|
+
Removing that BSJS layer is what surfaced the plain checkbox; it only *looks* new to
|
|
15
|
+
anyone who previously only used BSJS.
|
|
16
|
+
|
|
17
|
+
**Parent → child behavior.** When a merge report calls another async merge report,
|
|
18
|
+
the **parent's HTML resolves first**, the page loads, and then each async child
|
|
19
|
+
loads separately — so a parent merge report that fans out to N children can give
|
|
20
|
+
each child its own independent loader. (The resident-med report does exactly this:
|
|
21
|
+
a nasty merge that renders per resident, switched to async, **loads in batches of
|
|
22
|
+
3 at a time**.)
|
|
23
|
+
|
|
24
|
+
**Good use cases:** heavy/slow merges; merge reports embedded on a form; a parent
|
|
25
|
+
merge report aggregating several child merge reports; query-driven layouts where
|
|
26
|
+
displayed merge-report fields can stream in after the header data.
|
|
27
|
+
|
|
28
|
+
**Gotcha — script timing.** Because the content is no longer present at initial page
|
|
29
|
+
load, any page script that **expects the async merge report's DOM/data to already be
|
|
30
|
+
there will break**. If you have client code depending on the merge report, gate it on
|
|
31
|
+
the async content actually arriving rather than on initial `DOMContentLoaded`.
|
|
32
|
+
|
|
33
|
+
**Obsolete hack.** Older setups added a marker like
|
|
34
|
+
`htmlCode += '<span id="formFooter"></span>'` to force the async merge report to load
|
|
35
|
+
properly. With the current setup this should **no longer be necessary** — don't carry
|
|
36
|
+
it forward into new code.
|
|
37
|
+
|
|
38
|
+
For dynamic async content driven from the client (rather than this server-side
|
|
39
|
+
config), see [b-include element](b-include-element.md). Related merge-report detail:
|
|
40
|
+
[merge-report-static-index](merge-report-static-index.md),
|
|
41
|
+
[merge-report-memo-json](merge-report-memo-json.md).
|
|
@@ -20,6 +20,6 @@ The recurring **"merge report + memo field JSON hack"** — how Brandon and I re
|
|
|
20
20
|
- Injected controls must have **NO `name` attribute** — named controls get submitted with the form → "problem storing the data". See [named controls submit](named-controls-submit.md).
|
|
21
21
|
- Mount modals on `document.body` to escape the form's submit scope.
|
|
22
22
|
- Borrow native relate icons (`/static/.../relate-icons/pencil.svg`, `trash.svg`) and call `window.fixAllSVG()` after render to recolor them like native lists.
|
|
23
|
-
-
|
|
23
|
+
- File structure: [separate files](../conventions/separate-files.md). For sync, use the `/b6p-push` and `/b6p-pull` skills (`npx b6p`).
|
|
24
24
|
|
|
25
25
|
**Reference implementations:** kaizenacademy/1465899 "Treatment Plan Review Comments Display" (original inspo, has Domains + lock); kaizenacademy/1466219 "Protocol Update Table" (notes-only + permission gating). Related JSON-in-memo dashboards: [crm dashboard inspo](crm-dashboard-inspo.md), visit dashboard.
|
|
@@ -44,7 +44,7 @@ test -f ~/.b6p/secrets.enc && echo OK
|
|
|
44
44
|
|
|
45
45
|
If `$ARGUMENTS` contains a component path (e.g. `U######/Combined Scheduler`), use it. If empty, ask the user which component to audit.
|
|
46
46
|
|
|
47
|
-
Confirm
|
|
47
|
+
Confirm the component was pulled with `b6p` (so its sync metadata is recorded) — without that, audit cannot determine the destination URL. If it was never pulled here, pull it first.
|
|
48
48
|
|
|
49
49
|
### 2. Run the audit
|
|
50
50
|
|
|
@@ -16,7 +16,7 @@ b6p pull [options] <formula-url>
|
|
|
16
16
|
|
|
17
17
|
The user copies the DAV URL from the component's page in the BlueStep platform UI. You cannot discover or infer it. There is no fallback that takes a name.
|
|
18
18
|
|
|
19
|
-
A first pull creates the `U######/<ComponentName>/` folder (creating the U-folder if it does not exist)
|
|
19
|
+
A first pull creates the `U######/<ComponentName>/` folder (creating the U-folder if it does not exist), populates `declarations/` and `draft/`, and records the component's sync metadata.
|
|
20
20
|
|
|
21
21
|
## How to invoke `b6p`
|
|
22
22
|
|
|
@@ -49,7 +49,7 @@ test -f ~/.b6p/secrets.enc && echo OK
|
|
|
49
49
|
- If `$ARGUMENTS` looks like a URL (starts with `http://` or `https://`), use it.
|
|
50
50
|
- If `$ARGUMENTS` is empty or looks like a display name (no scheme), STOP and ask the user:
|
|
51
51
|
> I need the **DAV URL** of the component, not its name. Copy it from the component's page in the BlueStep platform UI and paste it here.
|
|
52
|
-
- Do NOT guess the URL. Do NOT try to derive it from
|
|
52
|
+
- Do NOT guess the URL. Do NOT try to derive it from another component's recorded metadata.
|
|
53
53
|
|
|
54
54
|
### 2. Run the pull
|
|
55
55
|
|
|
@@ -66,7 +66,6 @@ Capture the output — it prints the local path where the component landed.
|
|
|
66
66
|
Parse the CLI output, or scan for the most recently modified `U######/<Name>/` directory under the project root. Confirm:
|
|
67
67
|
|
|
68
68
|
- `declarations/` is populated
|
|
69
|
-
- `.b6p_metadata.json` exists at the component root
|
|
70
69
|
- `draft/info/metadata.json` and `draft/info/config.json` exist
|
|
71
70
|
- `draft/scripts/app.ts` (or whatever `config.json:main` points at) exists
|
|
72
71
|
|
|
@@ -8,13 +8,13 @@ allowed-tools: Bash(npx b6p *) Bash(git*) Bash(test -f *)
|
|
|
8
8
|
|
|
9
9
|
## How `b6p push` actually works
|
|
10
10
|
|
|
11
|
-
`b6p push` is most reliably driven by `--file <path>`, which tells the CLI to derive the destination DAV URL from the
|
|
11
|
+
`b6p push` is most reliably driven by `--file <path>`, which tells the CLI to derive the destination DAV URL from the sync metadata it recorded for that component when it was pulled:
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
b6p push --file <path-inside-component>
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Any file inside the component works as the `--file` argument; the CLI walks up to find
|
|
17
|
+
Any file inside the component works as the `--file` argument; the CLI walks up to find the component root and looks up its recorded sync metadata.
|
|
18
18
|
|
|
19
19
|
## How to invoke `b6p`
|
|
20
20
|
|
|
@@ -44,7 +44,7 @@ If `$ARGUMENTS` contains a component path (relative to the project root), use it
|
|
|
44
44
|
|
|
45
45
|
- Run `git status` to surface what changed and flag anything unexpected.
|
|
46
46
|
- Briefly summarise the diff scope: "X files changed in `U######/<Component>/draft/`".
|
|
47
|
-
- Confirm
|
|
47
|
+
- Confirm the component was pulled with `b6p` (so its sync metadata is recorded) — `--file` resolves the destination URL from that metadata. If the component was never pulled here, pull it first.
|
|
48
48
|
|
|
49
49
|
### 3. Confirm with the user
|
|
50
50
|
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "BlueStep pull/push/snapshot workflow — always use the CLI scripts (never fetch manually) and always snapshot after every change via push → pull → snapshot"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Always use the BlueStep CLI scripts. Never use WebFetch, curl, or the Write tool to interact with BlueStep files manually.
|
|
6
|
-
|
|
7
|
-
- Pull: `node ~/.bluestep/pull.js <url>`
|
|
8
|
-
- Push: `node ~/.bluestep/push.js [folder]`
|
|
9
|
-
- Snapshot: `node ~/.bluestep/push.js --snapshot --comment "message" [folder]`
|
|
10
|
-
|
|
11
|
-
**Why:** A full system handles auth, WebDAV, folder naming by display name, `.b6p_url.json` tracking, and GraphQL snapshot-history recording. Bypassing it breaks the whole workflow.
|
|
12
|
-
|
|
13
|
-
**How to apply:** Any time the user says "pull", "push", or "snapshot" in a BlueStep context, use the CLI scripts. Credentials are in `~/.bluestep/config.json` — never prompt for them. Always snapshot after every code change — do not wait to be asked. Always include a `--comment` with a 1–3 sentence summary of what changed and why.
|
|
14
|
-
|
|
15
|
-
## Snapshot workflow — always push → pull → snapshot
|
|
16
|
-
|
|
17
|
-
Never run `--snapshot` directly after editing. The correct sequence is:
|
|
18
|
-
|
|
19
|
-
1. `node ~/.bluestep/push.js [folder]` — push source files to draft (BlueStep compiles TypeScript server-side).
|
|
20
|
-
2. `node ~/.bluestep/pull.js <url>` — pull to get the freshly compiled `.build/` files from the server.
|
|
21
|
-
3. `node ~/.bluestep/push.js --snapshot --comment "summary of changes" [folder]` — now the snapshot has the correct compiled JS and records history.
|
|
22
|
-
|
|
23
|
-
**Why:** `push.js` skips `.build/` directories (compiled artifacts), and BlueStep compiles TypeScript on the server. Snapshotting without pulling first captures stale local `.build/` files and reverts the compiled output to an older version. The pull step fetches the server-compiled JS before snapshotting. The `--comment` flag records a GraphQL history entry (author, timestamp, message) matching what the VS Code extension does.
|
|
24
|
-
|
|
25
|
-
Related: [snapshot integrity](snapshot-integrity.md) (including locally-compiled `.build/*` in the snapshot `saveState`), [push inner draft](push-inner-draft.md), [tsc rootdir](tsc-rootdir.md).
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Always pass the inner draft/ folder (not the component root) to push.js, otherwise files land in a draft/draft/* dead zone on BlueStep"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
When pushing a BlueStep component, always pass the **inner `draft/` folder** as the local-folder argument to `push.js`, never the component root.
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# CORRECT — relative paths come out as "scripts/app.ts", "static/script.ts"
|
|
9
|
-
node ~/.bluestep/push.js [--snapshot --comment "..."] \
|
|
10
|
-
"C:\...\Bluestep Pull Requests\<org>\<...path>\<Component Name>\draft" \
|
|
11
|
-
"https://<org>.bluestep.net/files/<id>/draft/"
|
|
12
|
-
|
|
13
|
-
# WRONG — relative paths come out as "draft/scripts/app.ts" and land in draft/draft/*
|
|
14
|
-
node ~/.bluestep/push.js "...\<Component Name>" "..."
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
**Why:** `push.js` (`~/.bluestep/push.js`, lines 388–396) walks the supplied local folder and computes each file's path relative to it, then appends that relative path to the target URL. If the local folder is the component root (which contains `draft/` as a subfolder), every file's relative path starts with `draft/`, and concatenated with a target URL that already ends in `/draft/` you get `.../draft/draft/scripts/app.ts` — a parallel ghost tree BlueStep does not load from. The live files BlueStep serves live at the URL root (`.../draft/scripts/...`), not under a nested `draft/`.
|
|
18
|
-
|
|
19
|
-
**How to apply:** Every time you invoke `push.js` for a BlueStep component, the `localFolder` argument's last path segment must be `draft` (or `snapshot`). If you accidentally push at the wrong level, the symptom is silent staleness — pushes "succeed" but the live JS never updates, and browser caches and source maps mislead you into thinking the bug is in code that is actually fine. Diagnose by inspecting the BlueStep file tree for a duplicate `draft/` subfolder or unexpected files at the root.
|
|
20
|
-
|
|
21
|
-
**Related — the deriver fails when components are nested deeper than `<org>/<scriptName>`.** `push.js`'s URL deriver expects exactly three path segments before `draft/` (org / scriptName / type). The Report System uses `summitridge/Report System/<Component>/draft` — four segments — so auto-derive fails. Fix: read each component's `.b6p_metadata.json` and pass the `url` explicitly as the second argument. All three Report System components (Maestro, Viewer, Builder) need this on every push.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "BlueStep snapshots register cleanly only when push.js sends locally-compiled .build/* alongside source — otherwise the user has to re-snapshot manually"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
For BlueStep snapshots to register cleanly in the web UI without a manual re-snapshot, include the locally-compiled `.build/*.js` (and `.build/scripts/*.js`) files alongside the source `.ts`/`.html`/`.css` in the `saveState` that `push.js`'s `recordHistory` mutation records.
|
|
6
|
-
|
|
7
|
-
**Why:** `push.js`'s `buildSaveState(localFolder, files)` reads files from `walkDir`, which respects `SKIP_DIRS`. If `.build` is in `SKIP_DIRS`, the `saveState` is source-only. BlueStep's snapshot UI compares the recorded `saveState` against the live filesystem (which has `.build/*.js` from server-side compilation), sees a mismatch, and flags the snapshot as incomplete — surfaced to the user as the familiar "go re-snapshot manually" pattern. When `.build/` IS included, source ↔ compiled match, the snapshot finalizes cleanly, and there is no need to touch the BlueStep UI to finish the operation.
|
|
8
|
-
|
|
9
|
-
**How to apply:**
|
|
10
|
-
|
|
11
|
-
- `~/.bluestep/push.js`'s `SKIP_DIRS` MUST be `new Set(['declarations', 'info'])` — NOT `new Set(['.build', 'declarations', 'info'])`. (`declarations/` and `info/` are genuinely server-generated and should stay excluded; `.build/` is locally compiled and should be included.) Changed 2026-05-01.
|
|
12
|
-
- ALWAYS run `tsc` locally in each folder containing a `tsconfig.json` BEFORE invoking `push.js --snapshot`. Multi-tsconfig projects (e.g. root + `static/`) need a separate `tsc` per directory. Skipping the compile uploads a stale `.build/` that doesn't reflect current source, and the runtime silently diverges from what the snapshot's `.ts` says.
|
|
13
|
-
- A second, independent reason to compile locally: BlueStep's server-side TS recompile after a `.ts` push has been observed to be unreliable. Pushing the locally-compiled `.build/*.js` directly bypasses any server-side compile lag or failure (the `export {};` `SyntaxError` saga from 2026-05-01 was caused by exactly this).
|
|
14
|
-
- Verified empirically across many edits to `alpineacademy/1513841` and `1513859` (chatbot project) on 2026-05-01: with `.build/` included, every snapshot finalized cleanly in the BlueStep UI.
|
|
15
|
-
|
|
16
|
-
**The pattern in shorthand:**
|
|
17
|
-
|
|
18
|
-
1. Edit source.
|
|
19
|
-
2. `cd <folder-with-tsconfig> && tsc` (repeat for each tsconfig in the project).
|
|
20
|
-
3. `node ~/.bluestep/push.js --snapshot --comment "..." <folder>`.
|
|
21
|
-
4. Done. No BlueStep UI interaction needed.
|
|
22
|
-
|
|
23
|
-
Related: [always snapshot](always-snapshot.md), [tsc rootdir](tsc-rootdir.md), [push inner draft](push-inner-draft.md).
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: "Compile BlueStep endpoints with --rootDir . so output mirrors scripts/app.ts → .build/scripts/app.js; --rootDir ./scripts emits to .build/app.js which the runtime ignores"
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
When compiling a BlueStep endpoint locally, use:
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
tsc --rootDir . --ignoreDeprecations 6.0 --skipLibCheck
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
NOT `tsc --rootDir ./scripts ...`.
|
|
12
|
-
|
|
13
|
-
**Why:** The BlueStep runtime loads `.build/scripts/app.js` (mirroring `scripts/app.ts`). With `--rootDir ./scripts`, tsc emits to `.build/app.js` (one level too high). The push succeeds and the snapshot succeeds, but the runtime keeps serving the old `.build/scripts/app.js`. Symptom: code edits appear to have no effect after pushing and snapshotting — silent staleness, no error, just wrong output.
|
|
14
|
-
|
|
15
|
-
**How to apply:** Always run tsc from the `draft/` folder with `--rootDir .` (or omit `rootDir` entirely — tsc infers it from `tsconfig`). After compile, verify `.build/scripts/app.js` was updated, not `.build/app.js`. If a stale `.build/app.js` orphan exists from a past mistake, it can be left in place — the runtime ignores it.
|
|
16
|
-
|
|
17
|
-
Confirmed on alpineacademy `/b/greatHair`, May 2026.
|