@muthuishere/vsync 0.3.1 → 0.5.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.
- package/README.md +124 -66
- package/bin/audit.ts +73 -0
- package/bin/export.ts +52 -2
- package/bin/import.ts +52 -2
- package/bin/init.ts +26 -0
- package/bin/pull.ts +56 -1
- package/bin/push.ts +56 -1
- package/bin/use.ts +175 -0
- package/bin/vsync.ts +19 -0
- package/package.json +7 -3
- package/src/argv.ts +15 -3
- package/src/audit.ts +752 -0
- package/src/repoconfig.ts +19 -0
- package/src/templates/docs.md.ts +27 -0
package/src/repoconfig.ts
CHANGED
|
@@ -33,8 +33,15 @@ export type ConfigFile = {
|
|
|
33
33
|
gh?: { repo: string };
|
|
34
34
|
gcp?: { project: string };
|
|
35
35
|
};
|
|
36
|
+
// Optional audit-log block. Absent on disk → defaults to `{ enabled: true }`
|
|
37
|
+
// (audit is on by default — see SPEC-v0.4 §9). Explicit `{ enabled: false }`
|
|
38
|
+
// round-trips through save/load unchanged.
|
|
39
|
+
audit?: { enabled: boolean };
|
|
36
40
|
};
|
|
37
41
|
|
|
42
|
+
/** Per-(repo, env) audit preference, defaulted. Source of truth for callers. */
|
|
43
|
+
export const DEFAULT_AUDIT_ENABLED = true;
|
|
44
|
+
|
|
38
45
|
/** Full path for a given (repo, env). env is lowercased; repo is taken as-is. */
|
|
39
46
|
export function configFilePath(repo: string, env: string): string {
|
|
40
47
|
if (!repo) throw new Error("repo is required");
|
|
@@ -95,6 +102,10 @@ export async function loadConfigFile(
|
|
|
95
102
|
const json = gunzipSync(buf).toString("utf8");
|
|
96
103
|
const parsed = JSON.parse(json);
|
|
97
104
|
validateConfigFile(parsed);
|
|
105
|
+
// Default-on for `audit` — absent block means "enabled" per spec §9.
|
|
106
|
+
if (parsed.audit === undefined) {
|
|
107
|
+
parsed.audit = { enabled: DEFAULT_AUDIT_ENABLED };
|
|
108
|
+
}
|
|
98
109
|
return parsed;
|
|
99
110
|
}
|
|
100
111
|
|
|
@@ -160,4 +171,12 @@ export function validateConfigFile(cfg: unknown): asserts cfg is ConfigFile {
|
|
|
160
171
|
throw new Error("config: sync.gcp.project must be a string if sync.gcp is present");
|
|
161
172
|
}
|
|
162
173
|
}
|
|
174
|
+
if (c.audit !== undefined) {
|
|
175
|
+
if (typeof c.audit !== "object" || c.audit === null) {
|
|
176
|
+
throw new Error("config: audit must be an object if present");
|
|
177
|
+
}
|
|
178
|
+
if (typeof c.audit.enabled !== "boolean") {
|
|
179
|
+
throw new Error("config: audit.enabled must be a boolean");
|
|
180
|
+
}
|
|
181
|
+
}
|
|
163
182
|
}
|
package/src/templates/docs.md.ts
CHANGED
|
@@ -73,6 +73,33 @@ plus the salt from the per-repo config. To decrypt by hand:
|
|
|
73
73
|
|
|
74
74
|
Easier: just \`vsync pull\` again to restore from S3.
|
|
75
75
|
|
|
76
|
+
## Audit log
|
|
77
|
+
|
|
78
|
+
Every \`pull\`, \`push\`, \`import\`, and \`export\` appends a CSV row to
|
|
79
|
+
\`s3://<bucket>/<repo>/<env>/audit.csv\` capturing timestamp, action,
|
|
80
|
+
hostname, local IP, OS user, git email, and a free-form \`meta\` JSON
|
|
81
|
+
cell. Best-effort: an audit-write failure prints a warning and never
|
|
82
|
+
fails the parent command.
|
|
83
|
+
|
|
84
|
+
On by default. Three ways to opt out:
|
|
85
|
+
|
|
86
|
+
- \`--no-audit\` on a single invocation
|
|
87
|
+
- \`cfg.audit.enabled: false\` in the per-repo config
|
|
88
|
+
- \`vsync init <env> --audit=off\` at setup (or pick "off" at the first-time prompt)
|
|
89
|
+
|
|
90
|
+
Tag a row with context via four merging input paths, in increasing
|
|
91
|
+
priority order: \`$VSYNC_AUDIT_META\` (JSON) < \`$VSYNC_AUDIT_NOTE\` <
|
|
92
|
+
\`--meta key=value\` (repeatable) < \`--note=<text>\`. Later sources
|
|
93
|
+
overwrite same-named keys from earlier ones.
|
|
94
|
+
|
|
95
|
+
View the log with \`vsync audit <env>\` (\`--limit=N\`, \`--all\`, \`--csv\`).
|
|
96
|
+
Pretty table by default, newest first; \`--csv\` is raw passthrough.
|
|
97
|
+
|
|
98
|
+
Honesty clause: transparency for honest users, not tamper-proof
|
|
99
|
+
(anyone with bucket write can rewrite the file). It can't recover
|
|
100
|
+
already-pulled secrets either — once a teammate has pulled, they hold
|
|
101
|
+
a local copy.
|
|
102
|
+
|
|
76
103
|
## Rules for AI agents working in this repo
|
|
77
104
|
|
|
78
105
|
1. **Never commit anything under \`infra/vault/\`.** Add it to
|