@harperfast/template-vue-ts-studio 1.12.12 → 1.13.1

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.
Files changed (23) hide show
  1. package/.agents/skills/harper-best-practices/AGENTS.md +684 -239
  2. package/.agents/skills/harper-best-practices/SKILL.md +2 -1
  3. package/.agents/skills/harper-best-practices/rules/creating-a-fabric-account-and-cluster.md +7 -4
  4. package/.agents/skills/harper-best-practices/rules/creating-harper-apps.md +71 -4
  5. package/.agents/skills/harper-best-practices/rules/custom-resources.md +63 -29
  6. package/.agents/skills/harper-best-practices/rules/deploying-from-ci.md +358 -0
  7. package/.agents/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +132 -103
  8. package/.agents/skills/harper-best-practices/rules/load-env.md +37 -49
  9. package/.agents/skills/harper-best-practices/rules/programmatic-table-requests.md +71 -57
  10. package/.agents/skills/harper-best-practices/rules.manifest.yaml +184 -8
  11. package/README.md +0 -48
  12. package/agent/skills/harper-best-practices/AGENTS.md +684 -239
  13. package/agent/skills/harper-best-practices/SKILL.md +2 -1
  14. package/agent/skills/harper-best-practices/rules/creating-a-fabric-account-and-cluster.md +7 -4
  15. package/agent/skills/harper-best-practices/rules/creating-harper-apps.md +71 -4
  16. package/agent/skills/harper-best-practices/rules/custom-resources.md +63 -29
  17. package/agent/skills/harper-best-practices/rules/deploying-from-ci.md +358 -0
  18. package/agent/skills/harper-best-practices/rules/deploying-to-harper-fabric.md +132 -103
  19. package/agent/skills/harper-best-practices/rules/load-env.md +37 -49
  20. package/agent/skills/harper-best-practices/rules/programmatic-table-requests.md +71 -57
  21. package/agent/skills/harper-best-practices/rules.manifest.yaml +184 -8
  22. package/package.json +1 -1
  23. package/skills-lock.json +1 -1
@@ -14,31 +14,37 @@ metadata:
14
14
  reference/v5/resources/resource-api.md#`addTo(property: string, value:
15
15
  number)`
16
16
  - reference/v5/components/javascript-environment.md#Module Formats
17
- sourceCommit: 9e6ecf87dd25bb488ad44dc2876ca6439ccd682e
18
- inputHash: f5629f73cde74764
17
+ sourceCommit: e73e5efb2823cc52caf7a6458d67fbcff3bbff2c
18
+ inputHash: bb360b0d6c0a7bd4
19
19
  ---
20
20
 
21
21
  # Programmatic Table Requests
22
22
 
23
- Instructions for the agent to interact with Harper tables programmatically using the `tables` object, the Query API, and transactions.
23
+ Instructions for the agent to follow when interacting with Harper tables programmatically using the `tables` object.
24
24
 
25
25
  ## When to Use
26
26
 
27
- Apply this rule when writing server-side Harper component code that reads from or writes to tables directly — for example, in HTTP handlers, background jobs, timers, or SSR render functions. Use it whenever you need to construct queries with `conditions`, `sort`, `select`, `limit`, or `offset`, or when you need explicit transaction control via `transaction()`.
27
+ Apply this rule when writing server-side Harper component code that reads from or writes to tables using the programmatic API — for example, in HTTP handlers, background jobs, timers, or SSR entry points. Use it whenever you need to construct queries with `conditions`, `sort`, `select`, pagination, or transactions outside of the REST layer.
28
28
 
29
29
  ## How It Works
30
30
 
31
- 1. **Import `tables` (and other APIs) from `harper`**: Access every table defined in `schema.graphql` as a named property of `tables`. Each property is the table class implementing the Resource API.
31
+ 1. **Import `tables` (and other APIs) from `harper`**: Access every table defined in `schema.graphql` as a property of `tables`. Each property is the table class implementing the Resource API.
32
32
 
33
33
  ```javascript
34
34
  import { tables, transaction } from 'harper';
35
35
  const { Product } = tables;
