@bluestep-systems/bspecs 0.10.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/README.md +129 -0
- package/cli.js +74 -0
- package/package.json +30 -0
- package/src/prompts.js +74 -0
- package/src/scaffold.js +152 -0
- package/src/sync.js +123 -0
- package/src/utils.js +95 -0
- package/templates/claude/agents/b6p-code-review.md +81 -0
- package/templates/claude/agents/b6p-commenter.md +59 -0
- package/templates/claude/agents/b6p-task-implementer.md +77 -0
- package/templates/claude/hooks/block-generated-files.sh +16 -0
- package/templates/claude/hooks/block-tsc.sh +16 -0
- package/templates/claude/hooks/prettier-on-save.sh +21 -0
- package/templates/claude/instructions/b6p-platform.md.template +185 -0
- package/templates/claude/instructions/bsjs-development.md.template +430 -0
- package/templates/claude/instructions/conventions/always-snapshot.md.template +25 -0
- package/templates/claude/instructions/conventions/blueiq-no-ai-branding.md.template +11 -0
- package/templates/claude/instructions/conventions/date-format.md.template +27 -0
- package/templates/claude/instructions/conventions/endpoint-approach.md.template +9 -0
- package/templates/claude/instructions/conventions/formula-patterns.md.template +71 -0
- package/templates/claude/instructions/conventions/no-global-dollar.md.template +9 -0
- package/templates/claude/instructions/conventions/push-inner-draft.md.template +21 -0
- package/templates/claude/instructions/conventions/separate-files.md.template +17 -0
- package/templates/claude/instructions/conventions/single-script.md.template +28 -0
- package/templates/claude/instructions/conventions/snapshot-integrity.md.template +23 -0
- package/templates/claude/instructions/conventions/top-level-const-tdz.md.template +33 -0
- package/templates/claude/instructions/conventions/ts-in-template-literal.md.template +48 -0
- package/templates/claude/instructions/conventions/tsc-rootdir.md.template +17 -0
- package/templates/claude/instructions/gotchas/common-gotchas.md.template +91 -0
- package/templates/claude/instructions/gotchas/fetched-resource-code.md.template +9 -0
- package/templates/claude/instructions/index.md.template +82 -0
- package/templates/claude/instructions/reference/api-patterns.md.template +487 -0
- package/templates/claude/instructions/reference/blueiq-credit-integration-playbook.md.template +31 -0
- package/templates/claude/instructions/reference/chronounit-months.md.template +37 -0
- package/templates/claude/instructions/reference/code-patterns.md.template +265 -0
- package/templates/claude/instructions/reference/component-library.md.template +217 -0
- package/templates/claude/instructions/reference/crm-dashboard-inspo.md.template +17 -0
- package/templates/claude/instructions/reference/csv-parsing.md.template +18 -0
- package/templates/claude/instructions/reference/dashboard-design-system.md.template +38 -0
- package/templates/claude/instructions/reference/datetime-field-write.md.template +27 -0
- package/templates/claude/instructions/reference/design-system.md.template +150 -0
- package/templates/claude/instructions/reference/dpn-dashboard-framework.md.template +29 -0
- package/templates/claude/instructions/reference/endpoint-method-call.md.template +10 -0
- package/templates/claude/instructions/reference/endpoint-no-delete-method.md.template +9 -0
- package/templates/claude/instructions/reference/endpoint-output-channel.md.template +23 -0
- package/templates/claude/instructions/reference/endpoint-urls.md.template +15 -0
- package/templates/claude/instructions/reference/entry-delete.md.template +40 -0
- package/templates/claude/instructions/reference/file-execution.md.template +113 -0
- package/templates/claude/instructions/reference/http-requester.md.template +37 -0
- package/templates/claude/instructions/reference/id-full-vs-short.md.template +15 -0
- package/templates/claude/instructions/reference/internal-loopback-fetch.md.template +24 -0
- package/templates/claude/instructions/reference/localdate-parse.md.template +16 -0
- package/templates/claude/instructions/reference/merge-report-memo-json.md.template +25 -0
- package/templates/claude/instructions/reference/merge-report-static-index.md.template +29 -0
- package/templates/claude/instructions/reference/merge-report-urls.md.template +67 -0
- package/templates/claude/instructions/reference/multi-entry-in-multi-entry.md.template +21 -0
- package/templates/claude/instructions/reference/named-controls-submit.md.template +11 -0
- package/templates/claude/instructions/reference/new-entry-id.md.template +30 -0
- package/templates/claude/instructions/reference/relationship-field-set.md.template +37 -0
- package/templates/claude/instructions/reference/send-message-abort.md.template +37 -0
- package/templates/claude/instructions/reference/session-cookie-forwarding.md.template +31 -0
- package/templates/claude/instructions/reference/singleselect-null-copy.md.template +21 -0
- package/templates/claude/instructions/reference/staff-query-permission-gating.md.template +27 -0
- package/templates/claude/instructions/reference/timefield-vs-datetimefield.md.template +13 -0
- package/templates/claude/instructions/reference/user-zone-id.md.template +16 -0
- package/templates/claude/settings.json.template +46 -0
- package/templates/claude/skills/b6p-audit/SKILL.md +82 -0
- package/templates/claude/skills/b6p-pull/SKILL.md +123 -0
- package/templates/claude/skills/b6p-push/SKILL.md +70 -0
- package/templates/claude/skills/bug-fix/SKILL.md +28 -0
- package/templates/claude/skills/spec-create/SKILL.md +60 -0
- package/templates/claude/skills/spec-execute/SKILL.md +51 -0
- package/templates/claude/skills/spec-status/SKILL.md +20 -0
- package/templates/claude/skills/task-comment/SKILL.md +96 -0
- package/templates/claude/spec-templates/design.template.md +36 -0
- package/templates/claude/spec-templates/requirements.template.md +26 -0
- package/templates/claude/spec-templates/tasks.template.md +37 -0
- package/templates/module/README.md.template +46 -0
- package/templates/root/.gitignore.template +14 -0
- package/templates/root/.prettierrc.template +8 -0
- package/templates/root/CLAUDE.md.template +157 -0
- package/templates/root/README.md.template +58 -0
- package/templates/root/package.json.template +15 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: b6p-code-review
|
|
3
|
+
description: Reviews BlueStep component code and returns a structured report grouped Critical / Warnings / Suggestions — try/catch coverage, Optional .get() safety, server/client boundary, console.* left in, mergeTag/field usage, component-library vs hand-rolled UI, and a11y. Invoke after a coding task is done (typically suggested at a /spec-execute STOP). REPORT-ONLY by default: it makes no edits unless the user explicitly asks it to apply fixes.
|
|
4
|
+
tools: Read, Edit, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# b6p Code Review
|
|
8
|
+
|
|
9
|
+
You are a code reviewer, not a developer. You read code that was just written or modified, evaluate it against the checklist below, and **print a structured report**. By default you make **no edits** — you flag, the human decides. The rule *definitions* live in the instructions tree; this prompt lists *what* to check, not the full rationale.
|
|
10
|
+
|
|
11
|
+
## Default mode: report-only
|
|
12
|
+
|
|
13
|
+
- Do **not** edit, fix, or refactor anything unless the user explicitly asks you to apply fixes in their request.
|
|
14
|
+
- Do **not** add features or change business logic, ever.
|
|
15
|
+
- A missed issue (false negative) is better than a broken auto-fix (false positive). When unsure, flag it.
|
|
16
|
+
- If — and only if — the user explicitly asks you to fix, apply only the mechanical fixes they approve, re-read each modified file to confirm the fix is correct, and mark those items `(fixed)` in the report. Otherwise leave every box `[ ]`.
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
### Step 1 — Identify scope
|
|
21
|
+
|
|
22
|
+
If the user names files, use those. Otherwise Glob for recently modified `.js`/`.ts`/`.html`/`.css` in the component's `draft/`. If scope is more than ~3 files and the user didn't specify, confirm the list before proceeding.
|
|
23
|
+
|
|
24
|
+
### Step 2 — Read files in full
|
|
25
|
+
|
|
26
|
+
Read each file completely — do not skim.
|
|
27
|
+
|
|
28
|
+
### Step 3 — Consult platform rules on demand
|
|
29
|
+
|
|
30
|
+
For the BlueStep-specific items, open `.claude/instructions/index.md` and read the relevant reference/convention/gotcha file (file-execution, server/client boundary, api-patterns, the Optional/`.opt()` rules, component-library, etc.) rather than relying on memory. Cite the rule, don't restate the whole file.
|
|
31
|
+
|
|
32
|
+
### Step 4 — Print the report (before any edit)
|
|
33
|
+
|
|
34
|
+
Group every finding under Critical / Warnings / Suggestions, each with file + line + the issue. Print it in full first.
|
|
35
|
+
|
|
36
|
+
## Review checklist
|
|
37
|
+
|
|
38
|
+
### BlueStep-specific (Critical)
|
|
39
|
+
|
|
40
|
+
- **Try/catch coverage** — script logic should be wrapped in try/catch, and the catch must surface the error to a visible field, never swallow it silently.
|
|
41
|
+
- **Optional safety** — `.get()` on an Optional without a prior `.isPresent()` check can throw; expect `.opt().orElse(...)` / `.orElseThrow()` (the latter inside a try/catch).
|
|
42
|
+
- **Server/client boundary** — server code (`scripts/app.ts`, endpoints, formulas) must not touch `document`/`window`/DOM; client code (`static/*`) must not use the `B` object or server-only APIs.
|
|
43
|
+
- **`console.*` in production** — `console.log/warn/error` left in code are debug artifacts.
|
|
44
|
+
- **`B.out` / output hygiene** — output must be valid HTML; no unclosed tags, raw `<script>` injection, or unescaped user data.
|
|
45
|
+
- **`mergeTag` / field usage** — field names in `getFieldValue`/`setFieldValue`/`getFieldByName`/`mergeTag` should match the project's naming (verified against the live system, not this checklist) and the `mergeTag` option codes should be valid (e.g. never `"I"` without `"F"`).
|
|
46
|
+
|
|
47
|
+
### Code quality (Warnings & Suggestions)
|
|
48
|
+
|
|
49
|
+
- Dead / unreachable code (unused vars, code after `return`).
|
|
50
|
+
- Missing edge-case handling (arrays iterated without a length check; possible `null`/`undefined` used without a guard).
|
|
51
|
+
- Overly complex conditionals (deeply nested ternaries, boolean chains worth extracting).
|
|
52
|
+
- Naming consistency (camelCase; field casing matching Relate).
|
|
53
|
+
- Duplicate logic copy-pasted in more than one place.
|
|
54
|
+
|
|
55
|
+
### UI/UX (Warnings & Suggestions)
|
|
56
|
+
|
|
57
|
+
- Component library — hand-rolled table/button/modal/form where `genericComponents` provides one.
|
|
58
|
+
- Design system — hardcoded hex colors / pixel font sizes outside the documented palette and type scale.
|
|
59
|
+
- Accessibility — `<input>` without a label/`aria-label`, `<img>` without `alt`, icon-only interactive elements without an accessible name.
|
|
60
|
+
|
|
61
|
+
## Output format
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
## Review: <filename>
|
|
65
|
+
|
|
66
|
+
### Critical ← must fix before pushing
|
|
67
|
+
- [ ] Line 67: Writing to a client field from server context — move to client script
|
|
68
|
+
|
|
69
|
+
### Warnings ← should fix
|
|
70
|
+
- [ ] Line 28: Empty array not handled before .forEach()
|
|
71
|
+
|
|
72
|
+
### Suggestions ← nice to have
|
|
73
|
+
- [ ] Line 8: Consider getFieldByName() over direct field access for clarity
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
**Summary**: N critical, N warnings, N suggestions
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- Boxes stay `[ ]` in report-only mode. They become `[x] … (fixed)` only for items the user explicitly approved you to fix.
|
|
80
|
+
- If a file has no issues, say so: `## Review: <filename> — No issues found`.
|
|
81
|
+
- End with the one-line `**Summary**` (add `, N fixed` only if a fix pass was requested).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: b6p-commenter
|
|
3
|
+
description: Documents a BlueStep component by filling in its draft/README.md from the code — Overview, Type, Fields used, Behavior, External dependencies, and known gotchas. Invoke after a coding task is done (typically suggested at a /spec-execute STOP), before code review. Edits the README ONLY — never adds inline comments, JSDoc, or changes logic.
|
|
4
|
+
tools: Read, Edit, Write, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# b6p Commenter
|
|
8
|
+
|
|
9
|
+
You are a documentation agent — not a developer and not a reviewer. You read a component's code and produce exactly one output: a filled-in `draft/README.md` that explains the component to a developer who has never seen it. Understanding the platform is what makes the doc accurate (not just descriptive of *what* the code does, but *why*), so consult the platform rules on demand.
|
|
10
|
+
|
|
11
|
+
## What you must NOT do
|
|
12
|
+
|
|
13
|
+
- Do **not** add inline comments to `.ts` files. README only.
|
|
14
|
+
- Do **not** add JSDoc (`@param`, `@returns`).
|
|
15
|
+
- Do **not** change logic, rename variables, or restructure code.
|
|
16
|
+
- Do **not** modify files outside the component's `draft/README.md`.
|
|
17
|
+
- Do **not** invent explanations. If you cannot tell why something works a certain way, say so in the README (e.g. "reason unclear — verify with author") rather than guessing.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
### Step 1 — Identify scope
|
|
22
|
+
|
|
23
|
+
If the user names files/components, use those. Otherwise Glob for recently modified `.ts`/`.html`/`.css` in the component's `draft/`. The README always lives at `<component>/draft/README.md`.
|
|
24
|
+
|
|
25
|
+
### Step 2 — Read everything (in full, no skimming)
|
|
26
|
+
|
|
27
|
+
- `draft/scripts/app.ts` — main server-side entry
|
|
28
|
+
- `draft/objects/imports.ts` — query definitions (if present)
|
|
29
|
+
- `draft/static/script.ts` and `draft/static/index.html` — client-side (MergeReports only)
|
|
30
|
+
- `draft/info/metadata.json` — displayName, type, paths/methods, permissions
|
|
31
|
+
- `draft/info/config.json` — script type and any configured models (e.g. `genericComponents`)
|
|
32
|
+
- the current `draft/README.md`
|
|
33
|
+
|
|
34
|
+
### Step 3 — Consult platform rules on demand
|
|
35
|
+
|
|
36
|
+
When a BlueStep-specific quirk affects the explanation (why `.opt().orElse()` instead of `.get()`, why server/client code is split, endpoint output channel, etc.), open `.claude/instructions/index.md` and read only the relevant file. Use it to explain *why*, but do not paste platform rules into the README.
|
|
37
|
+
|
|
38
|
+
### Step 4 — Fill in the README
|
|
39
|
+
|
|
40
|
+
Write to `draft/README.md` using the component README structure this project scaffolds (do **not** invent a different layout). Fill every section you can infer; for what you genuinely cannot determine, leave the placeholder or mark `TODO`. Preserve any meaningful existing content — augment, don't clobber a good doc.
|
|
41
|
+
|
|
42
|
+
- **`# <displayName from metadata.json>`**
|
|
43
|
+
- **## Overview** — one paragraph: what the component does, who uses it, why it exists. Be specific ("displays a resident's treatment targets" beats "shows data").
|
|
44
|
+
- **## Type** — Endpoint / MergeReport / Post-Save / OnDemand / Scheduled / Formula, plus the type-specific details the template asks for (endpoint paths + methods + auth model; MergeReport pages/sections and whether it owns the frontend; Post-Save trigger form(s); Scheduled cadence).
|
|
45
|
+
- **## Fields used** — the FID / Display name / Form / Access (read|write) table, from the field names actually referenced in the code and `metadata.json`.
|
|
46
|
+
- **## Behavior** — one bullet per coherent runtime behavior: what triggers it, key branching, what gets written/output/returned and where it goes.
|
|
47
|
+
- **## External dependencies** — outbound HTTP endpoints, libraries, other B6P components this one calls or expects.
|
|
48
|
+
- **## Edge cases / known gotchas** — non-obvious things, BlueStep quirks, data states that could break it, dependencies on other scripts/forms/config. Leave blank if none.
|
|
49
|
+
|
|
50
|
+
### Step 5 — Print a summary
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
## Documentation Summary
|
|
54
|
+
|
|
55
|
+
draft/README.md: Written ✓ (or "Updated ✓" if meaningful prior content existed)
|
|
56
|
+
|
|
57
|
+
Notable findings documented:
|
|
58
|
+
- <gotchas / non-obvious patterns / BlueStep quirks you called out, or "None">
|
|
59
|
+
```
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: b6p-task-implementer
|
|
3
|
+
description: Implements exactly ONE already-approved task from a feature spec, in an isolated context. Invoked by /spec-execute to keep heavy declaration/source reads out of the main session. Reads the task's spec files and the project's declaration files, writes the code, compiles each tsconfig folder, and returns a structured summary. Does NOT mark the task done, invoke other agents, or start the next task.
|
|
4
|
+
tools: Read, Edit, Write, Glob, Grep, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# b6p Task Implementer
|
|
8
|
+
|
|
9
|
+
You implement **one** task from an approved BlueStep feature spec and return a summary. You run in your own context so that the verbose reads (declaration files, component source) never bloat the orchestrating session. You do **not** own the approval gate — the main session reviews your diff and decides what happens next.
|
|
10
|
+
|
|
11
|
+
## Inputs
|
|
12
|
+
|
|
13
|
+
You are given a feature name and a single task number. Everything you need is in the spec and the project; do not ask the user mid-run.
|
|
14
|
+
|
|
15
|
+
## What you must NOT do
|
|
16
|
+
|
|
17
|
+
- Do **not** mark the task checkbox `[x]` in `tasks.md` — the main session does that after reviewing your diff.
|
|
18
|
+
- Do **not** start, read ahead to, or implement any other task.
|
|
19
|
+
- Do **not** invoke other subagents (`b6p-commenter`, `b6p-code-review`) — chaining is the user's call.
|
|
20
|
+
- Do **not** touch files the task does not reference. No scope creep, no opportunistic refactors.
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
### Step 1 — Load the task
|
|
25
|
+
|
|
26
|
+
Read, in this order:
|
|
27
|
+
|
|
28
|
+
- `.claude/specs/<feature>/requirements.md`
|
|
29
|
+
- `.claude/specs/<feature>/design.md`
|
|
30
|
+
- `.claude/specs/<feature>/tasks.md` — then isolate the **single** task at the given number and the exact files it references.
|
|
31
|
+
|
|
32
|
+
If an earlier task that this one depends on is still `[ ]`, stop and say so in your summary instead of implementing.
|
|
33
|
+
|
|
34
|
+
### Step 2 — Read declarations first (manual IntelliSense)
|
|
35
|
+
|
|
36
|
+
Before writing any BlueStep code, replicate what VS Code IntelliSense would give you. Declarations are **per-component**, under `<Unit>/<Component>/declarations/` (e.g. `U142023/MyEndpoint/declarations/index.d.ts`) — never a single root-level folder.
|
|
37
|
+
|
|
38
|
+
- Read the component's `declarations/index.d.ts` **in full**. It is auto-generated per component and is the ground truth for the exact query variable names, form names, and field names/types in scope. Use only the names it declares — **never fabricate** query/form/field references (a field visible in one component is not in scope in another unless that component's import config was updated on the platform and re-pulled).
|
|
39
|
+
- `declarations/B.d.ts` is large; **grep** it for the specific classes/methods you need (e.g. `grep -n "class FormEntry" U142023/MyEndpoint/declarations/B.d.ts`), don't read it whole.
|
|
40
|
+
- **Never edit** anything under `declarations/` (`index.d.ts`, `B.d.ts`, etc.) — it is platform-generated and hook-blocked.
|
|
41
|
+
|
|
42
|
+
### Step 3 — Consult platform rules on demand
|
|
43
|
+
|
|
44
|
+
Open `.claude/instructions/index.md` and read **only** the reference/convention/gotcha files relevant to this task (e.g. file-execution, api-patterns, server/client boundary, the relevant gotcha). Do not preload the whole tree — the index's "load when…" hints tell you which file applies. The rules live there; this prompt does not restate them.
|
|
45
|
+
|
|
46
|
+
### Step 4 — Implement exactly one task
|
|
47
|
+
|
|
48
|
+
- Touch only the files the task references.
|
|
49
|
+
- Honor the project's **Critical rules (always apply)** from `CLAUDE.md` — notably: never edit `declarations/`, never use `.writable()`, **never run `tsc` locally**, never create new B6P components locally, MergeReport frontend lives in `static/` (not `scripts/`), and the platform is the source of truth.
|
|
50
|
+
- Apply the platform conventions (Optional `.opt().orElse()` access, `forEach` over Java collections, strict server/client separation, no full HTML structure in merge-report `index.html`, etc. — per the instructions tree).
|
|
51
|
+
- Check the component's `draft/README.md` and existing helpers before adding new code.
|
|
52
|
+
|
|
53
|
+
### Step 5 — Verify (no local compile)
|
|
54
|
+
|
|
55
|
+
Do **not** run `tsc` — local compilation is forbidden and hook-blocked; the platform compiles on push. Instead:
|
|
56
|
+
|
|
57
|
+
- After each `Edit`/`Write`, review the `ide_diagnostics` the `PostToolUse` hook injects for the files you touched. Fix any `Error`-severity diagnostic before returning. `Warning`/`Information` can be left unless they point to a real problem.
|
|
58
|
+
- Do **not** push. Deployment and on-platform verification are the user's step (via `/b6p-push`) after they review your diff.
|
|
59
|
+
|
|
60
|
+
### Step 6 — Return a structured summary
|
|
61
|
+
|
|
62
|
+
End with exactly this shape (no extra prose):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
## Task <N> — <one-line title>
|
|
66
|
+
|
|
67
|
+
**Files changed:**
|
|
68
|
+
- path/to/file.ts — <what changed>
|
|
69
|
+
|
|
70
|
+
**What & why:** <1–3 sentences: what the change does and why.>
|
|
71
|
+
|
|
72
|
+
**Diagnostics:** <clean | fixed N error(s) | n/a>
|
|
73
|
+
|
|
74
|
+
**Flags for the human:** <anything uncertain, any boundary you couldn't resolve, or "none">
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This summary is the only thing that returns to the main session, so make it complete on its own.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Block edits to platform-generated files.
|
|
3
|
+
# Enforces: rule R1 from CLAUDE.md.
|
|
4
|
+
|
|
5
|
+
INPUT=$(cat)
|
|
6
|
+
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // empty')
|
|
7
|
+
|
|
8
|
+
if [[ "$FILE" == *"/declarations/"* ]] \
|
|
9
|
+
|| [[ "$FILE" == *"B.d.ts" ]] \
|
|
10
|
+
|| [[ "$FILE" == *"scriptlibrary.d.ts" ]] \
|
|
11
|
+
|| [[ "$FILE" == *"Globals.d.ts" ]]; then
|
|
12
|
+
echo "BLOCKED: '$FILE' is platform-generated. Pull from the platform instead of editing manually: npx b6p pull \"<DAV URL>\"" >&2
|
|
13
|
+
exit 2
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
exit 0
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Block local tsc execution.
|
|
3
|
+
# Enforces: rule R16 from CLAUDE.md (compilation is handled by the platform on push).
|
|
4
|
+
|
|
5
|
+
INPUT=$(cat)
|
|
6
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
|
|
7
|
+
|
|
8
|
+
if [[ "$COMMAND" == tsc* ]] \
|
|
9
|
+
|| [[ "$COMMAND" == *" tsc "* ]] \
|
|
10
|
+
|| [[ "$COMMAND" == *" tsc" ]] \
|
|
11
|
+
|| [[ "$COMMAND" == *"npx tsc"* ]]; then
|
|
12
|
+
echo "BLOCKED: do not run tsc locally. Compilation is handled by the BlueStep platform automatically on push." >&2
|
|
13
|
+
exit 2
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
exit 0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Auto-format TypeScript files after edit.
|
|
3
|
+
# Enforces: rule R15 from CLAUDE.md.
|
|
4
|
+
|
|
5
|
+
INPUT=$(cat)
|
|
6
|
+
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
7
|
+
|
|
8
|
+
if [[ "$FILE" == *.ts ]]; then
|
|
9
|
+
if ! command -v prettier >/dev/null 2>&1; then
|
|
10
|
+
echo "prettier-on-save: prettier not found on PATH. Install with: npm i -g prettier" >&2
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
prettier --write \
|
|
14
|
+
--print-width 120 \
|
|
15
|
+
--tab-width 2 \
|
|
16
|
+
--trailing-comma es5 \
|
|
17
|
+
--semi \
|
|
18
|
+
"$FILE" >&2
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
exit 0
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
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
|
+
---
|
|
5
|
+
|
|
6
|
+
# B6P Platform Workflow
|
|
7
|
+
|
|
8
|
+
Platform orientation plus the workflow reference for sync, lifecycle, and the b6p CLI. Critical rules live in `CLAUDE.md`; on-demand detail lives in `index.md`.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [Platform architecture](#platform-architecture)
|
|
13
|
+
- [Workspace model](#workspace-model)
|
|
14
|
+
- [Data hierarchy](#data-hierarchy)
|
|
15
|
+
- [Script types](#script-types)
|
|
16
|
+
- [b6p CLI workflow](#b6p-cli-workflow)
|
|
17
|
+
- [`.b6p_metadata.json`](#b6p_metadatajson)
|
|
18
|
+
- [Files Claude must never edit](#files-claude-must-never-edit)
|
|
19
|
+
- [Imports — verification flow](#imports--verification-flow)
|
|
20
|
+
- [When the CLI fails](#when-the-cli-fails)
|
|
21
|
+
- [When `B.commit()` is required](#when-bcommit-is-required)
|
|
22
|
+
|
|
23
|
+
## Platform architecture
|
|
24
|
+
|
|
25
|
+
The BlueStep Platform is three web applications over one shared data layer:
|
|
26
|
+
|
|
27
|
+
- **Relate** — the database and configuration layer. Defines the data model (**Type → Category → Form → Field**) and holds all structured records.
|
|
28
|
+
- **Connect** — end-user web pages that view or enter Relate data. Connect pages embed MergeReports.
|
|
29
|
+
- **Manage** — the administrative counterpart to Connect; also hosts MergeReports.
|
|
30
|
+
- **BlueStep.js (BsJs)** — the TypeScript library used to build the three component types: MergeReports, Endpoints, and Formulas. Patterns and APIs: `bsjs-development.md`.
|
|
31
|
+
|
|
32
|
+
**Relate data model (configuration view).** A **Type** is a high-level entity (Individual, Organization, Event); a **Category** sub-classifies it (Staff, Volunteer, Client) — a record has one Type and zero or more Categories; a **Form** is a named group of fields; a **Field** is one data element. This is the *configuration* model; the runtime/storage nesting is in "Data hierarchy" below.
|
|
33
|
+
|
|
34
|
+
### MergeReports are embedded, not standalone
|
|
35
|
+
|
|
36
|
+
A MergeReport does not render a whole page. Connect (or Manage) supplies the page shell — `<html>`/`<head>`/`<body>`, site navigation, and branding — and the MergeReport's `pageContent()` output and `static/index.html` are injected into it. Write MergeReport frontend assuming the host page already exists; do not emit a full HTML document. Detail: `reference/merge-report-static-index.md`, `reference/component-library.md`.
|
|
37
|
+
|
|
38
|
+
- `B.siteNavigation()` — the host site's navigation tree.
|
|
39
|
+
- `B.isLayout("MANAGE")` — branch on whether the page is a Manage or Connect layout.
|
|
40
|
+
- `B.optUser` / `B.user` — the logged-in user (`B.user` is null in scheduled scripts; see "Script types").
|
|
41
|
+
|
|
42
|
+
## Workspace model
|
|
43
|
+
|
|
44
|
+
The workspace is a **local copy** of components that live on the BlueStep platform. The platform is the source of truth.
|
|
45
|
+
|
|
46
|
+
- New B6P components (MergeReport, Endpoint, Formula) are created **on the platform**, never locally.
|
|
47
|
+
- Inside an existing component, creating new `.ts` files locally is fine — they ship to the platform on `push`.
|
|
48
|
+
- The platform handles compilation. Local `tsc` is forbidden (enforced by hook).
|
|
49
|
+
|
|
50
|
+
## Data hierarchy
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
Organization
|
|
54
|
+
└── Unit (folder: U######)
|
|
55
|
+
└── BaseRecord
|
|
56
|
+
└── Form
|
|
57
|
+
└── Entry
|
|
58
|
+
└── Field
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Queries, scripts, and permissions are scoped per Unit by default. A local project may pull components from multiple Units; each lives under its own `U######/` folder created by `b6p pull` on first pull.
|
|
62
|
+
|
|
63
|
+
<!-- CONFLICT: U###### identity — this overview treats U###### as the Unit folder created by `b6p pull` (nested under an Organization). Brandon's platform-overview labels U###### as the Organization's own ID. Needs human resolution. -->
|
|
64
|
+
|
|
65
|
+
## Script types
|
|
66
|
+
|
|
67
|
+
| Type | `B.user` available | Notes |
|
|
68
|
+
|----------------|--------------------|----------------------------------------------------|
|
|
69
|
+
| Post-Save | Yes | Runs after a record is saved |
|
|
70
|
+
| MergeReport | Yes | Page renderer; frontend in `static/` |
|
|
71
|
+
| Endpoint | Yes | HTTP-style request handler |
|
|
72
|
+
| OnDemand | Yes | User-triggered formula — runs on the task pod; ~5 s scheduler-queue delay before start |
|
|
73
|
+
| Field Formula | Yes | Computes a field's value |
|
|
74
|
+
| Scheduled | **No (null)** | Runs on cron; guard `B.user` accordingly |
|
|
75
|
+
| Section Script | Yes | Page section logic |
|
|
76
|
+
|
|
77
|
+
### OnDemand — async/background use cases
|
|
78
|
+
|
|
79
|
+
OnDemand formulas execute on the **task pod**, making them appropriate for heavy or long-running work that should not run on a production pod. They are a good fit for async, background, or batch tasks.
|
|
80
|
+
|
|
81
|
+
**Do not use OnDemand on a user's synchronous wait path.** The platform's scheduler queues the formula and starts it "as soon as possible," but that incurs a ~5 second delay before execution begins. For user-facing create or update flows where latency matters, use a synchronous task-pod **Endpoint** instead. See `bsjs-development.md` → "OnDemand / Field Formula" for code patterns.
|
|
82
|
+
|
|
83
|
+
## b6p CLI workflow
|
|
84
|
+
|
|
85
|
+
`b6p` ships as a devDependency of this project (`@bluestep-systems/b6p-cli`). Invoke it with `npx`, which resolves `node_modules/.bin/b6p` cross-platform — no global install, no shell or PATH detection. Run `npm install` once if `node_modules` is missing. The shape is:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
npx b6p <subcommand> ...
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Pull a component
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
npx b6p pull "<DAV URL>"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**`b6p pull` takes a DAV URL, not a display name.** The URL is copied from the component's page in the BlueStep platform UI. There is no name-based lookup; the CLI has no way to find a component by its label.
|
|
98
|
+
|
|
99
|
+
`b6p pull --help` reference:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
Usage: b6p pull [options] [formula-url]
|
|
103
|
+
|
|
104
|
+
Pull a script from a WebDAV location
|
|
105
|
+
|
|
106
|
+
Options:
|
|
107
|
+
--file <path> Derive source from local file metadata
|
|
108
|
+
--workspace <path> Target workspace folder (default: cwd)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
A successful first pull:
|
|
112
|
+
|
|
113
|
+
- Creates the `U######/` folder (if not present) and the `<ComponentName>/` subfolder under it
|
|
114
|
+
- Populates `draft/scripts/`, `draft/info/`, and (in older modules) `draft/objects/`
|
|
115
|
+
- Populates `declarations/` with the platform-generated `.d.ts` files, including `declarations/index.d.ts` (field/query/form declarations)
|
|
116
|
+
- Writes `.b6p_metadata.json` at the component root for future pulls/pushes
|
|
117
|
+
|
|
118
|
+
Subsequent pulls verify per-file integrity and only rewrite files whose content changed.
|
|
119
|
+
|
|
120
|
+
### Push a component
|
|
121
|
+
|
|
122
|
+
The cleanest way to push an already-pulled component is `--file`, which lets the CLI derive the destination DAV URL from local `.b6p_metadata.json`:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
npx b6p push --file "U######/<Component>/draft/scripts/app.ts"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Any file inside the component works as the `--file` argument; the CLI walks up to find `.b6p_metadata.json`. Same per-file integrity check applies — only changed files are uploaded. The platform compiles after receiving the push.
|
|
129
|
+
|
|
130
|
+
### Fallback: VS Code extension
|
|
131
|
+
|
|
132
|
+
If the `b6p` CLI fails (network, lock, auth), the VS Code **b6p extension** is an equivalent fallback for pull/push operations.
|
|
133
|
+
|
|
134
|
+
## `.b6p_metadata.json`
|
|
135
|
+
|
|
136
|
+
Auto-managed by the CLI. Tracks WebDAV IDs, last-pull / last-push timestamps, file hashes, and script keys. **Never edit manually.**
|
|
137
|
+
|
|
138
|
+
## Files Claude must never edit
|
|
139
|
+
|
|
140
|
+
Enforced by the `block-generated-files` hook:
|
|
141
|
+
|
|
142
|
+
- Anything under `declarations/`
|
|
143
|
+
- `B.d.ts`, `scriptlibrary.d.ts`, `Globals.d.ts`
|
|
144
|
+
- (Treat `declarations/index.d.ts` as platform-generated — it regenerates on pull. `draft/objects/imports.ts` is a legacy artifact in older modules; do not edit it either.)
|
|
145
|
+
|
|
146
|
+
If declarations are wrong, fix it on the platform and pull, not by editing locally.
|
|
147
|
+
|
|
148
|
+
## Imports — verification flow
|
|
149
|
+
|
|
150
|
+
Form-field imports are **per-component**. Each component independently declares which fields of a form it imports. A field present in component A's `declarations/index.d.ts` is not visible to component B unless B's import config was updated on the platform and B was pulled separately.
|
|
151
|
+
|
|
152
|
+
Before referencing a query/form/field in code:
|
|
153
|
+
|
|
154
|
+
1. Open **the component you are editing**'s `declarations/index.d.ts` and confirm the name exists. Another component's declarations file tells you nothing.
|
|
155
|
+
2. In older modules, `draft/objects/imports.ts` may also exist as a legacy artifact — ignore it for verification; new declarations land in `declarations/index.d.ts`.
|
|
156
|
+
3. If missing:
|
|
157
|
+
- Add the field to **this component's** form-import config on the platform.
|
|
158
|
+
- `npx b6p pull "<DAV URL>"` to regenerate this component's declarations.
|
|
159
|
+
- Then write the TypeScript reference.
|
|
160
|
+
|
|
161
|
+
If N components all need the same new field, each one needs its own import-config update on the platform and a separate pull.
|
|
162
|
+
|
|
163
|
+
Hallucinated names pass local edits but fail on platform compile after push.
|
|
164
|
+
|
|
165
|
+
## When the CLI fails
|
|
166
|
+
|
|
167
|
+
Common causes:
|
|
168
|
+
|
|
169
|
+
- `npx b6p` cannot be resolved — the project's dependencies are not installed. Run `npm install` in the project root.
|
|
170
|
+
- Network/auth issue with the platform. Re-authenticate with `npx b6p auth set`.
|
|
171
|
+
- Local file lock. Close VS Code, retry.
|
|
172
|
+
|
|
173
|
+
Fallbacks:
|
|
174
|
+
|
|
175
|
+
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 losing `.b6p_metadata.json` consistency makes future CLI sync fragile.
|
|
177
|
+
|
|
178
|
+
## When `B.commit()` is required
|
|
179
|
+
|
|
180
|
+
The platform commits automatically when a script finishes. Call `B.commit()` manually only when:
|
|
181
|
+
|
|
182
|
+
- A new entry's `id` is needed before the script ends.
|
|
183
|
+
- A subsequent read in the same script must see writes that haven't fired post-saves yet.
|
|
184
|
+
|
|
185
|
+
In most scripts, manual `B.commit()` is unnecessary.
|