@event4u/agent-config 3.0.0 → 3.1.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/.agent-src/commands/install-via-agent.md +129 -0
- package/.agent-src/commands/video/from-script.md +1 -1
- package/.agent-src/commands/video.md +1 -1
- package/.agent-src/contexts/execution/cheap-question-mechanics.md +81 -0
- package/.agent-src/rules/caveman-speak.md +2 -2
- package/.agent-src/rules/context-hygiene.md +36 -0
- package/.agent-src/rules/engineering-safety-floor.md +102 -0
- package/.agent-src/rules/finance-safety-floor.md +114 -0
- package/.agent-src/rules/git-history-discipline.md +1 -1
- package/.agent-src/rules/no-cheap-questions.md +34 -32
- package/.agent-src/rules/provider-lifecycle-discipline.md +4 -4
- package/.agent-src/rules/strategy-safety-floor.md +114 -0
- package/.agent-src/skills/agents-md-thin-root/SKILL.md +15 -9
- package/.agent-src/skills/async-python-patterns/SKILL.md +1 -1
- package/.agent-src/skills/project-analysis-node-express/SKILL.md +1 -1
- package/.agent-src/skills/readme-reviewer/SKILL.md +52 -3
- package/.agent-src/skills/readme-writing/SKILL.md +52 -4
- package/.agent-src/skills/readme-writing-package/SKILL.md +48 -5
- package/.agent-src/skills/systematic-debugging/SKILL.md +41 -0
- package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/.agent-src/templates/hooks/pre-commit-frontmatter +66 -0
- package/.agent-src/templates/hooks/pre-commit-roadmap-progress +78 -39
- package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +4 -1
- package/.agent-src/templates/scripts/work_engine/orchestration.py +25 -11
- package/.claude-plugin/marketplace.json +2 -1
- package/AGENTS.md +10 -8
- package/CHANGELOG.md +233 -123
- package/README.md +165 -553
- package/config/agent-settings.template.yml +0 -7
- package/config/discovery/packs.yml +20 -0
- package/config/discovery/unassigned-artefacts.yml +2 -0
- package/config/gitignore-block.txt +19 -3
- package/dist/cli/commands/uiServe.js +13 -4
- package/dist/cli/commands/uiServe.js.map +1 -1
- package/dist/cli/registry.js +2 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/discovery/deprecation-report.md +7 -0
- package/dist/discovery/discovery-manifest.json +2107 -1409
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +9 -9
- package/dist/discovery/orphan-report.md +10 -0
- package/dist/discovery/packs.json +1002 -0
- package/dist/discovery/trust-report.md +26 -0
- package/dist/discovery/workspaces.json +705 -0
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +1623 -0
- package/dist/server/app.js +11 -3
- package/dist/server/app.js.map +1 -1
- package/dist/server/io/atomicMultiWrite.js +3 -1
- package/dist/server/io/atomicMultiWrite.js.map +1 -1
- package/dist/server/io/yamlIO.js +22 -0
- package/dist/server/io/yamlIO.js.map +1 -1
- package/dist/server/routes/ping.js +8 -0
- package/dist/server/routes/ping.js.map +1 -1
- package/dist/server/routes/schema.js +2 -2
- package/dist/server/routes/schema.js.map +1 -1
- package/dist/server/routes/settings.js +104 -23
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/userMd.js +37 -27
- package/dist/server/routes/userMd.js.map +1 -1
- package/dist/server/routes/wizard.js +256 -20
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/schemas/settings.js +0 -1
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/server/token.js +10 -3
- package/dist/server/token.js.map +1 -1
- package/dist/server/writeRoot.js +28 -11
- package/dist/server/writeRoot.js.map +1 -1
- package/dist/server/writeRoot.test.js +22 -4
- package/dist/server/writeRoot.test.js.map +1 -1
- package/dist/shared/userMd/formAdapter.js +29 -51
- package/dist/shared/userMd/formAdapter.js.map +1 -1
- package/dist/shared/userMd/schema.js +32 -104
- package/dist/shared/userMd/schema.js.map +1 -1
- package/dist/shared/userMd/utils.js +64 -50
- package/dist/shared/userMd/utils.js.map +1 -1
- package/dist/ui/assets/index-D-DY1ywI.js +35 -0
- package/dist/ui/assets/index-D-DY1ywI.js.map +1 -0
- package/dist/ui/index.html +1 -1
- package/docs/adrs/router/0001-three-tier-routing.md +5 -5
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +1 -1
- package/docs/architecture.md +3 -3
- package/docs/archive/CHANGELOG-pre-3.1.0.md +167 -0
- package/docs/catalog.md +30 -26
- package/docs/contracts/CHANGELOG-conventions.md +1 -1
- package/docs/contracts/agent-user-schema.md +6 -9
- package/docs/contracts/consumer-bridge.md +79 -0
- package/docs/contracts/discovery-manifest.md +209 -0
- package/docs/contracts/discovery-manifest.schema.json +77 -4
- package/docs/contracts/explain-trace.schema.json +1 -1
- package/docs/contracts/file-ownership-matrix.json +197 -13
- package/docs/contracts/frontmatter-contract.md +140 -0
- package/docs/contracts/gui-wizard.md +223 -0
- package/docs/contracts/installer-agent-mode.md +137 -0
- package/docs/contracts/kernel-membership.md +1 -1
- package/docs/contracts/mcp-tool-inventory.md +9 -9
- package/docs/contracts/namespace.md +6 -6
- package/docs/contracts/provider-lifecycle.md +5 -5
- package/docs/contracts/rule-router.md +4 -4
- package/docs/contracts/settings-api.md +53 -6
- package/docs/contracts/smoke-contracts.md +3 -3
- package/docs/contracts/trust-and-safety.md +144 -0
- package/docs/customization.md +2 -2
- package/docs/decisions/ADR-007-agent-discovery-scopes.md +12 -0
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +24 -0
- package/docs/decisions/ADR-015-discovery-manifest-contract.md +146 -0
- package/docs/decisions/ADR-016-installer-architecture.md +189 -0
- package/docs/decisions/ADR-017-monorepo-physical-layout.md +261 -0
- package/docs/decisions/ADR-018-trust-and-safety-layer.md +159 -0
- package/docs/decisions/ADR-019-router-json-dist-location.md +124 -0
- package/docs/decisions/ADR-020-global-only-consumer-scope.md +123 -0
- package/docs/decisions/ADR-021-deployment-shape.md +153 -0
- package/docs/decisions/INDEX.md +7 -0
- package/docs/deploy/connector-setup.md +129 -0
- package/docs/deploy/env-vars.md +70 -0
- package/docs/deploy/policy-cookbook.md +130 -0
- package/docs/deploy/quickstart.md +112 -0
- package/docs/distribution/public-install-smoke.md +68 -0
- package/docs/distribution/registries.md +55 -0
- package/docs/distribution/telemetry-privacy.md +128 -0
- package/docs/distribution/telemetry-schema.md +174 -0
- package/docs/featured-skills.md +95 -0
- package/docs/getting-started-by-role.md +19 -1
- package/docs/getting-started.md +2 -2
- package/docs/guidelines/agent-infra/installed-tools-manifest.md +11 -8
- package/docs/guidelines/docs/readme-size-and-splitting.md +53 -1
- package/docs/installation.md +27 -14
- package/docs/maintainers/dev-mode.md +105 -0
- package/docs/setup/per-ide/claude-desktop.md +3 -2
- package/docs/wizard.md +39 -4
- package/package.json +18 -1
- package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/scripts/_cli/cmd_doctor.py +150 -2
- package/scripts/_cli/cmd_explain.py +2 -1
- package/scripts/_cli/cmd_migrate_to_global.py +415 -0
- package/scripts/_cli/cmd_settings_migrate.py +146 -0
- package/scripts/_cli/explain_last/route.py +2 -1
- package/scripts/_dispatch.bash +36 -3
- package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/scripts/_lib/agent_settings.py +4 -1
- package/scripts/_lib/agent_src.py +157 -0
- package/scripts/agent-config +17 -6
- package/scripts/audit_skill_descriptions.py +18 -6
- package/scripts/build_discovery_manifest.py +373 -17
- package/scripts/check_artefact_checksums.py +104 -0
- package/scripts/check_cluster_patterns.py +20 -4
- package/scripts/check_command_count_messaging.py +33 -14
- package/scripts/check_council_references.py +43 -4
- package/scripts/check_overlay_cascade_subdirs.py +7 -3
- package/scripts/check_references.py +5 -2
- package/scripts/check_reply_consistency.py +32 -9
- package/scripts/check_template_pin_drift.py +24 -7
- package/scripts/check_token_optimizer_freshness.py +18 -3
- package/scripts/compile_router.py +34 -2
- package/scripts/compress.py +162 -44
- package/scripts/config/presets.py +19 -1
- package/scripts/config/profiles.py +16 -1
- package/scripts/discovery_stats.py +70 -0
- package/scripts/expected_perms.json +47 -0
- package/scripts/generate_index.py +78 -46
- package/scripts/generate_ownership_matrix.py +98 -43
- package/scripts/generate_pack_manifests.py +183 -0
- package/scripts/install +18 -1
- package/scripts/install.py +934 -59
- package/scripts/install.sh +27 -9
- package/scripts/lint_agents_layout.py +93 -13
- package/scripts/lint_agents_md.py +1 -1
- package/scripts/lint_archived_skills.py +32 -16
- package/scripts/lint_bench_corpus.py +14 -2
- package/scripts/lint_command_tiers.py +15 -2
- package/scripts/lint_featured_skills.py +139 -0
- package/scripts/lint_framework_leakage.py +33 -6
- package/scripts/lint_global_paths.py +147 -0
- package/scripts/lint_orchestration_dsl.py +6 -3
- package/scripts/lint_pack_boundaries.py +147 -0
- package/scripts/lint_pack_first_win.py +103 -0
- package/scripts/lint_readme_jargon.py +131 -0
- package/scripts/lint_readme_size.py +33 -0
- package/scripts/lint_rule_interactions.py +23 -5
- package/scripts/lint_rule_tiers.py +12 -3
- package/scripts/lint_trust_coherence.py +212 -0
- package/scripts/measure_rule_budget.py +22 -4
- package/scripts/move_artefact.py +143 -0
- package/scripts/new_skill.py +148 -0
- package/scripts/plan_physical_move.py +353 -0
- package/scripts/refine_ticket_detect.py +30 -7
- package/scripts/release.py +22 -2
- package/scripts/schemas/command.schema.json +4 -0
- package/scripts/skill_linter.py +248 -118
- package/scripts/skill_trigger_eval.py +28 -8
- package/scripts/smoke/kernel.sh +1 -1
- package/scripts/smoke/router.sh +24 -5
- package/scripts/smoke/skills.sh +15 -7
- package/scripts/smoke_quickstart.py +11 -2
- package/scripts/snapshot_agent_outputs.py +144 -0
- package/scripts/update_counts.py +45 -17
- package/scripts/validate_decision_engine.py +9 -1
- package/scripts/validate_discovery_manifest.py +94 -0
- package/scripts/validate_frontmatter.py +39 -20
- package/scripts/verify_physical_move.py +185 -0
- package/templates/agent-user.md +0 -1
- package/templates/agent-user.yml +21 -0
- package/templates/minimal/agents-overrides-readme.md +46 -0
- package/templates/minimal/overrides-gitkeep +2 -0
- package/dist/ui/assets/index-BTRcKDlB.js +0 -39
- package/dist/ui/assets/index-BTRcKDlB.js.map +0 -1
- package/templates/minimal/agents-gitkeep +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeRoot.test.js","sourceRoot":"","sources":["../../src/server/writeRoot.test.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"writeRoot.test.js","sourceRoot":"","sources":["../../src/server/writeRoot.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Form adapter for `.agent-user.
|
|
2
|
+
* Form adapter for `.agent-user.yml`.
|
|
3
3
|
*
|
|
4
|
-
* Bridges the
|
|
5
|
-
* the structured UserMdForm value. Lives under `src/shared/` so
|
|
6
|
-
* server and
|
|
7
|
-
*
|
|
4
|
+
* Bridges the parsed-YAML object (signal in WizardPage / UserMdPanel)
|
|
5
|
+
* and the structured UserMdForm value. Lives under `src/shared/` so
|
|
6
|
+
* server and UI round-trip identically; ESLint forbids Node imports in
|
|
7
|
+
* this tree.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* the user tries to finish with them blank.
|
|
9
|
+
* Defaults mirror `templates/agent-user.yml` so a fresh form is fully
|
|
10
|
+
* renderable (every field has *something*), while keeping `name`,
|
|
11
|
+
* `role[0]`, and `voice_sample` empty — the wizard surfaces those as
|
|
12
|
+
* 422 issues when the user tries to finish with them blank.
|
|
14
13
|
*
|
|
15
|
-
* Round-trip discipline:
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* Round-trip discipline: the form value **is** the identity object
|
|
15
|
+
* (post-migration to pure YAML). `mergeIdentity` is the soft merge used
|
|
16
|
+
* when reading a partial or legacy file; validation runs server-side on
|
|
17
|
+
* save via `userIdentitySchema`.
|
|
19
18
|
*/
|
|
20
|
-
import { parseUserMd, composeUserMd } from './utils.js';
|
|
21
19
|
/**
|
|
22
|
-
* Defaults for a fresh form. Matches `templates/agent-user.
|
|
20
|
+
* Defaults for a fresh form. Matches `templates/agent-user.yml`:
|
|
23
21
|
* `last_updated` is 1970-01-01 so any user-driven edit visibly bumps it.
|
|
24
22
|
*/
|
|
25
|
-
export function
|
|
23
|
+
export function defaultIdentity() {
|
|
26
24
|
return {
|
|
27
25
|
version: 1,
|
|
28
26
|
identity: { name: '' },
|
|
@@ -51,24 +49,24 @@ function pickRoles(value) {
|
|
|
51
49
|
const filtered = value.filter((v) => typeof v === 'string');
|
|
52
50
|
return filtered.length === 0 ? [''] : filtered;
|
|
53
51
|
}
|
|
52
|
+
function pickNotes(value) {
|
|
53
|
+
if (typeof value !== 'string')
|
|
54
|
+
return undefined;
|
|
55
|
+
return value === '' ? undefined : value;
|
|
56
|
+
}
|
|
54
57
|
/**
|
|
55
|
-
* Merge parsed
|
|
58
|
+
* Merge a parsed YAML object over defaults field-by-field. Malformed or
|
|
56
59
|
* missing entries fall through to the default so the form always has a
|
|
57
60
|
* complete shape to render — validation runs server-side on save.
|
|
58
61
|
*/
|
|
59
|
-
export function
|
|
60
|
-
const def =
|
|
62
|
+
export function mergeIdentity(parsed) {
|
|
63
|
+
const def = defaultIdentity();
|
|
61
64
|
const identityRaw = isObject(parsed.identity) ? parsed.identity : {};
|
|
62
65
|
const styleRaw = isObject(parsed.style) ? parsed.style : {};
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
};
|
|
66
|
-
const nickname = identityRaw.nickname;
|
|
67
|
-
if (typeof nickname === 'string' && nickname !== '')
|
|
68
|
-
identity.nickname = nickname;
|
|
69
|
-
return {
|
|
66
|
+
const notes = pickNotes(parsed.notes);
|
|
67
|
+
const out = {
|
|
70
68
|
version: 1,
|
|
71
|
-
identity,
|
|
69
|
+
identity: { name: pickString(identityRaw.name, def.identity.name) },
|
|
72
70
|
language: pickString(parsed.language, def.language),
|
|
73
71
|
role: pickRoles(parsed.role),
|
|
74
72
|
style: {
|
|
@@ -78,28 +76,8 @@ export function mergeFrontmatter(parsed) {
|
|
|
78
76
|
voice_sample: pickString(parsed.voice_sample, def.voice_sample),
|
|
79
77
|
last_updated: pickString(parsed.last_updated, def.last_updated),
|
|
80
78
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
* or frontmatter-less bodies produce defaults; the markdown content is
|
|
85
|
-
* preserved verbatim so a manually edited file round-trips cleanly when
|
|
86
|
-
* the user clicks Save without touching the form.
|
|
87
|
-
*/
|
|
88
|
-
export function bodyToForm(body) {
|
|
89
|
-
const parsed = parseUserMd(body);
|
|
90
|
-
return {
|
|
91
|
-
frontmatter: mergeFrontmatter(parsed.data),
|
|
92
|
-
content: parsed.content,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Compose a structured form value back into a markdown body. The result
|
|
97
|
-
* always carries block-style frontmatter per the contract.
|
|
98
|
-
*/
|
|
99
|
-
export function formToBody(value) {
|
|
100
|
-
return composeUserMd({
|
|
101
|
-
data: value.frontmatter,
|
|
102
|
-
content: value.content,
|
|
103
|
-
});
|
|
79
|
+
if (notes !== undefined)
|
|
80
|
+
out.notes = notes;
|
|
81
|
+
return out;
|
|
104
82
|
}
|
|
105
83
|
//# sourceMappingURL=formAdapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formAdapter.js","sourceRoot":"","sources":["../../../src/shared/userMd/formAdapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"formAdapter.js","sourceRoot":"","sources":["../../../src/shared/userMd/formAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,118 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Schema for `.agent-user.yml` (the user-identity file).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* agent
|
|
4
|
+
* Pure YAML — no fenced-frontmatter wrapper. The wizard, the server
|
|
5
|
+
* routes, and the on-disk file all carry the same shape: a single
|
|
6
|
+
* object that round-trips through `js-yaml`. See
|
|
7
|
+
* `docs/contracts/agent-user-schema.md` for the canonical reference.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* then validates the parsed frontmatter against the v1 contract
|
|
13
|
-
* (`docs/contracts/agent-user-schema.md`). Errors surface as Zod
|
|
14
|
-
* issues with the underlying message; the route returns HTTP 422.
|
|
15
|
-
*
|
|
16
|
-
* Strictness (A4 · 2026-05-19): the schema enforces the locked v1
|
|
17
|
-
* frontmatter — `version`, `identity.name`, `language`, `role[≥1]`,
|
|
18
|
-
* `style.formality`, `style.pace`, `voice_sample`, `last_updated`. Plain
|
|
19
|
-
* markdown without frontmatter is rejected; the wizard cannot finish on a
|
|
20
|
-
* partial body.
|
|
21
|
-
*
|
|
22
|
-
* Hard length cap kept at 8 000 chars (form input cap, not security).
|
|
9
|
+
* Lives under `src/shared/` so the Fastify server (request validation,
|
|
10
|
+
* wizard finish) and the Vite-bundled UI (form validation) consume
|
|
11
|
+
* the same Zod schema. ESLint forbids Node-only imports in this tree.
|
|
23
12
|
*/
|
|
24
13
|
import { z } from 'zod';
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
export const SEED_ROLE_IDS = [
|
|
36
|
-
'founder',
|
|
37
|
-
'developer',
|
|
38
|
-
'content_creator',
|
|
39
|
-
'agency',
|
|
40
|
-
'finance',
|
|
41
|
-
'ops',
|
|
42
|
-
];
|
|
43
|
-
/** `YYYY-MM-DD` — agent bumps `last_updated` on every accept. */
|
|
44
|
-
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
45
|
-
/** BCP-47-ish: lowercase primary tag, optional region. "de", "en", "en-US". */
|
|
46
|
-
const LANGUAGE_TAG = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})?$/;
|
|
47
|
-
/**
|
|
48
|
-
* Strict v1 frontmatter shape. Exported for the wizard UI form and for
|
|
49
|
-
* direct unit tests; the route-level schema (`userMdSchema` below) parses
|
|
50
|
-
* a body string and feeds the result through this.
|
|
51
|
-
*/
|
|
52
|
-
export const frontmatterSchema = z.object({
|
|
53
|
-
version: z.literal(1, { errorMap: () => ({ message: 'version must be 1' }) }),
|
|
14
|
+
/** Hard cap on the optional `notes` block. Keeps the file loadable into every reply. */
|
|
15
|
+
export const USER_IDENTITY_NOTES_MAX_CHARS = 8_000;
|
|
16
|
+
/** Hard cap on the `voice_sample` block — one to three sentences in practice. */
|
|
17
|
+
export const USER_IDENTITY_VOICE_SAMPLE_MAX_CHARS = 2_000;
|
|
18
|
+
/** ISO-8601 date (`YYYY-MM-DD`) — `last_updated` is a date, not a timestamp. */
|
|
19
|
+
const isoDate = z
|
|
20
|
+
.string()
|
|
21
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, 'last_updated must be ISO-8601 date (YYYY-MM-DD)');
|
|
22
|
+
export const userIdentitySchema = z.object({
|
|
23
|
+
version: z.literal(1),
|
|
54
24
|
identity: z.object({
|
|
55
|
-
name: z.string().min(1, 'identity.name is required'),
|
|
56
|
-
nickname: z.string().min(1).optional(),
|
|
25
|
+
name: z.string().trim().min(1, 'identity.name is required'),
|
|
57
26
|
}),
|
|
58
|
-
language: z
|
|
59
|
-
.string()
|
|
60
|
-
.regex(LANGUAGE_TAG, 'language must be a BCP-47 tag (e.g. "de", "en", "en-US")'),
|
|
27
|
+
language: z.string().trim().min(2, 'language must be a non-empty code'),
|
|
61
28
|
role: z
|
|
62
|
-
.array(z.string().min(1, 'role entries must be non-empty'))
|
|
29
|
+
.array(z.string().trim().min(1, 'role entries must be non-empty'))
|
|
63
30
|
.min(1, 'role must list at least one entry'),
|
|
64
31
|
style: z.object({
|
|
65
|
-
formality: z.enum(['informal', 'formal'],
|
|
66
|
-
|
|
67
|
-
}),
|
|
68
|
-
pace: z.enum(['pragmatic', 'thorough', 'rapid'], {
|
|
69
|
-
errorMap: () => ({ message: 'style.pace must be "pragmatic", "thorough", or "rapid"' }),
|
|
70
|
-
}),
|
|
32
|
+
formality: z.enum(['informal', 'formal']),
|
|
33
|
+
pace: z.enum(['rapid', 'pragmatic', 'thorough']),
|
|
71
34
|
}),
|
|
72
|
-
voice_sample: z
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// fence is present; the contract requires v1 frontmatter, so
|
|
80
|
-
// empty objects fall through to `frontmatterSchema` and fail
|
|
81
|
-
// there with the missing-required-field issues the wizard
|
|
82
|
-
// wants to surface.
|
|
83
|
-
return { ok: true, data: result.data };
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
const message = err instanceof Error ? err.message : 'frontmatter parse failed';
|
|
87
|
-
return { ok: false, message };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
export const userMdSchema = z.object({
|
|
91
|
-
body: z
|
|
35
|
+
voice_sample: z
|
|
36
|
+
.string()
|
|
37
|
+
.trim()
|
|
38
|
+
.min(1, 'voice_sample is required')
|
|
39
|
+
.max(USER_IDENTITY_VOICE_SAMPLE_MAX_CHARS, 'voice_sample exceeds hard cap'),
|
|
40
|
+
last_updated: isoDate,
|
|
41
|
+
notes: z
|
|
92
42
|
.string()
|
|
93
|
-
.max(
|
|
94
|
-
.
|
|
95
|
-
const parsed = tryParse(value);
|
|
96
|
-
if (!parsed.ok) {
|
|
97
|
-
ctx.addIssue({
|
|
98
|
-
code: z.ZodIssueCode.custom,
|
|
99
|
-
message: `.agent-user.md frontmatter invalid: ${parsed.message}`,
|
|
100
|
-
path: ['body'],
|
|
101
|
-
});
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
const shape = frontmatterSchema.safeParse(parsed.data);
|
|
105
|
-
if (shape.success)
|
|
106
|
-
return;
|
|
107
|
-
for (const issue of shape.error.issues) {
|
|
108
|
-
ctx.addIssue({
|
|
109
|
-
code: z.ZodIssueCode.custom,
|
|
110
|
-
message: issue.message,
|
|
111
|
-
path: ['body', ...issue.path],
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
.describe('Markdown body with v1 frontmatter per agent-user-schema contract.'),
|
|
43
|
+
.max(USER_IDENTITY_NOTES_MAX_CHARS, 'notes exceeds hard cap')
|
|
44
|
+
.optional(),
|
|
116
45
|
});
|
|
117
|
-
export const USER_MD_MAX_CHARS = MAX_BODY_CHARS;
|
|
118
46
|
//# sourceMappingURL=schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/shared/userMd/schema.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/shared/userMd/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wFAAwF;AACxF,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;AAEnD,iFAAiF;AACjF,MAAM,CAAC,MAAM,oCAAoC,GAAG,KAAK,CAAC;AAE1D,gFAAgF;AAChF,MAAM,OAAO,GAAG,CAAC;KACZ,MAAM,EAAE;KACR,KAAK,CAAC,qBAAqB,EAAE,iDAAiD,CAAC,CAAC;AAErF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,2BAA2B,CAAC;KAC9D,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mCAAmC,CAAC;IACvE,IAAI,EAAE,CAAC;SACF,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,gCAAgC,CAAC,CAAC;SACjE,GAAG,CAAC,CAAC,EAAE,mCAAmC,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACZ,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;KACnD,CAAC;IACF,YAAY,EAAE,CAAC;SACV,MAAM,EAAE;SACR,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,EAAE,0BAA0B,CAAC;SAClC,GAAG,CAAC,oCAAoC,EAAE,+BAA+B,CAAC;IAC/E,YAAY,EAAE,OAAO;IACrB,KAAK,EAAE,CAAC;SACH,MAAM,EAAE;SACR,GAAG,CAAC,6BAA6B,EAAE,wBAAwB,CAAC;SAC5D,QAAQ,EAAE;CAClB,CAAC,CAAC"}
|
|
@@ -1,74 +1,88 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pure parse / compose helpers for `.agent-user.
|
|
2
|
+
* Pure parse / compose helpers for `.agent-user.yml`.
|
|
3
3
|
*
|
|
4
4
|
* Shared between the Fastify server (route validation, wizard finish) and
|
|
5
|
-
* the Vite-bundled UI (round-trip between structured form and
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
* `crypto`, `process`, …) — ESLint enforces it.
|
|
5
|
+
* the Vite-bundled UI (round-trip between structured form and YAML text).
|
|
6
|
+
* Lives under `src/shared/` and MUST stay free of Node-only APIs
|
|
7
|
+
* (`fs`, `path`, `crypto`, `process`, …) — ESLint enforces it.
|
|
9
8
|
*
|
|
10
|
-
* Parser choice:
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* is not defined`, which silently broke the wizard's userMd step.)
|
|
9
|
+
* Parser choice: `js-yaml`. Pure JS, no `Buffer` / `process` dependency,
|
|
10
|
+
* bundles cleanly into the Vite UI output. (An earlier `gray-matter`
|
|
11
|
+
* attempt crashed in the browser with `ReferenceError: Buffer is not
|
|
12
|
+
* defined`, which silently broke the wizard's userMd step.)
|
|
15
13
|
*
|
|
16
14
|
* Compose choice: `yaml.dump` with `flowLevel: -1` emits **block style**
|
|
17
15
|
* at every depth. Block-style is required by the schema contract
|
|
18
|
-
* (`docs/contracts/agent-user-schema.md`): `
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* (`docs/contracts/agent-user-schema.md`): `role` and other list-valued
|
|
17
|
+
* fields produce clean, line-oriented git diffs that way; flow style
|
|
18
|
+
* (`role: [a, b]`) is allowed by the parser but rejected by the contract.
|
|
19
|
+
*
|
|
20
|
+
* Legacy bridge: `parseLegacyUserMd` accepts the old fenced-frontmatter
|
|
21
|
+
* `.agent-user.md` body and returns the same shape as `parseUserIdentity`
|
|
22
|
+
* so the server can read pre-migration files during the wizard finish.
|
|
23
|
+
* Drop once no consumer ships the legacy file.
|
|
22
24
|
*/
|
|
23
25
|
import yaml from 'js-yaml';
|
|
26
|
+
/** Frontmatter fence used by the legacy `.agent-user.md` format. */
|
|
27
|
+
const FRONTMATTER_FENCE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
24
28
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
29
|
+
* Parse a `.agent-user.yml` body into a plain object. Throws on
|
|
30
|
+
* malformed YAML — callers that need a soft failure (HTTP 422 in
|
|
31
|
+
* routes, form-level error in the UI) should pre-validate via
|
|
32
|
+
* `userIdentitySchema` in `./schema.ts`. An empty / whitespace-only
|
|
33
|
+
* body parses to `{}` so callers can layer defaults on top.
|
|
28
34
|
*/
|
|
29
|
-
|
|
35
|
+
export function parseUserIdentity(body) {
|
|
36
|
+
const trimmed = body.trim();
|
|
37
|
+
if (trimmed === '')
|
|
38
|
+
return {};
|
|
39
|
+
const loaded = yaml.load(body);
|
|
40
|
+
if (loaded === null || loaded === undefined)
|
|
41
|
+
return {};
|
|
42
|
+
if (typeof loaded !== 'object' || Array.isArray(loaded)) {
|
|
43
|
+
throw new Error('.agent-user.yml must parse to an object');
|
|
44
|
+
}
|
|
45
|
+
return loaded;
|
|
46
|
+
}
|
|
30
47
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
48
|
+
* Compose a plain object back into a `.agent-user.yml` body, emitting
|
|
49
|
+
* YAML in block style (no flow `[a, b]`, no inline maps) so list-valued
|
|
50
|
+
* fields like `role` produce one entry per line and diff cleanly in git.
|
|
33
51
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* via the Zod schema in `./schema.ts`. A body without a frontmatter
|
|
37
|
-
* fence parses to `{ data: {}, content: body }`.
|
|
52
|
+
* `yaml.dump` always terminates with `\n`; the result is returned as-is
|
|
53
|
+
* so atomicWrite preserves the trailing newline (POSIX-friendly).
|
|
38
54
|
*/
|
|
39
|
-
export function
|
|
55
|
+
export function composeUserIdentity(data) {
|
|
56
|
+
return yaml.dump(data, {
|
|
57
|
+
flowLevel: -1,
|
|
58
|
+
lineWidth: -1,
|
|
59
|
+
noRefs: true,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Parse a legacy `.agent-user.md` body (fenced YAML frontmatter +
|
|
64
|
+
* optional markdown body). The frontmatter becomes the identity object;
|
|
65
|
+
* any non-empty markdown body is captured under `notes` so prose is
|
|
66
|
+
* preserved across the migration. Returns `{}` when neither fence nor
|
|
67
|
+
* usable body is present.
|
|
68
|
+
*
|
|
69
|
+
* Drop once `.agent-user.md` files are no longer in circulation.
|
|
70
|
+
*/
|
|
71
|
+
export function parseLegacyUserMd(body) {
|
|
40
72
|
const match = FRONTMATTER_FENCE.exec(body);
|
|
41
73
|
if (match === null) {
|
|
42
|
-
|
|
74
|
+
const trimmed = body.trim();
|
|
75
|
+
return trimmed === '' ? {} : { notes: trimmed };
|
|
43
76
|
}
|
|
44
77
|
const yamlText = match[1] ?? '';
|
|
45
|
-
const
|
|
78
|
+
const tail = body.slice(match[0].length).trim();
|
|
46
79
|
const loaded = yaml.load(yamlText);
|
|
47
80
|
const data = loaded !== null && typeof loaded === 'object' && !Array.isArray(loaded)
|
|
48
|
-
? loaded
|
|
81
|
+
? { ...loaded }
|
|
49
82
|
: {};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Compose a structured `ParsedUserMd` back into an `.agent-user.md`
|
|
54
|
-
* body, emitting YAML frontmatter in block style (no flow `[a, b]`,
|
|
55
|
-
* no inline maps) so list-valued fields like `identity.role` produce
|
|
56
|
-
* one entry per line and diff cleanly in git.
|
|
57
|
-
*
|
|
58
|
-
* When `data` is empty, the leading `---\n---\n` fence is omitted.
|
|
59
|
-
*/
|
|
60
|
-
export function composeUserMd(parsed) {
|
|
61
|
-
if (Object.keys(parsed.data).length === 0) {
|
|
62
|
-
return parsed.content;
|
|
83
|
+
if (tail !== '' && data.notes === undefined) {
|
|
84
|
+
data.notes = tail;
|
|
63
85
|
}
|
|
64
|
-
|
|
65
|
-
flowLevel: -1,
|
|
66
|
-
lineWidth: -1,
|
|
67
|
-
noRefs: true,
|
|
68
|
-
});
|
|
69
|
-
// `yaml.dump` always terminates with `\n`; strip and re-add inside
|
|
70
|
-
// the fence so the body shape stays `---\n<yaml>\n---\n<content>`.
|
|
71
|
-
const trimmed = dumped.endsWith('\n') ? dumped.slice(0, -1) : dumped;
|
|
72
|
-
return `---\n${trimmed}\n---\n${parsed.content}`;
|
|
86
|
+
return data;
|
|
73
87
|
}
|
|
74
88
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/shared/userMd/utils.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/shared/userMd/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,oEAAoE;AACpE,MAAM,iBAAiB,GAAG,mCAAmC,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACvD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,MAAiC,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA6B;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QACnB,SAAS,EAAE,CAAC,CAAC;QACb,SAAS,EAAE,CAAC,CAAC;QACb,MAAM,EAAE,IAAI;KACf,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,IAAI,GACN,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QACnE,CAAC,CAAC,EAAE,GAAI,MAAkC,EAAE;QAC5C,CAAC,CAAC,EAAE,CAAC;IACb,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|