@hasna/instructions 0.6.0 → 0.7.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 +149 -8
- package/dist/chunks/apply-7svah2qm.js +25 -0
- package/dist/chunks/apply-jp13sa1e.js +25 -0
- package/dist/chunks/database-wstmr56z.js +23 -0
- package/dist/chunks/index-1cnyjnd7.js +623 -0
- package/dist/chunks/index-35z65jsa.js +198 -0
- package/dist/chunks/index-3djthcm6.js +117 -0
- package/dist/chunks/index-4pfq42t5.js +7300 -0
- package/dist/chunks/index-5d7zdftc.js +186 -0
- package/dist/chunks/index-7m4j8a33.js +12578 -0
- package/dist/chunks/index-8rb7ng2y.js +148 -0
- package/dist/chunks/index-arrrx0ed.js +344 -0
- package/dist/chunks/index-bsan4c16.js +48 -0
- package/dist/chunks/index-bzyxvwcd.js +625 -0
- package/dist/chunks/index-fpeyzn3n.js +186 -0
- package/dist/chunks/index-fwbs6tma.js +534 -0
- package/dist/chunks/index-ma2xmp6c.js +14 -0
- package/dist/chunks/index-n3fjspr0.js +119 -0
- package/dist/chunks/index-nnwp92tk.js +19 -0
- package/dist/chunks/index-z3ma4aqk.js +532 -0
- package/dist/chunks/legacy-store-migration-z2m5yzyk.js +322 -0
- package/dist/chunks/local-5wvv5xv3.js +694 -0
- package/dist/chunks/local-zxa5dpf4.js +518 -0
- package/dist/chunks/package-manager-guard-x70xrwk2.js +391 -0
- package/dist/chunks/redact-hnq4sc4r.js +16 -0
- package/dist/chunks/s3-backup-n2z4fwyh.js +240 -0
- package/dist/chunks/s3-config-hhght91k.js +14 -0
- package/dist/chunks/s3-object-store-90tgbh6k.js +14 -0
- package/dist/chunks/sync-2075deve.js +34 -0
- package/dist/chunks/sync-r8t7zsp3.js +34 -0
- package/dist/chunks/template-fsfxpe4p.js +16 -0
- package/dist/chunks/template-wgnzdn7h.js +16 -0
- package/dist/cli/index.js +1681 -15643
- package/dist/data/config-store.d.ts +2 -1
- package/dist/data/config-store.d.ts.map +1 -1
- package/dist/db/database.d.ts +3 -5
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/local.d.ts +38 -0
- package/dist/db/local.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13809 -12998
- package/dist/lib/apply.d.ts +7 -0
- package/dist/lib/apply.d.ts.map +1 -1
- package/dist/lib/compact-output.d.ts +1 -0
- package/dist/lib/compact-output.d.ts.map +1 -1
- package/dist/lib/export.d.ts +22 -3
- package/dist/lib/export.d.ts.map +1 -1
- package/dist/lib/ids.d.ts +4 -0
- package/dist/lib/ids.d.ts.map +1 -0
- package/dist/lib/import.d.ts +18 -0
- package/dist/lib/import.d.ts.map +1 -1
- package/dist/lib/instruction-graph.d.ts.map +1 -1
- package/dist/lib/legacy-store-migration.d.ts +39 -0
- package/dist/lib/legacy-store-migration.d.ts.map +1 -0
- package/dist/lib/managed-skill-runtimes.d.ts +1 -0
- package/dist/lib/managed-skill-runtimes.d.ts.map +1 -1
- package/dist/lib/session-render.d.ts +3 -0
- package/dist/lib/session-render.d.ts.map +1 -1
- package/dist/lib/sync-dir.d.ts.map +1 -1
- package/dist/mcp/index.js +73 -9462
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +205 -10
- package/dist/sdk/resolve.d.ts +1 -1
- package/dist/sdk/resolve.d.ts.map +1 -1
- package/dist/sdk/v1-client.d.ts +57 -0
- package/dist/sdk/v1-client.d.ts.map +1 -0
- package/dist/sdk/v1.generated.d.ts +212 -21
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.d.ts +13 -5
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8337 -7495
- package/dist/server/openapi.d.ts +1264 -92
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/v1.d.ts +25 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/status.d.ts +12 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/storage/cloud-store.d.ts +57 -1
- package/dist/storage/cloud-store.d.ts.map +1 -1
- package/dist/storage/index.d.ts +7 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +725 -0
- package/dist/storage/s3-backup.d.ts +76 -0
- package/dist/storage/s3-backup.d.ts.map +1 -0
- package/dist/storage/s3-config.d.ts +46 -0
- package/dist/storage/s3-config.d.ts.map +1 -0
- package/dist/storage/s3-object-store.d.ts +70 -0
- package/dist/storage/s3-object-store.d.ts.map +1 -0
- package/dist/types/index.d.ts +65 -3
- package/dist/types/index.d.ts.map +1 -1
- package/hasna.contract.json +110 -0
- package/migrations/0001_instructions.sql +63 -0
- package/migrations/0002_api_keys.sql +20 -0
- package/migrations/0003_idempotency_receipts.sql +24 -0
- package/package.json +29 -14
- package/assets/skills/inbox/SKILL.md +0 -86
- package/dist/cli/add-duplicate-target.test.d.ts +0 -2
- package/dist/cli/add-duplicate-target.test.d.ts.map +0 -1
- package/dist/cli/add-reference-update.test.d.ts +0 -2
- package/dist/cli/add-reference-update.test.d.ts.map +0 -1
- package/dist/cli/apply-unchanged-snapshot-bloat.test.d.ts +0 -2
- package/dist/cli/apply-unchanged-snapshot-bloat.test.d.ts.map +0 -1
- package/dist/cli/doctor-reference-duplicates.test.d.ts +0 -2
- package/dist/cli/doctor-reference-duplicates.test.d.ts.map +0 -1
- package/dist/cli/fail-closed-no-env.test.d.ts +0 -2
- package/dist/cli/fail-closed-no-env.test.d.ts.map +0 -1
- package/dist/cli/output.test.d.ts +0 -2
- package/dist/cli/output.test.d.ts.map +0 -1
- package/dist/cli/profile-binding.test.d.ts +0 -2
- package/dist/cli/profile-binding.test.d.ts.map +0 -1
- package/dist/cli/profile-reads.test.d.ts +0 -2
- package/dist/cli/profile-reads.test.d.ts.map +0 -1
- package/dist/cli/profile-update.test.d.ts +0 -2
- package/dist/cli/profile-update.test.d.ts.map +0 -1
- package/dist/cli/project-context.test.d.ts +0 -2
- package/dist/cli/project-context.test.d.ts.map +0 -1
- package/dist/cli/raw-store-root.test.d.ts +0 -2
- package/dist/cli/raw-store-root.test.d.ts.map +0 -1
- package/dist/cli/session-apply-managed-input-bound.test.d.ts +0 -2
- package/dist/cli/session-apply-managed-input-bound.test.d.ts.map +0 -1
- package/dist/cli/session.test.d.ts +0 -2
- package/dist/cli/session.test.d.ts.map +0 -1
- package/dist/cli/station-profile.test.d.ts +0 -2
- package/dist/cli/station-profile.test.d.ts.map +0 -1
- package/dist/data/config-store.test.d.ts +0 -2
- package/dist/data/config-store.test.d.ts.map +0 -1
- package/dist/db/configs.test.d.ts +0 -2
- package/dist/db/configs.test.d.ts.map +0 -1
- package/dist/db/database.test.d.ts +0 -2
- package/dist/db/database.test.d.ts.map +0 -1
- package/dist/db/machines.test.d.ts +0 -2
- package/dist/db/machines.test.d.ts.map +0 -1
- package/dist/db/profile-assets.test.d.ts +0 -2
- package/dist/db/profile-assets.test.d.ts.map +0 -1
- package/dist/db/profile-config-bindings.test.d.ts +0 -2
- package/dist/db/profile-config-bindings.test.d.ts.map +0 -1
- package/dist/db/profiles.test.d.ts +0 -2
- package/dist/db/profiles.test.d.ts.map +0 -1
- package/dist/db/snapshots.test.d.ts +0 -2
- package/dist/db/snapshots.test.d.ts.map +0 -1
- package/dist/lib/app-home.test.d.ts +0 -2
- package/dist/lib/app-home.test.d.ts.map +0 -1
- package/dist/lib/apply-batch.test.d.ts +0 -2
- package/dist/lib/apply-batch.test.d.ts.map +0 -1
- package/dist/lib/apply-dry-run-verdict.test.d.ts +0 -2
- package/dist/lib/apply-dry-run-verdict.test.d.ts.map +0 -1
- package/dist/lib/apply-secret-placeholder-guard.test.d.ts +0 -2
- package/dist/lib/apply-secret-placeholder-guard.test.d.ts.map +0 -1
- package/dist/lib/apply-text-format-credential-guard.test.d.ts +0 -2
- package/dist/lib/apply-text-format-credential-guard.test.d.ts.map +0 -1
- package/dist/lib/apply.test.d.ts +0 -2
- package/dist/lib/apply.test.d.ts.map +0 -1
- package/dist/lib/asset-plan.test.d.ts +0 -2
- package/dist/lib/asset-plan.test.d.ts.map +0 -1
- package/dist/lib/client-types.test.d.ts +0 -2
- package/dist/lib/client-types.test.d.ts.map +0 -1
- package/dist/lib/codewith-shared-todos-storage-standard.test.d.ts +0 -2
- package/dist/lib/codewith-shared-todos-storage-standard.test.d.ts.map +0 -1
- package/dist/lib/compact-output.test.d.ts +0 -2
- package/dist/lib/compact-output.test.d.ts.map +0 -1
- package/dist/lib/config-target-identity.test.d.ts +0 -2
- package/dist/lib/config-target-identity.test.d.ts.map +0 -1
- package/dist/lib/cursor-authority.test.d.ts +0 -2
- package/dist/lib/cursor-authority.test.d.ts.map +0 -1
- package/dist/lib/dangerous-operation-guard-standard.test.d.ts +0 -2
- package/dist/lib/dangerous-operation-guard-standard.test.d.ts.map +0 -1
- package/dist/lib/diff-redaction.test.d.ts +0 -2
- package/dist/lib/diff-redaction.test.d.ts.map +0 -1
- package/dist/lib/export-import.test.d.ts +0 -2
- package/dist/lib/export-import.test.d.ts.map +0 -1
- package/dist/lib/global-agent-rules-render-integration.test.d.ts +0 -2
- package/dist/lib/global-agent-rules-render-integration.test.d.ts.map +0 -1
- package/dist/lib/global-agent-rules-standard.test.d.ts +0 -2
- package/dist/lib/global-agent-rules-standard.test.d.ts.map +0 -1
- package/dist/lib/global-agent-rules-stored-content.test.d.ts +0 -2
- package/dist/lib/global-agent-rules-stored-content.test.d.ts.map +0 -1
- package/dist/lib/global-source-coverage.test.d.ts +0 -2
- package/dist/lib/global-source-coverage.test.d.ts.map +0 -1
- package/dist/lib/instruction-graph-apply.test.d.ts +0 -2
- package/dist/lib/instruction-graph-apply.test.d.ts.map +0 -1
- package/dist/lib/instruction-graph.test.d.ts +0 -2
- package/dist/lib/instruction-graph.test.d.ts.map +0 -1
- package/dist/lib/machine.test.d.ts +0 -2
- package/dist/lib/machine.test.d.ts.map +0 -1
- package/dist/lib/managed-skill-runtimes.test.d.ts +0 -2
- package/dist/lib/managed-skill-runtimes.test.d.ts.map +0 -1
- package/dist/lib/package-manager-guard.test.d.ts +0 -2
- package/dist/lib/package-manager-guard.test.d.ts.map +0 -1
- package/dist/lib/project-context-prepared-file.test.d.ts +0 -2
- package/dist/lib/project-context-prepared-file.test.d.ts.map +0 -1
- package/dist/lib/project-context.test.d.ts +0 -2
- package/dist/lib/project-context.test.d.ts.map +0 -1
- package/dist/lib/project-dashboard-standard.test.d.ts +0 -2
- package/dist/lib/project-dashboard-standard.test.d.ts.map +0 -1
- package/dist/lib/provider-assets-adapters.test.d.ts +0 -2
- package/dist/lib/provider-assets-adapters.test.d.ts.map +0 -1
- package/dist/lib/provider-context.test.d.ts +0 -2
- package/dist/lib/provider-context.test.d.ts.map +0 -1
- package/dist/lib/provider-version-adapters.test.d.ts +0 -2
- package/dist/lib/provider-version-adapters.test.d.ts.map +0 -1
- package/dist/lib/redact.test.d.ts +0 -2
- package/dist/lib/redact.test.d.ts.map +0 -1
- package/dist/lib/session-apply.test.d.ts +0 -2
- package/dist/lib/session-apply.test.d.ts.map +0 -1
- package/dist/lib/session-authority.test.d.ts +0 -2
- package/dist/lib/session-authority.test.d.ts.map +0 -1
- package/dist/lib/session-render-managed-output-bound.test.d.ts +0 -2
- package/dist/lib/session-render-managed-output-bound.test.d.ts.map +0 -1
- package/dist/lib/session-render-ownership.test.d.ts +0 -2
- package/dist/lib/session-render-ownership.test.d.ts.map +0 -1
- package/dist/lib/session-render-rule-currency-floor.test.d.ts +0 -2
- package/dist/lib/session-render-rule-currency-floor.test.d.ts.map +0 -1
- package/dist/lib/session-render-silent-source-drop.test.d.ts +0 -2
- package/dist/lib/session-render-silent-source-drop.test.d.ts.map +0 -1
- package/dist/lib/session-render-state-hermeticity.test.d.ts +0 -2
- package/dist/lib/session-render-state-hermeticity.test.d.ts.map +0 -1
- package/dist/lib/session-render-state.test.d.ts +0 -2
- package/dist/lib/session-render-state.test.d.ts.map +0 -1
- package/dist/lib/session-render.test.d.ts +0 -2
- package/dist/lib/session-render.test.d.ts.map +0 -1
- package/dist/lib/station-profile.test.d.ts +0 -2
- package/dist/lib/station-profile.test.d.ts.map +0 -1
- package/dist/lib/sync-dir.test.d.ts +0 -2
- package/dist/lib/sync-dir.test.d.ts.map +0 -1
- package/dist/lib/sync-dry-run-unchanged.test.d.ts +0 -2
- package/dist/lib/sync-dry-run-unchanged.test.d.ts.map +0 -1
- package/dist/lib/sync-known.test.d.ts +0 -2
- package/dist/lib/sync-known.test.d.ts.map +0 -1
- package/dist/lib/sync.test.d.ts +0 -2
- package/dist/lib/sync.test.d.ts.map +0 -1
- package/dist/lib/template.test.d.ts +0 -2
- package/dist/lib/template.test.d.ts.map +0 -1
- package/dist/lib/transforms.test.d.ts +0 -2
- package/dist/lib/transforms.test.d.ts.map +0 -1
- package/dist/lib/transport-resolver.test.d.ts +0 -2
- package/dist/lib/transport-resolver.test.d.ts.map +0 -1
- package/dist/mcp/create-config-target-guard.test.d.ts +0 -2
- package/dist/mcp/create-config-target-guard.test.d.ts.map +0 -1
- package/dist/mcp/early-args.test.d.ts +0 -2
- package/dist/mcp/early-args.test.d.ts.map +0 -1
- package/dist/mcp/http.test.d.ts +0 -2
- package/dist/mcp/http.test.d.ts.map +0 -1
- package/dist/mcp/mcp.test.d.ts +0 -2
- package/dist/mcp/mcp.test.d.ts.map +0 -1
- package/dist/sdk/resolve.test.d.ts +0 -2
- package/dist/sdk/resolve.test.d.ts.map +0 -1
- package/dist/sdk/sdk-bundle-self-contained.test.d.ts +0 -2
- package/dist/sdk/sdk-bundle-self-contained.test.d.ts.map +0 -1
- package/dist/server/cloud-auth.test.d.ts +0 -2
- package/dist/server/cloud-auth.test.d.ts.map +0 -1
- package/dist/server/cloud.test.d.ts +0 -2
- package/dist/server/cloud.test.d.ts.map +0 -1
- package/dist/server/early-args.test.d.ts +0 -2
- package/dist/server/early-args.test.d.ts.map +0 -1
- package/dist/server/profile-contract.test.d.ts +0 -2
- package/dist/server/profile-contract.test.d.ts.map +0 -1
- package/dist/status.test.d.ts +0 -2
- package/dist/status.test.d.ts.map +0 -1
- package/dist/storage/cloud-store.test.d.ts +0 -2
- package/dist/storage/cloud-store.test.d.ts.map +0 -1
- package/dist/test-support/preload-state-home.d.ts +0 -2
- package/dist/test-support/preload-state-home.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -18,9 +18,15 @@ bun add --global @hasna/instructions
|
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
instructions --help
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
# Hosted-by-default: resolves the approved key and uses
|
|
23
|
+
# https://api.hasna.com/instructions/v1.
|
|
24
|
+
instructions status
|
|
22
25
|
instructions list
|
|
23
|
-
|
|
26
|
+
|
|
27
|
+
# Explicit on-box SQLite mode; there is never an implicit fallback.
|
|
28
|
+
HASNA_INSTRUCTIONS_LOCAL=1 instructions init
|
|
29
|
+
HASNA_INSTRUCTIONS_LOCAL=1 instructions list
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
## Migrating from `@hasna/configs`
|
|
@@ -29,6 +35,19 @@ This package was formerly `@hasna/configs`. The `configs` CLI alias and
|
|
|
29
35
|
`configs-mcp` alias remain available for existing integrations; new usage can
|
|
30
36
|
use the `instructions` names.
|
|
31
37
|
|
|
38
|
+
Historical on-box rows can be migrated without overwriting the current store:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
export HASNA_INSTRUCTIONS_LOCAL=1
|
|
42
|
+
instructions migrate-legacy --confirm-local --json # no-write plan
|
|
43
|
+
instructions migrate-legacy --confirm-local --apply --json # backup + transaction
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The source defaults to `~/.hasna/configs/configs.db`; the destination defaults
|
|
47
|
+
to the current `instructions.db`. A non-empty destination is refused unless
|
|
48
|
+
`--merge-preserve-destination` is explicit, and that merge never overwrites an
|
|
49
|
+
existing row.
|
|
50
|
+
|
|
32
51
|
## CLI Usage
|
|
33
52
|
|
|
34
53
|
```bash
|
|
@@ -109,8 +128,9 @@ instructions-mcp --http # http://127.0.0.1:8807/mcp
|
|
|
109
128
|
MCP_HTTP=1 instructions-mcp
|
|
110
129
|
```
|
|
111
130
|
|
|
112
|
-
Health: `GET http://127.0.0.1:8807/health`.
|
|
113
|
-
`instructions-serve`
|
|
131
|
+
Health: `GET http://127.0.0.1:8807/health`. The production
|
|
132
|
+
`instructions-serve` process deliberately does **not** mount MCP; local MCP and
|
|
133
|
+
the authenticated `/v1` service remain separate authorities.
|
|
114
134
|
|
|
115
135
|
## HTTP API server (`instructions-serve`)
|
|
116
136
|
|
|
@@ -120,14 +140,20 @@ instructions-serve
|
|
|
120
140
|
|
|
121
141
|
Surfaces:
|
|
122
142
|
|
|
123
|
-
- `GET /health`, `GET /ready`, `GET /version` → `{ status, version,
|
|
143
|
+
- `GET /health`, `GET /ready`, `GET /version` → `{ status, version, backend }`
|
|
124
144
|
- `GET /openapi.json`, `GET /v1/openapi.json` → the OpenAPI 3.1 document the SDK
|
|
125
145
|
is generated from.
|
|
126
146
|
- `/v1/*` — versioned cloud API (configs, profiles, snapshots, stats).
|
|
127
147
|
- No `/api/*` — the former local REST surface is not mounted (the removed
|
|
128
148
|
bundled dashboard was its only consumer).
|
|
129
149
|
|
|
130
|
-
### Server data backend (
|
|
150
|
+
### Server data backend (PostgreSQL, fail closed)
|
|
151
|
+
|
|
152
|
+
`instructions-serve` requires `HASNA_INSTRUCTIONS_DATABASE_URL` (or its documented
|
|
153
|
+
alias) for a usable `/v1` service. Without a DSN, `/health` remains a liveness
|
|
154
|
+
probe but reports `backend: "unconfigured"`; `/ready` returns 503 and `/v1`
|
|
155
|
+
returns a stable unavailable error. It never exposes local SQLite over the
|
|
156
|
+
service boundary.
|
|
131
157
|
|
|
132
158
|
When `HASNA_INSTRUCTIONS_DATABASE_URL` is set the `/v1` API reads/writes the
|
|
133
159
|
shared Postgres **directly** (no local sync/cache in the service) and every
|
|
@@ -150,6 +176,16 @@ they resolve `HASNA_INSTRUCTIONS_API_KEY` (or the Keychain / credentials-file
|
|
|
150
176
|
tiers) through the one `@hasna/contracts` client resolver, and the authority
|
|
151
177
|
defaults to the fleet gateway `https://api.hasna.com/instructions`.
|
|
152
178
|
|
|
179
|
+
Collection responses are producer-bounded with `limit`/`cursor` envelopes.
|
|
180
|
+
Current clients follow every page; `view=identity` returns an allowlisted
|
|
181
|
+
metadata-only projection for configs, profiles, and machines, without loading
|
|
182
|
+
instruction content or private profile fields. Retryable create and binding
|
|
183
|
+
writes may send `Idempotency-Key`; PostgreSQL stores the authenticated
|
|
184
|
+
principal, operation, canonical request digest, and first committed response in
|
|
185
|
+
the same transaction as the domain mutation. A same-body retry replays that
|
|
186
|
+
response, while key reuse with different bytes returns
|
|
187
|
+
`409 IDEMPOTENCY_KEY_REUSED`.
|
|
188
|
+
|
|
153
189
|
## SDK
|
|
154
190
|
|
|
155
191
|
The importable module ships INSIDE `@hasna/instructions` at the `./sdk` export
|
|
@@ -203,7 +239,9 @@ The two transports behind `ConfigStore`:
|
|
|
203
239
|
- **local** — on-box SQLite (`LocalConfigStore`), **opt-in only**:
|
|
204
240
|
`HASNA_INSTRUCTIONS_LOCAL=1`, honoured only when the environment configures
|
|
205
241
|
no authority and no credential. Every local run says `local mode` once on
|
|
206
|
-
stderr.
|
|
242
|
+
stderr. The SQLite half is loaded through a single dynamic import and is
|
|
243
|
+
bundled as a separate chunk, so `dist/cli/index.js` and `dist/mcp/index.js`
|
|
244
|
+
ship with zero `bun:sqlite` references and a hosted run never loads it.
|
|
207
245
|
|
|
208
246
|
Retired locations (`~/.hasna/fleet-env`, `~/.hasna/cloud`, `~/.config/hasna`,
|
|
209
247
|
`$XDG_CONFIG_HOME`, a `~/.instructions/config.json` key store) are inputs
|
|
@@ -213,10 +251,91 @@ transport is decided by what resolves, never by a mode word.
|
|
|
213
251
|
Clients never hold a database DSN. The raw Postgres connection is a server-only
|
|
214
252
|
concern (`instructions-serve`), selected by `HASNA_INSTRUCTIONS_DATABASE_URL`.
|
|
215
253
|
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
## Domain export and import
|
|
257
|
+
|
|
258
|
+
`instructions export` writes a restorable Instructions domain archive v2. The
|
|
259
|
+
archive contains config content and every retained config snapshot, profiles,
|
|
260
|
+
ordered profile membership and config-binding metadata, profile asset bindings,
|
|
261
|
+
and registered machines. Relationships are recorded by stable config/profile
|
|
262
|
+
slugs and machine hostnames, so import can map them safely onto destination IDs.
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
instructions export --output ./instructions-domain.tar.gz
|
|
266
|
+
instructions import ./instructions-domain.tar.gz # exact recovery into an empty destination
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
V2 is deliberately a recovery format, not a merge format. Import validates the
|
|
270
|
+
complete archive and requires a destination with zero configs, profiles, and
|
|
271
|
+
machines before the first mutation. `--overwrite` is rejected for v2 before
|
|
272
|
+
destination inspection or mutation. Any validation, mutation, or readback
|
|
273
|
+
failure throws and makes the CLI exit nonzero; discard that attempted
|
|
274
|
+
destination and retry from a newly empty database.
|
|
275
|
+
|
|
276
|
+
The manifest contains deterministic per-collection counts and SHA-256 logical
|
|
277
|
+
hashes for pre/post deployment comparison without placing instruction content
|
|
278
|
+
in logs. Exact deployment integrity includes config `created_at`, `updated_at`,
|
|
279
|
+
and `synced_at`; snapshot `created_at`; profile `created_at` and `updated_at`;
|
|
280
|
+
and machine `created_at` plus the exact `last_applied_at` value. After recovery,
|
|
281
|
+
import reads the complete domain back through `ConfigStore` and verifies every
|
|
282
|
+
field that interface can reproduce: config data and versions, retained snapshot
|
|
283
|
+
contents, profiles, ordered bindings, asset mappings, machines, and whether a
|
|
284
|
+
machine was ever applied.
|
|
285
|
+
|
|
286
|
+
`ConfigStore` cannot assign archived config/profile/snapshot/machine creation or
|
|
287
|
+
update timestamps, nor an exact machine `last_applied_at`; generated destination
|
|
288
|
+
IDs are also intentionally remapped by stable slugs and hostnames. These values
|
|
289
|
+
remain protected in the archive's exact integrity hashes but are not recreated
|
|
290
|
+
by recovery. ConfigStore also has no cross-entity transaction, so an operational
|
|
291
|
+
failure may leave a partial destination; the nonzero result is terminal and that
|
|
292
|
+
destination must not be reused. Legacy v1 config-only archives remain importable,
|
|
293
|
+
including their historical skip/overwrite conflict behavior.
|
|
294
|
+
|
|
295
|
+
API keys and idempotency receipts are intentionally excluded: they are security
|
|
296
|
+
and transport state that must be provisioned independently. Feedback is also
|
|
297
|
+
excluded because it is product telemetry, not part of the Instructions
|
|
298
|
+
configuration domain.
|
|
299
|
+
|
|
300
|
+
## Native S3 backup storage
|
|
301
|
+
|
|
302
|
+
S3 is an **adjunct immutable backup plane**, never a database selector. SQLite
|
|
303
|
+
remains the explicit local authority and PostgreSQL remains the hosted `/v1`
|
|
304
|
+
authority. Setting S3 variables alone never opens SQLite, never selects HTTP,
|
|
305
|
+
and never changes CRUD routing.
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
export HASNA_INSTRUCTIONS_S3_BUCKET=your-private-bucket
|
|
309
|
+
export HASNA_INSTRUCTIONS_AWS_REGION=us-east-1
|
|
310
|
+
# Optional: HASNA_INSTRUCTIONS_S3_PREFIX (default: instructions/)
|
|
311
|
+
# Optional local/S3-compatible endpoint and explicit static credentials.
|
|
312
|
+
|
|
313
|
+
instructions storage status --json
|
|
314
|
+
instructions export --output ./instructions-backup.tar.gz
|
|
315
|
+
instructions storage backup push ./instructions-backup.tar.gz --id 2026-09-15-pre-deploy --dry-run --json
|
|
316
|
+
instructions storage backup push ./instructions-backup.tar.gz --id 2026-09-15-pre-deploy --json
|
|
317
|
+
instructions storage backup verify 2026-09-15-pre-deploy --json
|
|
318
|
+
instructions storage backup pull 2026-09-15-pre-deploy --output ./restored-instructions.tar.gz --json
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Each backup uses traversal-safe deterministic keys, an atomically created
|
|
322
|
+
payload, and an atomically created manifest containing SHA-256, byte size,
|
|
323
|
+
content type, and creation time. Native S3 creation uses `If-None-Match: *`;
|
|
324
|
+
concurrent different-byte writers cannot replace the winner, identical replay
|
|
325
|
+
is idempotent, and an injected store without conditional-create support fails
|
|
326
|
+
closed. Pulls verify the payload before an owner-only local file is written.
|
|
327
|
+
Production backup buckets must enable versioning, encryption, public-access
|
|
328
|
+
blocking, and S3 Object Lock with a default retention period. AWS runtime
|
|
329
|
+
credentials may come from Bun's standard AWS chain (including an ECS task role);
|
|
330
|
+
explicit static credentials are optional and must be a complete pair. Status
|
|
331
|
+
never prints credential values or the bucket name.
|
|
332
|
+
|
|
333
|
+
The public importable surface is available at `@hasna/instructions/storage`.
|
|
334
|
+
|
|
216
335
|
## Data Directory
|
|
217
336
|
|
|
218
337
|
Local data (the SQLite store and backups) lives under the configs store home,
|
|
219
|
-
resolved
|
|
338
|
+
resolved by the in-package resolver. The legacy `~/.hasna/instructions/` default
|
|
220
339
|
(with the `HASNA_CONFIGS_HOME` exact-app override) stays the effective store
|
|
221
340
|
home until the store has actually been migrated to the XDG config home
|
|
222
341
|
(`~/.config/hasna/configs` on Linux; `~/Library/Application
|
|
@@ -263,6 +382,28 @@ manifests for drift, refuses unmanaged file conflicts unless `--force` is
|
|
|
263
382
|
passed, removes stale managed mirrors only when safe, and writes local snapshots
|
|
264
383
|
before mutating managed files.
|
|
265
384
|
|
|
385
|
+
Grok Build and Devin CLI can render global instructions into an explicitly
|
|
386
|
+
selected native home. Pass Grok's `GROK_HOME` directory or Devin's resolved user
|
|
387
|
+
config directory as `--target-home`; the renderer writes a flattened `AGENTS.md`
|
|
388
|
+
and its ownership manifest there. Devin's target is the `devin` config directory,
|
|
389
|
+
not its parent `XDG_CONFIG_HOME` or its credential-data directory.
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
instructions session plan --tool grok --profile work \
|
|
393
|
+
--target-home "$GROK_HOME" --identity-export ./instructions.json --json
|
|
394
|
+
instructions session apply --tool devin --profile work \
|
|
395
|
+
--target-home /absolute/isolated/config/devin --identity-export ./instructions.json
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
An explicit `--project-root` keeps the project renderer: Grok writes repository
|
|
399
|
+
`AGENTS.md`; Devin writes `.devin/rules/*.md`. Without either explicit target,
|
|
400
|
+
these providers remain blocked. Compiled native profiles select the
|
|
401
|
+
`native-profile` capability (Grok 1.0.13+, Devin 3000.10.21+); conditional bindings
|
|
402
|
+
require an explicit supported fallback because global `AGENTS.md` is always on.
|
|
403
|
+
The existing conflict, drift, symlink and snapshot checks also apply to native homes.
|
|
404
|
+
See [Devin global rules](https://docs.devin.ai/cli/extensibility/rules) and
|
|
405
|
+
[Grok settings](https://docs.x.ai/build/settings) for native home configuration.
|
|
406
|
+
|
|
266
407
|
### Session renderer ownership
|
|
267
408
|
|
|
268
409
|
Anything the session renderer writes is off limits to `instructions apply` and
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
applyConfig,
|
|
4
|
+
applyConfigs,
|
|
5
|
+
applyConfigsWithReport,
|
|
6
|
+
compactPathForConfigHome,
|
|
7
|
+
expandPath,
|
|
8
|
+
getConfigHome,
|
|
9
|
+
normalizeTargetPath,
|
|
10
|
+
previewConfigs
|
|
11
|
+
} from "./index-fwbs6tma.js";
|
|
12
|
+
import"./index-4pfq42t5.js";
|
|
13
|
+
import"./index-35z65jsa.js";
|
|
14
|
+
import"./index-3djthcm6.js";
|
|
15
|
+
import"./index-nnwp92tk.js";
|
|
16
|
+
export {
|
|
17
|
+
previewConfigs,
|
|
18
|
+
normalizeTargetPath,
|
|
19
|
+
getConfigHome,
|
|
20
|
+
expandPath,
|
|
21
|
+
compactPathForConfigHome,
|
|
22
|
+
applyConfigsWithReport,
|
|
23
|
+
applyConfigs,
|
|
24
|
+
applyConfig
|
|
25
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
applyConfig,
|
|
4
|
+
applyConfigs,
|
|
5
|
+
applyConfigsWithReport,
|
|
6
|
+
compactPathForConfigHome,
|
|
7
|
+
expandPath,
|
|
8
|
+
getConfigHome,
|
|
9
|
+
normalizeTargetPath,
|
|
10
|
+
previewConfigs
|
|
11
|
+
} from "./index-z3ma4aqk.js";
|
|
12
|
+
import"./index-7m4j8a33.js";
|
|
13
|
+
import"./index-n3fjspr0.js";
|
|
14
|
+
import"./index-fpeyzn3n.js";
|
|
15
|
+
import"./index-bsan4c16.js";
|
|
16
|
+
export {
|
|
17
|
+
previewConfigs,
|
|
18
|
+
normalizeTargetPath,
|
|
19
|
+
getConfigHome,
|
|
20
|
+
expandPath,
|
|
21
|
+
compactPathForConfigHome,
|
|
22
|
+
applyConfigsWithReport,
|
|
23
|
+
applyConfigs,
|
|
24
|
+
applyConfig
|
|
25
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getDatabase,
|
|
4
|
+
insertFeedback,
|
|
5
|
+
resetDatabase,
|
|
6
|
+
resetLocalDatabase
|
|
7
|
+
} from "./index-5d7zdftc.js";
|
|
8
|
+
import {
|
|
9
|
+
now,
|
|
10
|
+
slugify,
|
|
11
|
+
uuid
|
|
12
|
+
} from "./index-ma2xmp6c.js";
|
|
13
|
+
import"./index-fpeyzn3n.js";
|
|
14
|
+
import"./index-bsan4c16.js";
|
|
15
|
+
export {
|
|
16
|
+
uuid,
|
|
17
|
+
slugify,
|
|
18
|
+
resetLocalDatabase,
|
|
19
|
+
resetDatabase,
|
|
20
|
+
now,
|
|
21
|
+
insertFeedback,
|
|
22
|
+
getDatabase
|
|
23
|
+
};
|