@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
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/lib/redact.ts
|
|
3
|
+
var SECRET_KEY_PATTERN = /^(.*_?API_?KEY|.*_?TOKEN|.*_?SECRET|.*_?PASSWORD|.*_?PASSWD|.*_?CREDENTIAL|.*_?AUTH(?:_TOKEN|_KEY|ORIZATION)?|.*_?PRIVATE_?KEY|.*_?ACCESS_?KEY|.*_?CLIENT_?SECRET|.*_?SIGNING_?KEY|.*_?ENCRYPTION_?KEY|.*_AUTH_TOKEN)$/i;
|
|
4
|
+
var VALUE_PATTERNS = [
|
|
5
|
+
{ re: /npm_[A-Za-z0-9]{36,}/, reason: "npm token" },
|
|
6
|
+
{ re: /gh[pousr]_[A-Za-z0-9_]{36,}/, reason: "GitHub token" },
|
|
7
|
+
{ re: /sk[-]ant-[A-Za-z0-9\-_]{40,}/, reason: "Anthropic API key" },
|
|
8
|
+
{ re: /sk-[A-Za-z0-9]{48,}/, reason: "OpenAI API key" },
|
|
9
|
+
{ re: /xoxb-[0-9]+-[A-Za-z0-9\-]+/, reason: "Slack bot token" },
|
|
10
|
+
{ re: /AIza[0-9A-Za-z\-_]{35}/, reason: "Google API key" },
|
|
11
|
+
{ re: /ey[A-Za-z0-9_\-]{20,}\.[A-Za-z0-9_\-]{20,}\./, reason: "JWT token" },
|
|
12
|
+
{ re: /AKIA[0-9A-Z]{16}/, reason: "AWS access key" }
|
|
13
|
+
];
|
|
14
|
+
var MIN_SECRET_VALUE_LEN = 8;
|
|
15
|
+
function redactShell(content) {
|
|
16
|
+
const redacted = [];
|
|
17
|
+
const lines = content.split(`
|
|
18
|
+
`);
|
|
19
|
+
const out = [];
|
|
20
|
+
for (let i = 0;i < lines.length; i++) {
|
|
21
|
+
const line = lines[i];
|
|
22
|
+
const m = line.match(/^(\s*(?:export\s+)?)([A-Z][A-Z0-9_]*)(\s*=\s*)(['"]?)(.+?)\4\s*$/);
|
|
23
|
+
if (m) {
|
|
24
|
+
const [, prefix, key, eq, quote, value] = m;
|
|
25
|
+
if (shouldRedactKeyValue(key, value)) {
|
|
26
|
+
const reason = reasonFor(key, value);
|
|
27
|
+
redacted.push({ varName: key, line: i + 1, reason });
|
|
28
|
+
out.push(`${prefix}${key}${eq}${quote}{{${key}}}${quote}`);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
out.push(line);
|
|
33
|
+
}
|
|
34
|
+
return { content: out.join(`
|
|
35
|
+
`), redacted, isTemplate: redacted.length > 0 };
|
|
36
|
+
}
|
|
37
|
+
function redactJson(content) {
|
|
38
|
+
const redacted = [];
|
|
39
|
+
const lines = content.split(`
|
|
40
|
+
`);
|
|
41
|
+
const out = [];
|
|
42
|
+
for (let i = 0;i < lines.length; i++) {
|
|
43
|
+
const line = lines[i];
|
|
44
|
+
const m = line.match(/^(\s*"([^"]+)"\s*:\s*)"([^"]+)"(,?)(\s*)$/);
|
|
45
|
+
if (m) {
|
|
46
|
+
const [, prefix, key, value, comma, trail] = m;
|
|
47
|
+
if (shouldRedactKeyValue(key, value)) {
|
|
48
|
+
const varName = key.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
49
|
+
redacted.push({ varName, line: i + 1, reason: reasonFor(key, value) });
|
|
50
|
+
out.push(`${prefix}"{{${varName}}}"${comma}${trail}`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let newLine = line;
|
|
55
|
+
for (const { re, reason } of VALUE_PATTERNS) {
|
|
56
|
+
newLine = newLine.replace(re, (match) => {
|
|
57
|
+
const varName = `REDACTED_${reason.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
|
|
58
|
+
redacted.push({ varName, line: i + 1, reason });
|
|
59
|
+
return `{{${varName}}}`;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
out.push(newLine);
|
|
63
|
+
}
|
|
64
|
+
return { content: out.join(`
|
|
65
|
+
`), redacted, isTemplate: redacted.length > 0 };
|
|
66
|
+
}
|
|
67
|
+
function redactToml(content) {
|
|
68
|
+
const redacted = [];
|
|
69
|
+
const lines = content.split(`
|
|
70
|
+
`);
|
|
71
|
+
const out = [];
|
|
72
|
+
for (let i = 0;i < lines.length; i++) {
|
|
73
|
+
const line = lines[i];
|
|
74
|
+
const m = line.match(/^(\s*)([a-zA-Z][a-zA-Z0-9_\-]*)(\s*=\s*)(['"]?)(.+?)\4\s*$/);
|
|
75
|
+
if (m) {
|
|
76
|
+
const [, indent, key, eq, quote, value] = m;
|
|
77
|
+
if (shouldRedactKeyValue(key, value)) {
|
|
78
|
+
const varName = key.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
79
|
+
redacted.push({ varName, line: i + 1, reason: reasonFor(key, value) });
|
|
80
|
+
out.push(`${indent}${key}${eq}${quote}{{${varName}}}${quote}`);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
out.push(line);
|
|
85
|
+
}
|
|
86
|
+
return { content: out.join(`
|
|
87
|
+
`), redacted, isTemplate: redacted.length > 0 };
|
|
88
|
+
}
|
|
89
|
+
function redactIni(content) {
|
|
90
|
+
const redacted = [];
|
|
91
|
+
const lines = content.split(`
|
|
92
|
+
`);
|
|
93
|
+
const out = [];
|
|
94
|
+
for (let i = 0;i < lines.length; i++) {
|
|
95
|
+
const line = lines[i];
|
|
96
|
+
const authM = line.match(/^(\/\/[^:]+:_authToken=)(.+)$/);
|
|
97
|
+
if (authM && !isReferenceValue(authM[2].trim())) {
|
|
98
|
+
redacted.push({ varName: "NPM_TOKEN", line: i + 1, reason: "npm auth token" });
|
|
99
|
+
out.push(`${authM[1]}\${NPM_TOKEN}`);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const m = line.match(/^(\s*)([a-zA-Z][a-zA-Z0-9_\-]*)(\s*=\s*)(.+?)\s*$/);
|
|
103
|
+
if (m) {
|
|
104
|
+
const [, indent, key, eq, value] = m;
|
|
105
|
+
if (shouldRedactKeyValue(key, value)) {
|
|
106
|
+
const varName = key.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
107
|
+
redacted.push({ varName, line: i + 1, reason: reasonFor(key, value) });
|
|
108
|
+
out.push(`${indent}${key}${eq}{{${varName}}}`);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
out.push(line);
|
|
113
|
+
}
|
|
114
|
+
return { content: out.join(`
|
|
115
|
+
`), redacted, isTemplate: redacted.length > 0 };
|
|
116
|
+
}
|
|
117
|
+
function redactGeneric(content) {
|
|
118
|
+
const redacted = [];
|
|
119
|
+
const lines = content.split(`
|
|
120
|
+
`);
|
|
121
|
+
const out = [];
|
|
122
|
+
for (let i = 0;i < lines.length; i++) {
|
|
123
|
+
let line = lines[i];
|
|
124
|
+
for (const { re, reason } of VALUE_PATTERNS) {
|
|
125
|
+
line = line.replace(re, (match) => {
|
|
126
|
+
const varName = reason.toUpperCase().replace(/[^A-Z0-9]/g, "_");
|
|
127
|
+
redacted.push({ varName, line: i + 1, reason });
|
|
128
|
+
return `{{${varName}}}`;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
out.push(line);
|
|
132
|
+
}
|
|
133
|
+
return { content: out.join(`
|
|
134
|
+
`), redacted, isTemplate: redacted.length > 0 };
|
|
135
|
+
}
|
|
136
|
+
function shouldRedactKeyValue(key, value) {
|
|
137
|
+
if (!value || value.startsWith("{{"))
|
|
138
|
+
return false;
|
|
139
|
+
if (isReferenceValue(value.trim()))
|
|
140
|
+
return false;
|
|
141
|
+
if (value.length < MIN_SECRET_VALUE_LEN)
|
|
142
|
+
return false;
|
|
143
|
+
if (/^(true|false|yes|no|on|off|null|undefined|\d+)$/i.test(value))
|
|
144
|
+
return false;
|
|
145
|
+
if (SECRET_KEY_PATTERN.test(key))
|
|
146
|
+
return true;
|
|
147
|
+
for (const { re } of VALUE_PATTERNS) {
|
|
148
|
+
if (re.test(value))
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
function reasonFor(key, value) {
|
|
154
|
+
if (SECRET_KEY_PATTERN.test(key))
|
|
155
|
+
return `secret key name: ${key}`;
|
|
156
|
+
for (const { re, reason } of VALUE_PATTERNS) {
|
|
157
|
+
if (re.test(value))
|
|
158
|
+
return reason;
|
|
159
|
+
}
|
|
160
|
+
return "secret value pattern";
|
|
161
|
+
}
|
|
162
|
+
function isReferenceValue(value) {
|
|
163
|
+
return /^\{\{[A-Z][A-Z0-9_]*\}\}$/.test(value) || /^\$\{[A-Z][A-Z0-9_]*\}$/.test(value) || /^\$[A-Z][A-Z0-9_]*$/.test(value) || /^%[A-Z][A-Z0-9_]*%$/.test(value);
|
|
164
|
+
}
|
|
165
|
+
function redactFormatForTarget(targetPath, storedFormat) {
|
|
166
|
+
const p = targetPath.toLowerCase();
|
|
167
|
+
if (/(^|\/)\.(zshrc|zprofile|bashrc|bash_profile|profile|zshenv|env)$/.test(p) || p.endsWith(".env"))
|
|
168
|
+
return "shell";
|
|
169
|
+
if (/(^|\/)\.(npmrc|yarnrc|curlrc|netrc)$/.test(p))
|
|
170
|
+
return "ini";
|
|
171
|
+
return storedFormat;
|
|
172
|
+
}
|
|
173
|
+
function redactContent(content, format) {
|
|
174
|
+
switch (format) {
|
|
175
|
+
case "shell":
|
|
176
|
+
return redactShell(content);
|
|
177
|
+
case "json":
|
|
178
|
+
return redactJson(content);
|
|
179
|
+
case "toml":
|
|
180
|
+
return redactToml(content);
|
|
181
|
+
case "ini":
|
|
182
|
+
return redactIni(content);
|
|
183
|
+
default:
|
|
184
|
+
return redactGeneric(content);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function scanSecrets(content, format) {
|
|
188
|
+
const r = redactContent(content, format);
|
|
189
|
+
return r.redacted;
|
|
190
|
+
}
|
|
191
|
+
function hasSecrets(content, format) {
|
|
192
|
+
return scanSecrets(content, format).length > 0;
|
|
193
|
+
}
|
|
194
|
+
function isSecretVarName(name) {
|
|
195
|
+
return SECRET_KEY_PATTERN.test(name);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export { redactFormatForTarget, redactContent, scanSecrets, hasSecrets, isSecretVarName };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/types/index.ts
|
|
3
|
+
var CONFIG_AGENTS = [
|
|
4
|
+
"claude",
|
|
5
|
+
"codex",
|
|
6
|
+
"opencode",
|
|
7
|
+
"cursor",
|
|
8
|
+
"codewith",
|
|
9
|
+
"aicopilot",
|
|
10
|
+
"antigravity",
|
|
11
|
+
"qwen",
|
|
12
|
+
"grok",
|
|
13
|
+
"copilot",
|
|
14
|
+
"devin",
|
|
15
|
+
"windsurf-legacy",
|
|
16
|
+
"cline",
|
|
17
|
+
"zsh",
|
|
18
|
+
"git",
|
|
19
|
+
"npm",
|
|
20
|
+
"global"
|
|
21
|
+
];
|
|
22
|
+
var PROFILE_CONFIG_BINDING_SCHEMA = "hasna.instructions.profile-config-binding/v1";
|
|
23
|
+
var INSTRUCTION_ACTIVATION_MODES = ["always", "glob", "model", "manual"];
|
|
24
|
+
var INSTRUCTION_FALLBACKS = ["fail", "flatten", "promote-always", "omit"];
|
|
25
|
+
var PROFILE_ASSET_BINDING_SCHEMA = "hasna.instructions.profile-asset-binding/v1";
|
|
26
|
+
var ASSET_KINDS = ["skill", "workflow", "plugin", "extension", "hook", "custom-agent"];
|
|
27
|
+
var ASSET_DESTINATION_STRATEGIES = ["emit-file", "install-local", "install-marketplace", "unsupported"];
|
|
28
|
+
var ASSET_SCOPES = ["global", "project", "session"];
|
|
29
|
+
var ASSET_UNINSTALL_POLICIES = ["remove-managed", "retain"];
|
|
30
|
+
var ASSET_ROLLBACK_POLICIES = ["snapshot", "installer-receipt", "none"];
|
|
31
|
+
class ConfigNotFoundError extends Error {
|
|
32
|
+
constructor(id) {
|
|
33
|
+
super(`Config not found: ${id}`);
|
|
34
|
+
this.name = "ConfigNotFoundError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class ProfileNotFoundError extends Error {
|
|
39
|
+
constructor(id) {
|
|
40
|
+
super(`Profile not found: ${id}`);
|
|
41
|
+
this.name = "ProfileNotFoundError";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class ConfigApplyError extends Error {
|
|
46
|
+
constructor(message) {
|
|
47
|
+
super(message);
|
|
48
|
+
this.name = "ConfigApplyError";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class TemplateRenderError extends Error {
|
|
53
|
+
constructor(message) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = "TemplateRenderError";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/lib/template.ts
|
|
60
|
+
var VAR_PATTERN = /\{\{([A-Z0-9_]+)(?::([^}]*))?\}\}/g;
|
|
61
|
+
function parseTemplateVars(content) {
|
|
62
|
+
const names = new Set;
|
|
63
|
+
let match;
|
|
64
|
+
VAR_PATTERN.lastIndex = 0;
|
|
65
|
+
while ((match = VAR_PATTERN.exec(content)) !== null) {
|
|
66
|
+
names.add(match[1]);
|
|
67
|
+
}
|
|
68
|
+
return Array.from(names);
|
|
69
|
+
}
|
|
70
|
+
function extractTemplateVars(content) {
|
|
71
|
+
const vars = new Map;
|
|
72
|
+
let match;
|
|
73
|
+
VAR_PATTERN.lastIndex = 0;
|
|
74
|
+
while ((match = VAR_PATTERN.exec(content)) !== null) {
|
|
75
|
+
const name = match[1];
|
|
76
|
+
const description = match[2] ?? null;
|
|
77
|
+
if (!vars.has(name)) {
|
|
78
|
+
vars.set(name, { name, description, required: true });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return Array.from(vars.values());
|
|
82
|
+
}
|
|
83
|
+
function renderTemplate(content, vars) {
|
|
84
|
+
const missing = [];
|
|
85
|
+
VAR_PATTERN.lastIndex = 0;
|
|
86
|
+
let match;
|
|
87
|
+
while ((match = VAR_PATTERN.exec(content)) !== null) {
|
|
88
|
+
const name = match[1];
|
|
89
|
+
if (!(name in vars))
|
|
90
|
+
missing.push(name);
|
|
91
|
+
}
|
|
92
|
+
if (missing.length > 0) {
|
|
93
|
+
throw new TemplateRenderError(`Missing required template variables: ${missing.join(", ")}`);
|
|
94
|
+
}
|
|
95
|
+
VAR_PATTERN.lastIndex = 0;
|
|
96
|
+
return content.replace(VAR_PATTERN, (_match, name) => vars[name] ?? "");
|
|
97
|
+
}
|
|
98
|
+
function renderTemplatePreview(content, vars) {
|
|
99
|
+
const unresolved = new Set;
|
|
100
|
+
VAR_PATTERN.lastIndex = 0;
|
|
101
|
+
const rendered = content.replace(VAR_PATTERN, (match, name) => {
|
|
102
|
+
if (name in vars)
|
|
103
|
+
return vars[name] ?? "";
|
|
104
|
+
unresolved.add(name);
|
|
105
|
+
return match;
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
content: rendered,
|
|
109
|
+
unresolved: [...unresolved].sort()
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function isTemplate(content) {
|
|
113
|
+
VAR_PATTERN.lastIndex = 0;
|
|
114
|
+
return VAR_PATTERN.test(content);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export { CONFIG_AGENTS, PROFILE_CONFIG_BINDING_SCHEMA, INSTRUCTION_ACTIVATION_MODES, INSTRUCTION_FALLBACKS, PROFILE_ASSET_BINDING_SCHEMA, ASSET_KINDS, ASSET_DESTINATION_STRATEGIES, ASSET_SCOPES, ASSET_UNINSTALL_POLICIES, ASSET_ROLLBACK_POLICIES, ConfigNotFoundError, ProfileNotFoundError, ConfigApplyError, parseTemplateVars, extractTemplateVars, renderTemplate, renderTemplatePreview, isTemplate };
|