yaaw-se 0.3.11 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/installer/migrations/index.d.ts +2 -2
  2. package/dist/installer/migrations/index.js +2 -2
  3. package/dist/installer/migrations/index.js.map +1 -1
  4. package/dist/installer/migrations/project/index.js +2 -1
  5. package/dist/installer/migrations/project/index.js.map +1 -1
  6. package/dist/installer/migrations/project/v2-to-v3.d.ts +2 -0
  7. package/dist/installer/migrations/project/v2-to-v3.js +56 -0
  8. package/dist/installer/migrations/project/v2-to-v3.js.map +1 -0
  9. package/dist/installer/plan.js +98 -268
  10. package/dist/installer/plan.js.map +1 -1
  11. package/dist/installer/project-state.js +3 -13
  12. package/dist/installer/project-state.js.map +1 -1
  13. package/dist/installer/status.js +67 -231
  14. package/dist/installer/status.js.map +1 -1
  15. package/dist/installer/transaction.js +58 -109
  16. package/dist/installer/transaction.js.map +1 -1
  17. package/dist/installer/types.d.ts +5 -2
  18. package/dist/installer/verify.js +27 -27
  19. package/dist/installer/verify.js.map +1 -1
  20. package/dist/payload/bootstrap/claude-code.md +6 -6
  21. package/dist/payload/bootstrap/cline.md +8 -8
  22. package/dist/payload/bootstrap/codex.md +7 -7
  23. package/dist/payload/bootstrap/gemini-cli.md +6 -6
  24. package/dist/payload/payload-files.json +97 -417
  25. package/dist/payload/payload.json +1 -1
  26. package/dist/payload/skills/yaaw-create-spec/SKILL.md +2 -6
  27. package/dist/payload/skills/yaaw-create-ticket/SKILL.md +2 -6
  28. package/dist/payload/skills/yaaw-create-tickets/SKILL.md +2 -6
  29. package/dist/payload/skills/yaaw-implement/SKILL.md +2 -6
  30. package/dist/payload/skills/yaaw-orchestrator/SKILL.md +2 -3
  31. package/dist/payload/skills/yaaw-planner/SKILL.md +2 -6
  32. package/dist/payload/skills/yaaw-planning-review/SKILL.md +2 -6
  33. package/dist/payload/skills/yaaw-prd/SKILL.md +2 -6
  34. package/dist/payload/skills/yaaw-refine-prd/SKILL.md +2 -6
  35. package/dist/payload/skills/yaaw-repair/SKILL.md +2 -6
  36. package/dist/payload/skills/yaaw-review/SKILL.md +2 -6
  37. package/dist/payload/skills/yaaw-revise-prd/SKILL.md +2 -6
  38. package/dist/payload/yaaw-core/registries/skills.json +38 -0
  39. package/dist/payload/yaaw-core/system/SYSTEM.md +121 -0
  40. package/dist/payload/yaaw-core/system/engine/contracts.mjs +147 -0
  41. package/dist/payload/yaaw-core/system/engine/repository-identity.mjs +24 -0
  42. package/dist/payload/yaaw-core/system/engine/routing.mjs +153 -0
  43. package/dist/payload/yaaw-core/system/engine/runtime.mjs +66 -0
  44. package/dist/payload/yaaw-core/system/kernel.yaml +145 -0
  45. package/dist/payload/yaaw-core/system/modules/changeability.md +27 -0
  46. package/dist/payload/yaaw-core/system/roles/implementer.md +16 -12
  47. package/dist/payload/yaaw-core/system/roles/orchestrator.md +24 -14
  48. package/dist/payload/yaaw-core/system/roles/planner.md +37 -11
  49. package/dist/payload/yaaw-core/system/roles/prd.md +26 -18
  50. package/dist/payload/yaaw-core/system/roles/reviewer.md +16 -15
  51. package/dist/payload/yaaw-core/system/schemas/handoff.schema.json +24 -161
  52. package/dist/payload/yaaw-core/system/schemas/intent.schema.json +11 -64
  53. package/dist/payload/yaaw-core/system/schemas/observed-state.schema.json +12 -162
  54. package/dist/payload/yaaw-core/system/schemas/repository-identity.schema.json +12 -39
  55. package/dist/payload/yaaw-core/system/templates/evidence.json +1 -18
  56. package/dist/payload/yaaw-core/system/templates/handoff.json +11 -27
  57. package/dist/payload/yaaw-core/system/templates/intent.json +2 -2
  58. package/dist/payload/yaaw-core/system/templates/observed-state.json +5 -28
  59. package/dist/payload/yaaw-core/system/templates/review.md +2 -2
  60. package/package.json +5 -2
  61. package/dist/payload/yaaw-core/system/core/artifact-model.md +0 -43
  62. package/dist/payload/yaaw-core/system/core/authority.md +0 -21
  63. package/dist/payload/yaaw-core/system/core/context-loading.md +0 -56
  64. package/dist/payload/yaaw-core/system/core/dispatch-execution.md +0 -28
  65. package/dist/payload/yaaw-core/system/core/execution-context.md +0 -61
  66. package/dist/payload/yaaw-core/system/core/framework-integrity.md +0 -60
  67. package/dist/payload/yaaw-core/system/core/invalidation.md +0 -13
  68. package/dist/payload/yaaw-core/system/core/io-contract.md +0 -23
  69. package/dist/payload/yaaw-core/system/core/lifecycle.md +0 -23
  70. package/dist/payload/yaaw-core/system/core/recovery.md +0 -17
  71. package/dist/payload/yaaw-core/system/core/routing.md +0 -21
  72. package/dist/payload/yaaw-core/system/core/state-model.md +0 -14
  73. package/dist/payload/yaaw-core/system/core/transitions.md +0 -36
  74. package/dist/payload/yaaw-core/system/expertise/changeability/MODULE.md +0 -58
  75. package/dist/payload/yaaw-core/system/registries/artifacts.json +0 -99
  76. package/dist/payload/yaaw-core/system/registries/execution-policy.json +0 -169
  77. package/dist/payload/yaaw-core/system/registries/expertise.json +0 -47
  78. package/dist/payload/yaaw-core/system/registries/handoff-policy.json +0 -67
  79. package/dist/payload/yaaw-core/system/registries/paths.json +0 -18
  80. package/dist/payload/yaaw-core/system/registries/reconciliation-policy.json +0 -18
  81. package/dist/payload/yaaw-core/system/registries/role-io.json +0 -30
  82. package/dist/payload/yaaw-core/system/registries/routing-policy.json +0 -74
  83. package/dist/payload/yaaw-core/system/registries/skills.json +0 -110
  84. package/dist/payload/yaaw-core/system/registries/transitions.json +0 -178
  85. package/dist/payload/yaaw-core/system/registries/workflows.json +0 -38
  86. package/dist/payload/yaaw-core/system/rules/artifact-writing.md +0 -10
  87. package/dist/payload/yaaw-core/system/rules/assumption-challenge.md +0 -109
  88. package/dist/payload/yaaw-core/system/rules/changeability.md +0 -38
  89. package/dist/payload/yaaw-core/system/rules/durable-memory.md +0 -9
  90. package/dist/payload/yaaw-core/system/rules/question-format.md +0 -20
  91. package/dist/payload/yaaw-core/system/rules/recovery-evidence.md +0 -9
  92. package/dist/payload/yaaw-core/system/rules/repository-identity.md +0 -42
  93. package/dist/payload/yaaw-core/system/rules/research-admission.md +0 -30
  94. package/dist/payload/yaaw-core/system/rules/review-independence.md +0 -11
  95. package/dist/payload/yaaw-core/system/rules/ticket-sizing.md +0 -9
  96. package/dist/payload/yaaw-core/system/schemas/project-state.schema.json +0 -12
  97. package/dist/payload/yaaw-core/system/templates/project-state.json +0 -13
  98. package/dist/payload/yaaw-core/system/tools/orchestration-engine.mjs +0 -210
  99. package/dist/payload/yaaw-core/system/tools/orchestration-runtime.mjs +0 -46
  100. package/dist/payload/yaaw-core/system/tools/repository-identity.mjs +0 -92
  101. package/dist/payload/yaaw-core/system/workflows/implementation/implement-ticket.md +0 -18
  102. package/dist/payload/yaaw-core/system/workflows/implementation/repair-ticket.md +0 -17
  103. package/dist/payload/yaaw-core/system/workflows/implementation/select-ticket.md +0 -17
  104. package/dist/payload/yaaw-core/system/workflows/implementation/verify-ticket.md +0 -19
  105. package/dist/payload/yaaw-core/system/workflows/orchestration/determine-next-action.md +0 -24
  106. package/dist/payload/yaaw-core/system/workflows/orchestration/dispatch.md +0 -35
  107. package/dist/payload/yaaw-core/system/workflows/orchestration/inspect-state.md +0 -19
  108. package/dist/payload/yaaw-core/system/workflows/orchestration/reconcile-state.md +0 -19
  109. package/dist/payload/yaaw-core/system/workflows/orchestration/recover-interruption.md +0 -32
  110. package/dist/payload/yaaw-core/system/workflows/orchestration/route.md +0 -27
  111. package/dist/payload/yaaw-core/system/workflows/planning/create-spec.md +0 -21
  112. package/dist/payload/yaaw-core/system/workflows/planning/create-tickets.md +0 -50
  113. package/dist/payload/yaaw-core/system/workflows/planning/decision-frontier.md +0 -33
  114. package/dist/payload/yaaw-core/system/workflows/planning/discover.md +0 -21
  115. package/dist/payload/yaaw-core/system/workflows/planning/question-round.md +0 -22
  116. package/dist/payload/yaaw-core/system/workflows/planning/readiness-review.md +0 -33
  117. package/dist/payload/yaaw-core/system/workflows/planning/record-decisions.md +0 -19
  118. package/dist/payload/yaaw-core/system/workflows/planning/replan.md +0 -24
  119. package/dist/payload/yaaw-core/system/workflows/planning/research.md +0 -20
  120. package/dist/payload/yaaw-core/system/workflows/planning/route.md +0 -28
  121. package/dist/payload/yaaw-core/system/workflows/planning/write-understanding.md +0 -26
  122. package/dist/payload/yaaw-core/system/workflows/prd/create.md +0 -22
  123. package/dist/payload/yaaw-core/system/workflows/prd/question-round.md +0 -20
  124. package/dist/payload/yaaw-core/system/workflows/prd/readiness.md +0 -22
  125. package/dist/payload/yaaw-core/system/workflows/prd/record-decisions.md +0 -20
  126. package/dist/payload/yaaw-core/system/workflows/prd/refine.md +0 -15
  127. package/dist/payload/yaaw-core/system/workflows/prd/revise.md +0 -18
  128. package/dist/payload/yaaw-core/system/workflows/prd/route.md +0 -23
  129. package/dist/payload/yaaw-core/system/workflows/review/classify-findings.md +0 -17
  130. package/dist/payload/yaaw-core/system/workflows/review/inspect-change.md +0 -20
  131. package/dist/payload/yaaw-core/system/workflows/review/record-review.md +0 -19
  132. package/dist/payload/yaaw-core/system/workflows/review/review-ticket.md +0 -24
  133. /package/dist/payload/yaaw-core/system/{tools → engine}/frontmatter.mjs +0 -0
  134. /package/dist/payload/yaaw-core/system/{tools/framework-integrity.mjs → engine/integrity.mjs} +0 -0
  135. /package/dist/payload/yaaw-core/system/{expertise/frontend-design/MODULE.md → modules/frontend-design.md} +0 -0
  136. /package/dist/payload/yaaw-core/system/{expertise/python/MODULE.md → modules/python.md} +0 -0
  137. /package/dist/payload/yaaw-core/system/{expertise/security/MODULE.md → modules/security.md} +0 -0
  138. /package/dist/payload/yaaw-core/system/{expertise/testing/MODULE.md → modules/testing.md} +0 -0