36
- // equivalent to: databases.data.Product
36
+ // same as: databases.data.Product
37
37
  ```
38
38
 
39
- For standalone components, run `npm link harper` so imports resolve to the live runtime.
39
+ For components in their own directory, run:
40
40
 
41
- 2. **Define your schema with `@table`**: Tables must be declared in `schema.graphql`. Mark attributes you intend to sort or filter on with `@indexed`.
41
+ ```bash
42
+ npm link harper
43
+ ```
44
+
45
+ All installed components have `harper` automatically linked.
46
+
47
+ 2. **Define your schema with `@table`**: Every type you want to access via `tables` must carry the `@table` directive. Mark queryable fields with `@indexed`.
42
48
 
43
49
  ```graphql
44
50
  type Product @table {
@@ -48,7 +54,7 @@ Apply this rule when writing server-side Harper component code that reads from o
48
54
  }
49
55
  ```
50
56
 
51
- 3. **Query records with `search(`**: Pass a Query object to `search(`. Iterate results with `for await`.
57
+ 3. **Query records using `search(`**: Pass a Query object to `search()`. The query is an async iterable.
52
58
 
53
59
  ```javascript
54
60
  const query = {
@@ -59,7 +65,7 @@ Apply this rule when writing server-side Harper component code that reads from o
59
65
  }
60
66
  ```
61
67
 
62
- 4. **Build `conditions`**: Each condition object supports these properties:
68
+ 4. **Build `conditions`**: Each condition object supports the following properties:
63
69
 
64
70
  | Property | Description |
65
71
  | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -69,53 +75,60 @@ Apply this rule when writing server-side Harper component code that reads from o
69
75
  | `conditions` | Nested conditions array |
70
76
  | `operator` | `and` (default) or `or` for the nested `conditions` |
71
77
 
72
- 5. **Control result shape with `select`**: Pass an array of property names, a single string, or nested objects for relationships.
78
+ 5. **Apply `select` to shape results**: Pass an array of property names, a string for a single property, or nested objects for relationships.
73
79
 
74
80
  ```javascript
75
- // Scalar fields only
81
+ // Flat select
76
82
  Product.search({ select: ['name', 'price'] });
77
83
 
78
- // Partial related record
84
+ // Nested relationship select
79
85
  Book.get({ id: 42, select: ['id', 'title', { name: 'author', select: ['name'] }] });
80
86
  ```
81
87
 
82
88
  Special `select` values: `$id`, `$updatedtime`, `$distance`.
83
89
 
84
- 6. **Paginate with `limit` and `offset`**:
85
-
86
- ```javascript
87
- Product.search({ conditions: [...], limit: 20, offset: 40 });
88
- ```
90
+ 6. **Apply `sort`**: Harper uses an index to provide sort order.
89
91
 
90
- 7. **Sort with `sort`**: The `sort` object accepts `attribute`, `descending` (default `false`), and `next` for tie-breaking. Harper uses an index for sort order — the sort `attribute` must be `@indexed`, **or** at least one entry in `conditions` must be present.
92
+ | Property | Description |
93
+ | ------------ | ---------------------------------------------------------- |
94
+ | `attribute` | Property name (or array for chained relationship property) |
95
+ | `descending` | Sort descending if `true` (default: `false`) |
96
+ | `next` | Secondary sort to resolve ties (same structure) |
97
+ - If the sort `attribute` is `@indexed`, no condition is required.
98
+ - If the sort `attribute` is not indexed, at least one entry in `conditions` (on **any** attribute) is required.
99
+ - Sorting by a non-indexed attribute with zero conditions raises:
100
+ > `HdbError: <attribute> is not indexed and not combined with any other conditions`
101
+ - The bare `@primaryKey` is treated as not indexed for sort purposes. To iterate in primary-key order, add an open-ended condition:
91
102
 
92
- Sorting by a non-indexed attribute with zero conditions raises:
103
+ ```javascript
104
+ Product.search({
105
+ conditions: [{ attribute: 'id', comparator: 'greater_than', value: '' }],
106
+ sort: { attribute: 'id' },
107
+ });
108
+ ```
93
109
 
94
- > `HdbError: <attribute> is not indexed and not combined with any other conditions`
110
+ - Pass `allowFullScan: true` to permit an unconditional ordered scan, or omit `sort` entirely to iterate without an index requirement.
95
111
 
96
- Note: `@primaryKey` alone is treated as not indexed for sort purposes. To scan the whole table in primary-key order, add an open-ended condition:
112
+ 7. **Paginate with `limit` and `offset`**:
97
113
 
98
114
  ```javascript
99
- Product.search({
100
- conditions: [{ attribute: 'id', comparator: 'greater_than', value: '' }],
101
- sort: { attribute: 'id' },
102
- });
115
+ Product.search({ conditions: [...], limit: 20, offset: 40 });
103
116
  ```
104
117
 
105
- Alternatively, pass `allowFullScan: true` to permit an unconditional ordered scan, or omit `sort` entirely to iterate without an index requirement.
106
-
107
- 8. **Debug query planning with `explain` and `enforceExecutionOrder`**:
118
+ 8. **Debug with `explain` and `enforceExecutionOrder`**:
108
119
  - `explain: true` — returns conditions reordered as Harper will execute them.
109
- - `enforceExecutionOrder: true` — forces conditions to execute in the order supplied, disabling automatic re-ordering.
120
+ - `enforceExecutionOrder: true` — forces conditions to execute in the order supplied, disabling Harper's automatic re-ordering.
110
121
 
111
- 9. **Use `addTo` for concurrent-safe numeric updates**: `addTo` uses CRDT incrementation, safe across threads and nodes.
122
+ 9. **Use `addTo` for concurrent-safe increments**: `addTo(property, value)` uses CRDT incrementation, safe across threads and nodes.
112
123
 
113
124
  ```javascript
114
- const record = await Product.update(32);
115
- record.addTo('quantity', -1);
125
+ static async post(target, data) {
126
+ const record = await this.update(target.id);
127
+ record.addTo('quantity', -1);
128
+ }
116
129
  ```
117
130
 
118
- 10. **Wrap background work in `transaction()`**: HTTP handlers get a transaction automatically. Use `transaction()` explicitly for timers, background jobs, or any code outside a request context. Always `await` the call and `catch` errors.
131
+ 10. **Wrap background work in `transaction()`**: Harper auto-starts transactions for HTTP handlers. Use `transaction()` explicitly for timers, background jobs, or any code outside a natural transaction context.
119
132
 
120
133
  ```javascript
121
134
  await transaction(async (txn) => {
@@ -127,18 +140,18 @@ Apply this rule when writing server-side Harper component code that reads from o
127
140
 
128
141
  The `txn` object exposes:
129
142
 
130
- | Member | Description |
131
- | --------------------- | ------------------------------------------------------ |
132
- | `commit()` | Commits the current transaction |
133
- | `abort()` | Aborts and resets the transaction |
134
- | `resetReadSnapshot()` | Resets the read snapshot to the latest committed state |
135
- | `timestamp` | Timestamp associated with the current transaction |
143
+ | Member | Type | Description |
144
+ | --------------------- | --------------- | ------------------------------------------------------ |
145
+ | `commit()` | `() => Promise` | Commits the current transaction |
146
+ | `abort()` | `() => void` | Aborts the transaction and resets it |
147
+ | `resetReadSnapshot()` | `() => void` | Resets the read snapshot to the latest committed state |
148
+ | `timestamp` | `number` | Timestamp associated with the current transaction |
136
149
 
137
- **Atomicity**: all tables in the same database share one transactional context — writes across multiple tables commit atomically. Tables in different databases each get their own transaction with no cross-database atomicity guarantee.
150
+ On normal callback completion the transaction commits automatically. If the callback throws, the transaction is aborted.
138
151
 
139
- If `transaction()` is called with a context that already has an active transaction, it reuses that transaction — safe to call defensively.
152
+ 11. **Understand atomicity**: Transactions span a single database. All tables within the same database share one transactional context — reads return a consistent snapshot and writes across multiple tables commit atomically. Cross-database operations get separate transactions with no cross-database atomicity guarantee.
140
153
 
141
- 11. **Keep `harper` external when bundling for SSR**: In `vite.config`, mark `harper` as external so it resolves to the runtime rather than being bundled.
154
+ 12. **Keep `harper` external when bundling for SSR**: In `vite.config`, mark `harper` as external so it resolves to the runtime rather than being bundled.
142
155
 
143
156
  ```javascript
144
157
  // vite.config
@@ -149,7 +162,7 @@ Apply this rule when writing server-side Harper component code that reads from o
149
162
 
150
163
  ## Examples
151
164
 
152
- ### Full CRUD sequence
165
+ **Full CRUD flow:**
153
166
 
154
167
  ```javascript
155
168
  import { tables } from 'harper';
@@ -161,19 +174,18 @@ const created = await Product.create({ name: 'Shirt', price: 9.5 });
161
174
  // Patch
162
175
  await Product.patch(created.id, { price: Math.round(created.price * 0.8 * 100) / 100 });
163
176
 
164
- // Retrieve by primary key
177
+ // Get by primary key
165
178
  const record = await Product.get(created.id);
166
179
 
167
- // Query with conditions
168
- const query = {
180
+ // Search with conditions
181
+ for await (const record of Product.search({
169
182
  conditions: [{ attribute: 'price', comparator: 'less_than', value: 8.0 }],
170
- };
171
- for await (const record of Product.search(query)) {
183
+ })) {
172
184
  // process record
173
185
  }
174
186
  ```
175
187
 
176
- ### Nested conditions with `or`
188
+ **Nested conditions with `or`:**
177
189
 
178
190
  ```javascript
179
191
  Product.search({
@@ -190,13 +202,13 @@ Product.search({
190
202
  });
191
203
  ```
192
204
 
193
- ### Chained attribute reference (join/relationship)
205
+ **Chained attribute reference (join):**
194
206
 
195
207
  ```javascript
196
208
  Product.search({ conditions: [{ attribute: ['brand', 'name'], value: 'Harper' }] });
197
209
  ```
198
210
 
199
- ### Background job with `transaction()`
211
+ **Background job with `transaction()`:**
200
212
 
201
213
  ```javascript
202
214
  import { isMainThread } from 'node:worker_threads';
@@ -224,7 +236,7 @@ if (isMainThread) {
224
236
  }
225
237
  ```
226
238
 
227
- ### SSR render with `tables`
239
+ **SSR with Harper data:**
228
240
 
229
241
  ```typescript
230
242
  import { tables } from 'harper';
@@ -237,7 +249,9 @@ export async function render(url: string): Promise<string> {
237
249
 
238
250
  ## Notes
239
251
 
240
- - `tables` and `databases` do **not** automatically apply role permissions — calls run in a trusted server-side context. Apply your own authorization controls before exposing results.
241
- - Destructive operations (`update`, `patch`, `delete`) act on live data and are not easily reversible. Scope them with specific `conditions` and validate the affected set before writing.
242
- - `tables` is the same live, process-wide object whether accessed as a global or via `import { tables } from 'harper'`. A record written through one component is immediately visible to every other.
243
- - Run `npm link harper` for components in their own directory to ensure typings match the running installation.
252
+ - `tables` and `databases` calls run in a trusted server-side context and do **not** automatically apply the target table's role permissions.
253
+ - Programmatic `update`, `patch`, and `delete` calls operate directly on stored data. Scope destructive operations with specific `conditions`, validate the affected set before writing, and gate them behind authorization controls.
254
+ - If `transaction()` is called with a context that already has an active transaction, it reuses that transaction — making it safe to call defensively.
255
+ - Always `await` the `transaction()` call and `catch` errors when outside a request context; an unawaited call means a failed write is never observed.
256
+ - Guard against timer overlap: if a job can outlast its interval, use a `running` flag to skip a tick rather than opening two transactions over the same rows.
257
+ - CommonJS is also supported: `const { tables, Resource } = require('harper');`
@@ -595,8 +595,12 @@ rules:
595
595
  # Infrastructure & Ops (priority 4 — MEDIUM)
596
596
  # ===========================================================================
597
597
 
598
+ # Deploying is split across two rules: as one, its sources would come to
599
+ # ~57KB, well over any other rule's input, and the larger the input, the more
600
+ # facts regeneration compresses away. This rule covers a CLI deploy and what
601
+ # happens to a release afterwards; deploying-from-ci covers OIDC in CI.
598
602
  - rule: deploying-to-harper-fabric
599
- description: How to deploy a Harper application to the Harper Fabric cloud.
603
+ description: How to deploy a Harper application to Harper Fabric with the CLI, check that the release was certified, and roll back by activating a previous release's `deployment_id`.
600
604
  category: ops
601
605
  priority: 4
602
606
  order: 1
@@ -608,6 +612,41 @@ rules:
608
612
  - path: fabric/cluster-creation-management.md
609
613
  section: 'Connecting the Harper CLI to a Cluster'
610
614
  role: supplemental
615
+ # The CLI forms of `restart=rolling`, `replicated=false`, `activate=false`
616
+ # and `deployment_id=`. Matched by heading text, so the
617
+ # `restart=rolling` anchor also fails if commands.md ever gains an
618
+ # earlier `Parameters` heading.
619
+ - path: reference/v5/cli/commands.md
620
+ section: 'Parameters'
621
+ role: supplemental
622
+ # How `list_deployments` and `get_job` are run from the CLI.
623
+ - path: reference/v5/cli/operations-api-commands.md
624
+ section: 'General Syntax'
625
+ role: supplemental
626
+ # `deploy_component` is sourced by subsection: the whole section is
627
+ # ~30KB, mostly detail that does not change what an agent does.
628
+ # `Restarting` is left out: Parameters and the canary section carry
629
+ # what an agent needs from it.
630
+ - path: reference/v5/operations-api/operations.md
631
+ section: 'Certifying a release in a canary worker'
632
+ role: primary
633
+ - path: reference/v5/operations-api/operations.md
634
+ section: 'Staging a build and activating it later'
635
+ role: primary
636
+ - path: reference/v5/operations-api/operations.md
637
+ section: 'Going back to a previous release'
638
+ role: primary
639
+ # What a retried activation does on each node, and that a retry with
640
+ # `restart` restarts every worker even where the release is live.
641
+ - path: reference/v5/operations-api/operations.md
642
+ section: 'Retrying an activation'
643
+ role: supplemental
644
+ - path: reference/v5/operations-api/operations.md
645
+ section: '`list_deployments`'
646
+ role: supplemental
647
+ - path: reference/v5/operations-api/operations.md
648
+ section: '`get_job`'
649
+ role: supplemental
611
650
  must_cover:
612
651
  - 'harper deploy'
613
652
  - 'harper login'
@@ -619,6 +658,10 @@ rules:
619
658
  # enc:v1: (1×) → the client-side-encryption envelope
620
659
  # They double as the rename detector for that subheading: if it is
621
660
  # retitled or removed, the content goes and these anchors fail.
661
+ #
662
+ # Deploying by reference is no longer the CI default, but a private
663
+ # repository is still deployed that way. If the docs move this guidance
664
+ # out of `## Remote Management`, re-point the source; don't drop these.
622
665
  - 'fine-grained'
623
666
  - 'Contents: Read-only'
624
667
  - 'read:org'
@@ -633,35 +676,168 @@ rules:
633
676
  # provisions for. The source escapes it as `super\_user`; every generated
634
677
  # body so far unescapes, so the anchor is the unescaped form.
635
678
  - 'super_user'
679
+ # Going back: activating a kept release rebuilds nothing, where
680
+ # redeploying an older commit installs it again from source.
681
+ # `stagingRetention` holds how many releases a node keeps.
682
+ - 'deployment_id'
683
+ - 'list_deployments'
684
+ - 'stagingRetention'
685
+ - 'activate: false'
686
+ # On Pro and Fabric a deploy replicates unless `replicated=false`.
687
+ - 'replicated=false'
688
+ # `not-requested` occurs only in the `certification` table, so it holds
689
+ # the table, not a passing mention of the field. `restartJobId`, `get_job`
690
+ # and `COMPLETE` hold the wait: a rolling deploy responds once its job
691
+ # starts, and its record says `success` even if the job then fails.
692
+ - 'restart=rolling'
693
+ - 'certification'
694
+ - 'not-requested'
695
+ - 'fails closed'
696
+ - 'restartJobId'
697
+ - 'get_job'
698
+ - 'COMPLETE'
636
699
  cross_links:
637
700
  - creating-a-fabric-account-and-cluster
701
+ - deploying-from-ci
702
+
703
+ - rule: deploying-from-ci
704
+ description: How to deploy a Harper application from GitHub Actions with OIDC trusted publishing, so CI stores no Harper credential, including the one-command setup with `harper deploy setup=true provider=github-actions`.
705
+ category: ops
706
+ priority: 4
707
+ order: 2
708
+ mode: generate
709
+ # The guide's isolated-worker and per-PR preview sections are left out:
710
+ # ~18KB on their own, and a different task from deploying a release.
711
+ sources:
712
+ # The one-command setup (v5.4.0) for a workflow that deploys when changes
713
+ # merge to a branch, which create-harper projects scaffold. The guide's
714
+ # hand-written policy is still what a tag-triggered release needs.
715
+ - path: reference/v5/cli/commands.md
716
+ section: 'GitHub Actions deploys (OIDC)'
717
+ role: primary
718
+ - path: learn/developers/deploying-from-ci.md
719
+ section: 'Let the workflow authenticate with OIDC'
720
+ role: primary
721
+ - path: learn/developers/deploying-from-ci.md
722
+ section: 'Path A: deploy a tagged release from your repository'
723
+ role: primary
724
+ - path: learn/developers/deploying-from-ci.md
725
+ section: 'Give Harper a durable credential for a private source'
726
+ role: supplemental
727
+ - path: learn/developers/deploying-from-ci.md
728
+ section: 'Path B: build in CI, publish to GitHub Packages, deploy the artifact'
729
+ role: supplemental
730
+ - path: learn/developers/deploying-from-ci.md
731
+ section: 'Check the deployment record'
732
+ role: supplemental
733
+ - path: learn/developers/deploying-from-ci.md
734
+ section: 'Operational notes'
735
+ role: supplemental
736
+ # Where the exchange sits in credential precedence, and how to diagnose
737
+ # a refused one.
738
+ - path: reference/v5/cli/authentication.md
739
+ section: 'Workload identity (OIDC)'
740
+ role: supplemental
741
+ - path: reference/v5/operations-api/operations.md
742
+ section: 'Policy specificity for GitHub Actions'
743
+ role: supplemental
744
+ - path: reference/v5/operations-api/operations.md
745
+ section: '`list_oidc_trust`'
746
+ role: supplemental
747
+ - path: reference/v5/operations-api/operations.md
748
+ section: '`drop_oidc_trust`'
749
+ role: supplemental
750
+ must_cover:
751
+ # The one-command setup: `workflow=` holds the default-file rule (a
752
+ # `deploy.yml` workflow can't match a policy pinned to `deploy.yaml`),
753
+ # and `github-actions-<project>` the policy name a revocation drops.
754
+ - 'provider=github-actions'
755
+ - 'workflow='
756
+ - 'github-actions-<project>'
757
+ # The version check `harper deploy` makes before it uploads; a role
758
+ # without it logs a refused operation on every run.
759
+ - 'registration_info'
760
+ - 'id-token: write'
761
+ - 'vars.HARPER_CLI_TARGET'
762
+ # A configured credential outranks the exchange, so a pipeline that
763
+ # keeps its refresh token never uses OIDC.
764
+ - 'HARPER_CLI_REFRESH_TOKEN'
765
+ # The workflow as written: without a checkout and the CLI, a clean
766
+ # runner has nothing to deploy and nothing to deploy it with. Fact
767
+ # retention can't see inside a fence, and step 2's single job also has
768
+ # `runs-on: ubuntu-latest` and `actions/checkout`, so Path A's complete
769
+ # workflow is held by what only it has: its trigger (`push:` and
770
+ # `tags: ['v*']`), its `jobs:` wrapper, and the wait loop's
771
+ # `.[0].status`. The CLI install is held with its pin: an unpinned one
772
+ # would change under a rerun of an old tag after a new major release.
773
+ - 'actions/checkout'
774
+ - 'npm install --global harper@^5.3'
775
+ - 'runs-on: ubuntu-latest'
776
+ - 'push:'
777
+ - "tags: ['v*']"
778
+ - 'jobs:'
779
+ - '.[0].status'
780
+ # `workflow_path` is what a tag-triggered release pins instead of
781
+ # `workflow_ref`. `trailing slash` holds the audience rule, without which
782
+ # a policy never matches. The environment is the ref gate, and only as
783
+ # strong as its deployment branch and tag rules.
784
+ - 'add_oidc_trust'
785
+ - 'super_user'
786
+ - 'token.actions.githubusercontent.com'
787
+ - 'repository_id'
788
+ - 'workflow_ref'
789
+ - 'workflow_path'
790
+ - 'environment: production'
791
+ - 'Deployment branches and tags'
792
+ - 'trailing slash'
793
+ # An `operations` allowlist refuses what it doesn't list, so the wait
794
+ # step needs `get_job`. A job lives only on the node that received the
795
+ # deploy, so polls through a load-balanced URL have to reach it.
796
+ - 'deploy_component'
797
+ - 'get_job'
798
+ - 'get_deployment'
799
+ - 'restartJobId'
800
+ - 'load-balanced'
801
+ - 'credential=true'
802
+ # A rejected exchange never says which check failed; `invalid_reason`
803
+ # and the `oidc-trust` log do. Dropping a policy leaves an issued token
804
+ # valid for its hour; `alter_user` stops it.
805
+ - 'list_oidc_trust'
806
+ - 'invalid_reason'
807
+ - 'oidc-trust'
808
+ - 'drop_oidc_trust'
809
+ - 'alter_user'
810
+ # The user setup creates, which an incident revocation deactivates.
811
+ - '<project>-ci-deploy'
812
+ cross_links:
813
+ - deploying-to-harper-fabric
638
814
 
639
815
  - rule: creating-a-fabric-account-and-cluster
640
816
  description: How to create a Harper Fabric account, organization, and cluster.
641
817
  category: ops
642
818
  priority: 4
643
- order: 2
819
+ order: 3
644
820
  mode: synthesized
645
821
 
646
822
  - rule: creating-harper-apps
647
823
  description: How to initialize a new Harper application using the CLI.
648
824
  category: ops
649
825
  priority: 4
650
- order: 3
826
+ order: 4
651
827
  mode: synthesized
652
828
 
653
829
  - rule: serving-web-content
654
830
  description: How to serve static files and integrated Vite/React applications in Harper.
655
831
  category: ops
656
832
  priority: 4
657
- order: 4
833
+ order: 5
658
834
  mode: synthesized
659
835
 
660
836
  - rule: logging
661
837
  description: Best practices for logging in Harper, including console capture, the granular logger interface, and programmatic log retrieval.
662
838
  category: ops
663
839
  priority: 4
664
- order: 5
840
+ order: 6
665
841
  mode: generate
666
842
  sources:
667
843
  - path: reference/v5/logging/overview.md
@@ -677,7 +853,7 @@ rules:
677
853
  description: How to load environment variables from .env files into a Harper application using the loadEnv plugin.
678
854
  category: ops
679
855
  priority: 4
680
- order: 6
856
+ order: 7
681
857
  mode: generate
682
858
  sources:
683
859
  - path: reference/v5/environment-variables/overview.md
@@ -693,7 +869,7 @@ rules:
693
869
  description: Breaking changes and recommended updates when migrating a Harper application to v5.
694
870
  category: ops
695
871
  priority: 4
696
- order: 7
872
+ order: 8
697
873
  mode: generate
698
874
  sources:
699
875
  - path: release-notes/v5-lincoln/v5-migration.md
@@ -723,7 +899,7 @@ rules:
723
899
  description: How to delegate tasks to Harper's built-in agent via the CLI and the agent operations API.
724
900
  category: ops
725
901
  priority: 4
726
- order: 8
902
+ order: 9
727
903
  mode: synthesized
728
904
  cross_links:
729
905
  - deploying-to-harper-fabric
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harperfast/template-vue-ts-studio",
3
- "version": "1.12.12",
3
+ "version": "1.13.1",
4
4
  "type": "module",
5
5
  "repository": "github:HarperFast/create-harper",
6
6
  "scripts": {},
package/skills-lock.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "source": "harperfast/skills",
6
6
  "sourceType": "github",
7
7
  "skillPath": "harper-best-practices/SKILL.md",
8
- "computedHash": "b157e80968413da12ccbbe21f4b64eb0d1bcfc7c0f166b03f51a0013fe8901a0"
8
+ "computedHash": "b95b53d7d50d882d44b2f331fc45047e3caa8bd5140fbfb777aedd9b18eb451b"
9
9
  },
10
10
  "harper-local-dev": {
11
11
  "source": "harperfast/skills",