@@ -17,85 +17,43 @@ export class ManagedConflictError extends Error {
17
17
  this.name = "ManagedConflictError";
18
18
  }
19
19
  }
20
- async function exists(path) {
21
- try {
22
- await access(path);
23
- return true;
24
- }
25
- catch {
26
- return false;
27
- }
20
+ async function exists(path) { try {
21
+ await access(path);
22
+ return true;
28
23
  }
29
- async function walk(dir) {
30
- const entries = await readdir(dir, { withFileTypes: true });
31
- const out = [];
32
- for (const entry of entries) {
33
- const full = join(dir, entry.name);
34
- if (entry.isDirectory())
35
- out.push(...await walk(full));
36
- else
37
- out.push(full);
38
- }
39
- return out;
40
- }
41
- async function canonicalSkills(payloadRoot) {
42
- const registry = JSON.parse(await readFile(join(payloadRoot, "yaaw-core", "system", "registries", "skills.json"), "utf8"));
43
- return Object.keys(registry).sort().map(id => ({ id, source: join(payloadRoot, "skills", id, "SKILL.md") }));
44
- }
45
- export async function resolveSkillSelection(payloadRoot, request) {
46
- const all = (await canonicalSkills(payloadRoot)).map(x => x.id);
47
- const core = ["yaaw-orchestrator", "yaaw-prd", "yaaw-planner", "yaaw-implement", "yaaw-review"];
48
- if (Array.isArray(request)) {
49
- const unknown = request.filter(x => !all.includes(x));
50
- if (unknown.length)
51
- throw new Error(`Unknown skills: ${unknown.join(", ")}`);
52
- return [...new Set(request)];
53
- }
54
- if (request === "standard")
55
- return all;
56
- if (request === "core")
57
- return core;
58
- const requested = request.split(",").map(x => x.trim()).filter(Boolean);
59
- const unknown = requested.filter(x => !all.includes(x));
24
+ catch {
25
+ return false;
26
+ } }
27
+ async function walk(dir) { const out = []; for (const entry of await readdir(dir, { withFileTypes: true })) {
28
+ const full = join(dir, entry.name);
29
+ if (entry.isDirectory())
30
+ out.push(...await walk(full));
31
+ else
32
+ out.push(full);
33
+ } return out; }
34
+ async function canonicalSkills(payloadRoot) { const kernel = JSON.parse(await readFile(join(payloadRoot, "yaaw-core", "system", "kernel.yaml"), "utf8")); return Object.keys(kernel.skills ?? {}).sort().map(id => ({ id, source: join(payloadRoot, "skills", id, "SKILL.md") })); }
35
+ export async function resolveSkillSelection(payloadRoot, request) { const all = (await canonicalSkills(payloadRoot)).map(x => x.id), core = ["yaaw-orchestrator", "yaaw-prd", "yaaw-planner", "yaaw-implement", "yaaw-review"]; if (Array.isArray(request)) {
36
+ const unknown = request.filter(x => !all.includes(x));
60
37
  if (unknown.length)
61
38
  throw new Error(`Unknown skills: ${unknown.join(", ")}`);
62
- return [...new Set(requested)];
63
- }
64
- function rel(projectRoot, path) {
65
- return relative(projectRoot, path).replaceAll("\\", "/");
66
- }
67
- function queueEmptyParentCleanup(operations, projectRoot, path, owner) {
68
- const protectedDirs = new Set([
69
- projectRoot,
70
- join(projectRoot, ".yaaw-core"),
71
- join(projectRoot, ".yaaw-core", "project"),
72
- join(projectRoot, ".yaaw-core", "install")
73
- ]);
74
- let current = dirname(path);
75
- while (current !== projectRoot && !protectedDirs.has(current)) {
76
- // Cleanup is intentionally repeatable. Earlier attempts may see sibling
77
- // managed files that are removed later in the same transaction; the final
78
- // attempt then removes the now-empty adapter/framework directory.
79
- operations.push({ type: "remove-empty-dir", path: current, owner });
80
- current = dirname(current);
81
- }
82
- }
83
- async function currentFileHash(path) {
84
- try {
85
- return sha256Bytes(await readFile(path));
86
- }
87
- catch {
88
- return null;
89
- }
39
+ return [...new Set(request)];
40
+ } if (request === "standard")
41
+ return all; if (request === "core")
42
+ return core; const requested = request.split(",").map(x => x.trim()).filter(Boolean), unknown = requested.filter(x => !all.includes(x)); if (unknown.length)
43
+ throw new Error(`Unknown skills: ${unknown.join(", ")}`); return [...new Set(requested)]; }
44
+ function rel(projectRoot, path) { return relative(projectRoot, path).replaceAll("\\", "/"); }
45
+ function queueEmptyParentCleanup(operations, projectRoot, path, owner) { const protectedDirs = new Set([projectRoot, join(projectRoot, ".yaaw-core"), join(projectRoot, ".yaaw-core", "project"), join(projectRoot, ".yaaw-core", "install")]); let current = dirname(path); while (current !== projectRoot && !protectedDirs.has(current)) {
46
+ operations.push({ type: "remove-empty-dir", path: current, owner });
47
+ current = dirname(current);
48
+ } }
49
+ async function currentFileHash(path) { try {
50
+ return sha256Bytes(await readFile(path));
90
51
  }
52
+ catch {
53
+ return null;
54
+ } }
91
55
  export async function chooseManagedFile(params) {
92
- const { ctx, previous, path, owner, operations, records, conflicts, backupStamp } = params;
93
- const pathRel = rel(ctx.projectRoot, path);
94
- const expected = params.source ? await readFile(params.source) : Buffer.from(params.content ?? "");
95
- const expectedHash = sha256Bytes(expected);
96
- const diskHash = await currentFileHash(path);
97
- const prior = previous?.managedFiles?.[pathRel];
98
- const hasConflict = diskHash !== null && (prior ? (prior.localOverride === true || diskHash !== prior.sha256) : diskHash !== expectedHash);
56
+ const { ctx, previous, path, owner, operations, records, conflicts, backupStamp } = params, pathRel = rel(ctx.projectRoot, path), expected = params.source ? await readFile(params.source) : Buffer.from(params.content ?? ""), expectedHash = sha256Bytes(expected), diskHash = await currentFileHash(path), prior = previous?.managedFiles?.[pathRel], hasConflict = diskHash !== null && (prior ? (prior.localOverride === true || diskHash !== prior.sha256) : diskHash !== expectedHash);
99
57
  if (hasConflict && ctx.conflictPolicy === "fail") {
100
58
  conflicts.push(pathRel);
101
59
  return;
@@ -116,18 +74,13 @@ export async function chooseManagedFile(params) {
116
74
  records[pathRel] = { owner, sha256: expectedHash };
117
75
  }
118
76
  export async function chooseManagedSection(params) {
119
- const { ctx, previous, op, sectionRecords, operations, conflicts, backupStamp } = params;
120
- const pathRel = rel(ctx.projectRoot, op.path);
77
+ const { ctx, previous, op, sectionRecords, operations, conflicts, backupStamp } = params, pathRel = rel(ctx.projectRoot, op.path);
121
78
  let original = "";
122
79
  try {
123
80
  original = await readFile(op.path, "utf8");
124
81
  }
125
82
  catch { }
126
- const existing = extractManagedSection(original, op.sectionId);
127
- const expectedHash = managedSectionHash(op.content);
128
- const prior = previous?.managedSections?.[pathRel]?.[op.sectionId];
129
- const existingHash = existing === null ? null : managedSectionHash(existing);
130
- const conflict = existing !== null && (prior ? (prior.localOverride === true || existingHash !== prior.sha256) : existingHash !== expectedHash);
83
+ const existing = extractManagedSection(original, op.sectionId), expectedHash = managedSectionHash(op.content), prior = previous?.managedSections?.[pathRel]?.[op.sectionId], existingHash = existing === null ? null : managedSectionHash(existing), conflict = existing !== null && (prior ? (prior.localOverride === true || existingHash !== prior.sha256) : existingHash !== expectedHash);
131
84
  if (conflict && ctx.conflictPolicy === "fail") {
132
85
  conflicts.push(`${pathRel}#${op.sectionId}`);
133
86
  return;
@@ -138,16 +91,14 @@ export async function chooseManagedSection(params) {
138
91
  return;
139
92
  }
140
93
  if (conflict && ctx.conflictPolicy === "backup-replace") {
141
- const backupPath = join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel);
142
- operations.push({ type: "write-managed-file", path: backupPath, content: original, owner: "installer:backup" });
94
+ operations.push({ type: "write-managed-file", path: join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel), content: original, owner: "installer:backup" });
143
95
  }
144
96
  operations.push(op);
145
97
  sectionRecords[pathRel] ??= {};
146
98
  sectionRecords[pathRel][op.sectionId] = { owner: op.owner, sha256: expectedHash };
147
99
  }
148
100
  export async function chooseManagedConfigKeys(params) {
149
- const { ctx, previous, op, configRecords, operations, conflicts, backupStamp } = params;
150
- const pathRel = rel(ctx.projectRoot, op.path);
101
+ const { ctx, previous, op, configRecords, operations, conflicts, backupStamp } = params, pathRel = rel(ctx.projectRoot, op.path);
151
102
  let original = "";
152
103
  try {
153
104
  original = await readFile(op.path, "utf8");
@@ -158,11 +109,7 @@ export async function chooseManagedConfigKeys(params) {
158
109
  const ownedEntries = [];
159
110
  let backupQueued = false;
160
111
  for (const entry of op.entries) {
161
- const prior = previous?.managedConfigKeys?.[pathRel]?.[entry.key];
162
- const current = readTomlManagedValue(original, entry.key);
163
- const expectedHash = semanticConfigHash(entry.value);
164
- const currentHash = current === undefined ? null : semanticConfigHash(current);
165
- const namespacedRole = entry.key.startsWith("agents.yaaw_");
112
+ const prior = previous?.managedConfigKeys?.[pathRel]?.[entry.key], current = readTomlManagedValue(original, entry.key), expectedHash = semanticConfigHash(entry.value), currentHash = current === undefined ? null : semanticConfigHash(current), namespacedRole = entry.key.startsWith("agents.yaaw_");
166
113
  if (!prior) {
167
114
  if (current === undefined) {
168
115
  ownedEntries.push(entry);
@@ -170,17 +117,14 @@ export async function chooseManagedConfigKeys(params) {
170
117
  configRecords[pathRel][entry.key] = { owner: op.owner, sha256: expectedHash, value: entry.value };
171
118
  continue;
172
119
  }
173
- if (!namespacedRole && currentHash === expectedHash) {
174
- // Compatible user-owned value satisfies the request. Do not claim ownership.
120
+ if (!namespacedRole && currentHash === expectedHash)
175
121
  continue;
176
- }
177
122
  if (ctx.conflictPolicy === "fail" || ctx.conflictPolicy === "keep") {
178
123
  conflicts.push(`${pathRel}#${entry.key}`);
179
124
  continue;
180
125
  }
181
126
  if (ctx.conflictPolicy === "backup-replace" && !backupQueued) {
182
- const backupPath = join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel);
183
- operations.push({ type: "write-managed-file", path: backupPath, content: original, owner: "installer:backup" });
127
+ operations.push({ type: "write-managed-file", path: join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel), content: original, owner: "installer:backup" });
184
128
  backupQueued = true;
185
129
  }
186
130
  ownedEntries.push(entry);
@@ -196,19 +140,12 @@ export async function chooseManagedConfigKeys(params) {
196
140
  if (modified && ctx.conflictPolicy === "keep") {
197
141
  if (current !== undefined) {
198
142
  configRecords[pathRel] ??= {};
199
- configRecords[pathRel][entry.key] = {
200
- owner: op.owner,
201
- sha256: currentHash,
202
- value: current,
203
- packageSha256: expectedHash,
204
- localOverride: true
205
- };
143
+ configRecords[pathRel][entry.key] = { owner: op.owner, sha256: currentHash, value: current, packageSha256: expectedHash, localOverride: true };
206
144
  }
207
145
  continue;
208
146
  }
209
147
  if (modified && ctx.conflictPolicy === "backup-replace" && !backupQueued) {
210
- const backupPath = join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel);
211
- operations.push({ type: "write-managed-file", path: backupPath, content: original, owner: "installer:backup" });
148
+ operations.push({ type: "write-managed-file", path: join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel), content: original, owner: "installer:backup" });
212
149
  backupQueued = true;
213
150
  }
214
151
  ownedEntries.push(entry);
@@ -219,8 +156,7 @@ export async function chooseManagedConfigKeys(params) {
219
156
  operations.push({ ...op, entries: ownedEntries });
220
157
  }
221
158
  export async function protectConfigRemoval(params) {
222
- const { ctx, pathRel, records, operations, conflicts, backupStamp } = params;
223
- const path = join(ctx.projectRoot, pathRel);
159
+ const { ctx, pathRel, records, operations, conflicts, backupStamp } = params, path = join(ctx.projectRoot, pathRel);
224
160
  let original = "";
225
161
  try {
226
162
  original = await readFile(path, "utf8");
@@ -235,8 +171,7 @@ export async function protectConfigRemoval(params) {
235
171
  const current = readTomlManagedValue(original, key);
236
172
  if (current === undefined)
237
173
  continue;
238
- const currentHash = semanticConfigHash(current);
239
- const modified = record.localOverride === true || currentHash !== record.sha256;
174
+ const currentHash = semanticConfigHash(current), modified = record.localOverride === true || currentHash !== record.sha256;
240
175
  if (modified && ctx.conflictPolicy === "fail") {
241
176
  conflicts.push(`${pathRel}#${key}`);
242
177
  continue;
@@ -244,8 +179,7 @@ export async function protectConfigRemoval(params) {
244
179
  if (modified && ctx.conflictPolicy === "keep")
245
180
  continue;
246
181
  if (modified && ctx.conflictPolicy === "backup-replace" && !backupQueued) {
247
- const backupPath = join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel);
248
- operations.push({ type: "write-managed-file", path: backupPath, content: original, owner: "installer:backup" });
182
+ operations.push({ type: "write-managed-file", path: join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel), content: original, owner: "installer:backup" });
249
183
  backupQueued = true;
250
184
  }
251
185
  removable.push(key);
@@ -255,62 +189,32 @@ export async function protectConfigRemoval(params) {
255
189
  queueEmptyParentCleanup(operations, ctx.projectRoot, path, "integration:codex");
256
190
  }
257
191
  }
258
- async function protectRemoval(params) {
259
- const { ctx, previous, pathRel, record, operations, conflicts, backupStamp } = params;
260
- const path = join(ctx.projectRoot, pathRel);
261
- const diskHash = await currentFileHash(path);
262
- if (diskHash === null)
263
- return;
264
- const modified = record.localOverride === true || diskHash !== record.sha256;
265
- if (modified && ctx.conflictPolicy === "fail") {
266
- conflicts.push(pathRel);
267
- return;
268
- }
269
- if (modified && ctx.conflictPolicy === "keep") {
270
- operations.push({ type: "preserve", path, reason: "local managed-file override retained during removal" });
271
- return;
272
- }
273
- if (modified && ctx.conflictPolicy === "backup-replace") {
274
- const backupPath = join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel);
275
- operations.push({ type: "write-managed-file", path: backupPath, content: await readFile(path), owner: "installer:backup" });
276
- }
277
- operations.push({ type: "remove-managed-file", path, owner: record.owner });
278
- queueEmptyParentCleanup(operations, ctx.projectRoot, path, record.owner);
279
- }
280
- async function protectSectionRemoval(params) {
281
- const { ctx, pathRel, sectionId, record, operations, conflicts, backupStamp } = params;
282
- const path = join(ctx.projectRoot, pathRel);
283
- let original = "";
284
- try {
285
- original = await readFile(path, "utf8");
286
- }
287
- catch {
288
- return;
289
- }
290
- const existing = extractManagedSection(original, sectionId);
291
- if (existing === null)
292
- return;
293
- const modified = record.localOverride === true || managedSectionHash(existing) !== record.sha256;
294
- if (modified && ctx.conflictPolicy === "fail") {
295
- conflicts.push(`${pathRel}#${sectionId}`);
296
- return;
297
- }
298
- if (modified && ctx.conflictPolicy === "keep") {
299
- operations.push({ type: "preserve", path, reason: "local managed-section override retained during removal" });
300
- return;
301
- }
302
- if (modified && ctx.conflictPolicy === "backup-replace") {
303
- const backupPath = join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel);
304
- operations.push({ type: "write-managed-file", path: backupPath, content: original, owner: "installer:backup" });
305
- }
306
- operations.push({ type: "remove-managed-section", path, sectionId, owner: record.owner });
192
+ async function protectRemoval(params) { const { ctx, pathRel, record, operations, conflicts, backupStamp } = params, path = join(ctx.projectRoot, pathRel), diskHash = await currentFileHash(path); if (diskHash === null)
193
+ return; const modified = record.localOverride === true || diskHash !== record.sha256; if (modified && ctx.conflictPolicy === "fail") {
194
+ conflicts.push(pathRel);
195
+ return;
196
+ } if (modified && ctx.conflictPolicy === "keep") {
197
+ operations.push({ type: "preserve", path, reason: "local managed-file override retained during removal" });
198
+ return;
199
+ } if (modified && ctx.conflictPolicy === "backup-replace")
200
+ operations.push({ type: "write-managed-file", path: join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel), content: await readFile(path), owner: "installer:backup" }); operations.push({ type: "remove-managed-file", path, owner: record.owner }); queueEmptyParentCleanup(operations, ctx.projectRoot, path, record.owner); }
201
+ async function protectSectionRemoval(params) { const { ctx, pathRel, sectionId, record, operations, conflicts, backupStamp } = params, path = join(ctx.projectRoot, pathRel); let original = ""; try {
202
+ original = await readFile(path, "utf8");
307
203
  }
204
+ catch {
205
+ return;
206
+ } const existing = extractManagedSection(original, sectionId); if (existing === null)
207
+ return; const modified = record.localOverride === true || managedSectionHash(existing) !== record.sha256; if (modified && ctx.conflictPolicy === "fail") {
208
+ conflicts.push(`${pathRel}#${sectionId}`);
209
+ return;
210
+ } if (modified && ctx.conflictPolicy === "keep") {
211
+ operations.push({ type: "preserve", path, reason: "local managed-section override retained during removal" });
212
+ return;
213
+ } if (modified && ctx.conflictPolicy === "backup-replace")
214
+ operations.push({ type: "write-managed-file", path: join(ctx.projectRoot, ".yaaw-core", "install", "backups", backupStamp, pathRel), content: original, owner: "installer:backup" }); operations.push({ type: "remove-managed-section", path, sectionId, owner: record.owner }); }
308
215
  export async function buildInstallPlan(ctx, previous) {
309
- const warnings = [];
310
- const operations = [{ type: "mkdir", path: ctx.projectRoot, owner: "layout" }];
311
- const conflicts = [];
312
- const now = new Date().toISOString();
313
- const backupStamp = now.replace(/[:.]/g, "-");
216
+ const warnings = [], operations = [{ type: "mkdir", path: ctx.projectRoot, owner: "layout" }], conflicts = [];
217
+ const now = new Date().toISOString(), backupStamp = now.replace(/[:.]/g, "-");
314
218
  previous = previous ? migrateInstallationManifest(previous) : null;
315
219
  if (ctx.action === "uninstall") {
316
220
  if (!previous)
@@ -320,27 +224,15 @@ export async function buildInstallPlan(ctx, previous) {
320
224
  continue;
321
225
  await protectRemoval({ ctx, previous, pathRel, record, operations, conflicts, backupStamp });
322
226
  }
323
- for (const [pathRel, sections] of Object.entries(previous.managedSections)) {
324
- for (const [sectionId, record] of Object.entries(sections)) {
227
+ for (const [pathRel, sections] of Object.entries(previous.managedSections))
228
+ for (const [sectionId, record] of Object.entries(sections))
325
229
  await protectSectionRemoval({ ctx, previous, pathRel, sectionId, record, operations, conflicts, backupStamp });
326
- }
327
- }
328
- for (const [pathRel, records] of Object.entries(previous.managedConfigKeys ?? {})) {
230
+ for (const [pathRel, records] of Object.entries(previous.managedConfigKeys ?? {}))
329
231
  await protectConfigRemoval({ ctx, pathRel, records, operations, conflicts, backupStamp });
330
- }
331
232
  if (conflicts.length)
332
233
  throw new ManagedConflictError(conflicts);
333
- operations.push({ type: "remove-managed-file", path: join(ctx.projectRoot, MANIFEST_RELATIVE_PATH), owner: "installer" });
334
- operations.push({
335
- type: "write-managed-file",
336
- path: join(ctx.projectRoot, ".yaaw-core", "install", "uninstalled.json"),
337
- content: JSON.stringify({ schema: "yaaw.uninstalled/v1", version: previous.yaawVersion, uninstalledAt: now, projectMemory: ".yaaw-core/project" }, null, 2) + "\n",
338
- owner: "installer"
339
- });
340
- return {
341
- plan: { action: ctx.action, projectRoot: ctx.projectRoot, operations, selectedIntegrations: [], selectedSkills: [], warnings: ["Durable .yaaw-core/project data will be preserved."] },
342
- manifest: null
343
- };
234
+ operations.push({ type: "remove-managed-file", path: join(ctx.projectRoot, MANIFEST_RELATIVE_PATH), owner: "installer" }, { type: "write-managed-file", path: join(ctx.projectRoot, ".yaaw-core", "install", "uninstalled.json"), content: JSON.stringify({ schema: "yaaw.uninstalled/v1", version: previous.yaawVersion, uninstalledAt: now, projectMemory: ".yaaw-core/project" }, null, 2) + "\n", owner: "installer" });
235
+ return { plan: { action: ctx.action, projectRoot: ctx.projectRoot, operations, selectedIntegrations: [], selectedSkills: [], warnings: ["Durable .yaaw-core/project data will be preserved."] }, manifest: null };
344
236
  }
345
237
  if (previous) {
346
238
  if (previous.installationSchema > CURRENT_INSTALLATION_SCHEMA)
@@ -351,89 +243,46 @@ export async function buildInstallPlan(ctx, previous) {
351
243
  throw new Error(`Installed project schema ${previous.projectSchema} is newer than this package supports (${CURRENT_PROJECT_SCHEMA}); downgrade is blocked.`);
352
244
  for (const integrationId of ctx.selectedIntegrations) {
353
245
  const installed = previous.integrations[integrationId];
354
- if (installed && installed.adapterVersion > getIntegration(integrationId).adapterVersion) {
246
+ if (installed && installed.adapterVersion > getIntegration(integrationId).adapterVersion)
355
247
  throw new Error(`Installed ${integrationId} adapter v${installed.adapterVersion} is newer than this package supports; downgrade is blocked.`);
356
- }
357
248
  }
358
249
  }
359
250
  const manifest = emptyManifest(ctx.packageVersion, previous?.installedAt ?? now);
360
251
  manifest.updatedAt = now;
361
252
  manifest.skills = [...ctx.selectedSkills];
362
- const coreRoot = join(ctx.payloadRoot, "yaaw-core", "system");
363
- const coreFiles = await walk(coreRoot);
364
- const desiredFilePaths = new Set();
253
+ const coreRoot = join(ctx.payloadRoot, "yaaw-core", "system"), coreFiles = await walk(coreRoot), desiredFilePaths = new Set();
365
254
  for (const source of coreFiles) {
366
- const coreRel = relative(coreRoot, source);
367
- const target = join(ctx.projectRoot, ".yaaw-core", "system", coreRel);
255
+ const coreRel = relative(coreRoot, source), target = join(ctx.projectRoot, ".yaaw-core", "system", coreRel);
368
256
  desiredFilePaths.add(rel(ctx.projectRoot, target));
369
257
  await chooseManagedFile({ ctx, previous, path: target, owner: "package:system", source, operations, records: manifest.managedFiles, conflicts, backupStamp });
370
258
  }
371
259
  operations.push(...await planProjectInitialization(ctx.payloadRoot, ctx.projectRoot));
372
260
  if (["quick-update", "modify", "repair"].includes(ctx.action)) {
373
- for (const name of ["observed-state.json", "handoff.json", "intent.json", "dispatch-failures.json"]) {
374
- operations.push({
375
- type: "remove-runtime-file",
376
- path: join(ctx.projectRoot, ".yaaw-core", "runtime", name),
377
- owner: "runtime:invalidate"
378
- });
379
- }
261
+ for (const name of ["observed-state.json", "handoff.json", "intent.json", "dispatch-failures.json"])
262
+ operations.push({ type: "remove-runtime-file", path: join(ctx.projectRoot, ".yaaw-core", "runtime", name), owner: "runtime:invalidate" });
380
263
  warnings.push("Replaceable YAAW runtime coordination caches will be invalidated after package changes.");
381
264
  }
382
- if (previous) {
383
- for (const migration of migrationPath(projectMigrations, previous.projectSchema, CURRENT_PROJECT_SCHEMA)) {
384
- operations.push(...await migration.plan({
385
- projectRoot: ctx.projectRoot,
386
- payloadRoot: ctx.payloadRoot,
387
- fromVersion: migration.from,
388
- toVersion: migration.to
389
- }));
390
- }
391
- }
392
- const configurationSummaries = [];
393
- const skillMap = new Map((await canonicalSkills(ctx.payloadRoot)).map(x => [x.id, x]));
394
- const selectedCanonical = ctx.selectedSkills.map(id => {
395
- const skill = skillMap.get(id);
396
- if (!skill)
397
- throw new Error(`Unknown canonical skill: ${id}`);
398
- return skill;
399
- });
265
+ if (previous)
266
+ for (const migration of migrationPath(projectMigrations, previous.projectSchema, CURRENT_PROJECT_SCHEMA))
267
+ operations.push(...await migration.plan({ projectRoot: ctx.projectRoot, payloadRoot: ctx.payloadRoot, fromVersion: migration.from, toVersion: migration.to }));
268
+ const configurationSummaries = [], skillMap = new Map((await canonicalSkills(ctx.payloadRoot)).map(x => [x.id, x]));
269
+ const selectedCanonical = ctx.selectedSkills.map(id => { const skill = skillMap.get(id); if (!skill)
270
+ throw new Error(`Unknown canonical skill: ${id}`); return skill; });
400
271
  for (const integrationId of ctx.selectedIntegrations) {
401
- const adapter = getIntegration(integrationId);
402
- const previousRecord = previous?.integrations?.[integrationId];
403
- const previousConfiguration = previousRecord?.configuration;
272
+ const adapter = getIntegration(integrationId), previousRecord = previous?.integrations?.[integrationId], previousConfiguration = previousRecord?.configuration;
404
273
  let settings = ctx.integrationSettings?.[integrationId] ?? previousConfiguration?.settings ?? previousRecord?.runtime;
405
274
  if (adapter.configuration && settings === undefined)
406
275
  settings = adapter.configuration.defaultSettings();
407
- const ictx = { projectRoot: ctx.projectRoot, payloadRoot: ctx.payloadRoot, settings };
408
- const runtimeOps = adapter.configuration ? await adapter.configuration.plan(ictx) : adapter.planRuntime ? await adapter.planRuntime(ictx) : [];
409
- const adapterOps = [...await adapter.planSkills(ictx, selectedCanonical), ...await adapter.planBootstrap(ictx), ...runtimeOps];
410
- const installationRecord = {
411
- adapterVersion: adapter.adapterVersion,
412
- skillsRoot: rel(ctx.projectRoot, adapter.skillsRoot(ctx.projectRoot)),
413
- bootstrap: adapter.bootstrapRelativePath
414
- };
276
+ const ictx = { projectRoot: ctx.projectRoot, payloadRoot: ctx.payloadRoot, settings }, runtimeOps = adapter.configuration ? await adapter.configuration.plan(ictx) : adapter.planRuntime ? await adapter.planRuntime(ictx) : [], adapterOps = [...await adapter.planSkills(ictx, selectedCanonical), ...await adapter.planBootstrap(ictx), ...runtimeOps];
277
+ const installationRecord = { adapterVersion: adapter.adapterVersion, skillsRoot: rel(ctx.projectRoot, adapter.skillsRoot(ctx.projectRoot)), bootstrap: adapter.bootstrapRelativePath };
415
278
  if (adapter.configuration) {
416
- const normalizedSettings = adapter.configuration.normalize(settings);
417
- const preserveReviewedState = Boolean(previousConfiguration && ["quick-update", "repair"].includes(ctx.action));
418
- const configuration = preserveReviewedState
419
- ? structuredClone(previousConfiguration)
420
- : {
421
- schema: "yaaw.integration-config/v1",
422
- appliedRevision: adapter.configuration.revision,
423
- notifiedRevision: adapter.configuration.revision,
424
- profile: ctx.integrationProfiles?.[integrationId] ?? previousConfiguration?.profile ?? { id: "custom", revision: adapter.configuration.revision },
425
- settings: normalizedSettings
426
- };
279
+ const normalizedSettings = adapter.configuration.normalize(settings), preserveReviewedState = Boolean(previousConfiguration && ["quick-update", "repair"].includes(ctx.action)), configuration = preserveReviewedState ? structuredClone(previousConfiguration) : { schema: "yaaw.integration-config/v1", appliedRevision: adapter.configuration.revision, notifiedRevision: adapter.configuration.revision, profile: ctx.integrationProfiles?.[integrationId] ?? previousConfiguration?.profile ?? { id: "custom", revision: adapter.configuration.revision }, settings: normalizedSettings };
427
280
  if (ctx.action === "quick-update" && ctx.acknowledgeConfigurationUpdates?.includes(integrationId))
428
281
  configuration.notifiedRevision = adapter.configuration.revision;
429
282
  configuration.settings = preserveReviewedState ? previousConfiguration.settings : normalizedSettings;
430
283
  installationRecord.configuration = configuration;
431
284
  installationRecord.runtime = configuration.settings;
432
- configurationSummaries.push({
433
- integrationId,
434
- profile: configuration.profile ? `${configuration.profile.id} r${configuration.profile.revision}` : "custom",
435
- description: adapter.configuration.describe(configuration.settings)
436
- });
285
+ configurationSummaries.push({ integrationId, profile: configuration.profile ? `${configuration.profile.id} r${configuration.profile.revision}` : "custom", description: adapter.configuration.describe(configuration.settings) });
437
286
  }
438
287
  else if (adapter.planRuntime)
439
288
  installationRecord.runtime = settings ?? null;
@@ -447,47 +296,28 @@ export async function buildInstallPlan(ctx, previous) {
447
296
  desiredFilePaths.add(rel(ctx.projectRoot, op.path));
448
297
  await chooseManagedFile({ ctx, previous, path: op.path, owner: op.owner, content: op.content, operations, records: manifest.managedFiles, conflicts, backupStamp });
449
298
  }
450
- else if (op.type === "update-managed-section") {
299
+ else if (op.type === "update-managed-section")
451
300
  await chooseManagedSection({ ctx, previous, op, sectionRecords: manifest.managedSections, operations, conflicts, backupStamp });
452
- }
453
- else if (op.type === "update-managed-config-keys") {
301
+ else if (op.type === "update-managed-config-keys")
454
302
  await chooseManagedConfigKeys({ ctx, previous, op, configRecords: manifest.managedConfigKeys, operations, conflicts, backupStamp });
455
- }
456
303
  }
457
304
  }
458
305
  if (previous) {
459
- for (const [pathRel, record] of Object.entries(previous.managedFiles)) {
460
- if (!desiredFilePaths.has(pathRel) && record.owner !== "installer:backup") {
306
+ for (const [pathRel, record] of Object.entries(previous.managedFiles))
307
+ if (!desiredFilePaths.has(pathRel) && record.owner !== "installer:backup")
461
308
  await protectRemoval({ ctx, previous, pathRel, record, operations, conflicts, backupStamp });
462
- }
463
- }
464
- for (const [pathRel, sections] of Object.entries(previous.managedSections)) {
465
- for (const [sectionId, record] of Object.entries(sections)) {
466
- if (!manifest.managedSections[pathRel]?.[sectionId]) {
309
+ for (const [pathRel, sections] of Object.entries(previous.managedSections))
310
+ for (const [sectionId, record] of Object.entries(sections))
311
+ if (!manifest.managedSections[pathRel]?.[sectionId])
467
312
  await protectSectionRemoval({ ctx, previous, pathRel, sectionId, record, operations, conflicts, backupStamp });
468
- }
469
- }
470
- }
471
313
  for (const [pathRel, records] of Object.entries(previous.managedConfigKeys ?? {})) {
472
314
  const obsolete = Object.fromEntries(Object.entries(records).filter(([key]) => !manifest.managedConfigKeys[pathRel]?.[key]));
473
- if (Object.keys(obsolete).length) {
315
+ if (Object.keys(obsolete).length)
474
316
  await protectConfigRemoval({ ctx, pathRel, records: obsolete, operations, conflicts, backupStamp });
475
- }
476
317
  }
477
318
  }
478
319
  if (conflicts.length)
479
320
  throw new ManagedConflictError(conflicts);
480
- return {
481
- plan: {
482
- action: ctx.action,
483
- projectRoot: ctx.projectRoot,
484
- operations,
485
- selectedIntegrations: [...ctx.selectedIntegrations],
486
- selectedSkills: [...ctx.selectedSkills],
487
- warnings,
488
- configurationSummaries
489
- },
490
- manifest
491
- };
321
+ return { plan: { action: ctx.action, projectRoot: ctx.projectRoot, operations, selectedIntegrations: [...ctx.selectedIntegrations], selectedSkills: [...ctx.selectedSkills], warnings, configurationSummaries }, manifest };
492
322
  }
493
323
  //# sourceMappingURL=plan.js.map