@open-agent-toolkit/cli 0.1.30 → 0.1.32
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/assets/docs/cli-utilities/config-and-local-state.md +18 -5
- package/assets/docs/cli-utilities/tool-packs.md +13 -8
- package/assets/docs/reference/cli-reference.md +14 -13
- package/assets/docs/reference/file-locations.md +2 -1
- package/assets/docs/reference/oat-directory-structure.md +35 -22
- package/assets/migration/pjm-restructure.md +500 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/deep-research/SKILL.md +2 -2
- package/assets/skills/oat-brainstorm/SKILL.md +3 -3
- package/assets/skills/oat-brainstorm/references/destinations.md +10 -2
- package/assets/skills/oat-brainstorm/references/dogfood-results.md +4 -4
- package/assets/skills/oat-pjm-add-backlog-item/SKILL.md +17 -20
- package/assets/skills/oat-pjm-decision/SKILL.md +129 -0
- package/assets/skills/oat-pjm-review-backlog/SKILL.md +17 -17
- package/assets/skills/oat-pjm-review-backlog/references/backlog-review-template.md +2 -2
- package/assets/skills/oat-pjm-review-backlog/references/priority-alignment-template.md +13 -13
- package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +34 -25
- package/assets/skills/oat-project-complete/SKILL.md +2 -2
- package/assets/skills/oat-project-document/SKILL.md +4 -3
- package/assets/skills/oat-project-import-plan/SKILL.md +2 -2
- package/assets/skills/oat-project-summary/SKILL.md +76 -8
- package/assets/templates/backlog-item.md +1 -1
- package/assets/templates/current-state.md +11 -2
- package/assets/templates/decision.md +18 -0
- package/assets/templates/pjm-agents.md +13 -0
- package/assets/templates/reference-agents.md +14 -0
- package/assets/templates/repo-agents.md +13 -0
- package/assets/templates/roadmap.md +8 -3
- package/dist/commands/backlog/index.d.ts +1 -0
- package/dist/commands/backlog/index.d.ts.map +1 -1
- package/dist/commands/backlog/index.js +48 -11
- package/dist/commands/backlog/init.js +1 -1
- package/dist/commands/backlog/regenerate-index.d.ts.map +1 -1
- package/dist/commands/backlog/regenerate-index.js +24 -5
- package/dist/commands/backlog/shared/generate-id.d.ts +1 -3
- package/dist/commands/backlog/shared/generate-id.d.ts.map +1 -1
- package/dist/commands/backlog/shared/generate-id.js +4 -64
- package/dist/commands/cleanup/artifacts/artifacts.d.ts.map +1 -1
- package/dist/commands/cleanup/artifacts/artifacts.js +4 -1
- package/dist/commands/decision/index.d.ts +20 -0
- package/dist/commands/decision/index.d.ts.map +1 -0
- package/dist/commands/decision/index.js +177 -0
- package/dist/commands/decision/init.d.ts +7 -0
- package/dist/commands/decision/init.d.ts.map +1 -0
- package/dist/commands/decision/init.js +53 -0
- package/dist/commands/decision/migrate.d.ts +24 -0
- package/dist/commands/decision/migrate.d.ts.map +1 -0
- package/dist/commands/decision/migrate.js +270 -0
- package/dist/commands/decision/new.d.ts +16 -0
- package/dist/commands/decision/new.d.ts.map +1 -0
- package/dist/commands/decision/new.js +118 -0
- package/dist/commands/decision/regenerate-index.d.ts +14 -0
- package/dist/commands/decision/regenerate-index.d.ts.map +1 -0
- package/dist/commands/decision/regenerate-index.js +122 -0
- package/dist/commands/decision/shared/generate-id.d.ts +2 -0
- package/dist/commands/decision/shared/generate-id.d.ts.map +1 -0
- package/dist/commands/decision/shared/generate-id.js +5 -0
- package/dist/commands/doctor/index.d.ts +2 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +6 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/init/tools/shared/skill-manifest.d.ts +2 -2
- package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/skill-manifest.js +5 -1
- package/dist/commands/pjm/doctor.d.ts +3 -0
- package/dist/commands/pjm/doctor.d.ts.map +1 -0
- package/dist/commands/pjm/doctor.js +238 -0
- package/dist/commands/pjm/index.d.ts +7 -0
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +132 -10
- package/dist/commands/pjm/init.d.ts +3 -2
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +42 -33
- package/dist/commands/pjm/migrate.d.ts +36 -0
- package/dist/commands/pjm/migrate.d.ts.map +1 -0
- package/dist/commands/pjm/migrate.js +393 -0
- package/dist/commands/shared/date-id.d.ts +2 -0
- package/dist/commands/shared/date-id.d.ts.map +1 -0
- package/dist/commands/shared/date-id.js +10 -0
- package/dist/commands/shared/managed-index.d.ts +22 -0
- package/dist/commands/shared/managed-index.d.ts.map +1 -0
- package/dist/commands/shared/managed-index.js +92 -0
- package/dist/commands/shared/slug.d.ts +2 -0
- package/dist/commands/shared/slug.d.ts.map +1 -0
- package/dist/commands/shared/slug.js +57 -0
- package/dist/commands/shared/strip-template-frontmatter.d.ts +2 -0
- package/dist/commands/shared/strip-template-frontmatter.d.ts.map +1 -0
- package/dist/commands/shared/strip-template-frontmatter.js +16 -0
- package/dist/engine/hook.d.ts.map +1 -1
- package/dist/engine/hook.js +13 -0
- package/dist/release/public-package-contract.d.ts.map +1 -1
- package/dist/release/public-package-contract.js +10 -1
- package/package.json +2 -2
- package/assets/templates/decision-record.md +0 -21
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { access, mkdir, readdir, readFile, rename, stat, writeFile, } from 'node:fs/promises';
|
|
2
|
+
import { basename, dirname, join } from 'node:path';
|
|
3
|
+
import { initializeBacklog } from '../backlog/init.js';
|
|
4
|
+
import { regenerateBacklogIndex } from '../backlog/regenerate-index.js';
|
|
5
|
+
import { generateBacklogId } from '../backlog/shared/generate-id.js';
|
|
6
|
+
import { initializeDecisionRecords } from '../decision/init.js';
|
|
7
|
+
import { migrateDecisionRecords, } from '../decision/migrate.js';
|
|
8
|
+
import { stripTemplateFrontmatter } from '../shared/strip-template-frontmatter.js';
|
|
9
|
+
import YAML from 'yaml';
|
|
10
|
+
import { initializeRepoReference } from './init.js';
|
|
11
|
+
const ACTIVE_MOVES = [
|
|
12
|
+
{ source: 'reference/current-state.md', target: 'pjm/current-state.md' },
|
|
13
|
+
{ source: 'reference/roadmap.md', target: 'pjm/roadmap.md' },
|
|
14
|
+
{ source: 'reference/backlog', target: 'pjm/backlog' },
|
|
15
|
+
];
|
|
16
|
+
const JUDGMENT_TARGETS = [
|
|
17
|
+
'reference/backlog.md',
|
|
18
|
+
'reference/backlog-completed.md',
|
|
19
|
+
];
|
|
20
|
+
async function pathExists(path) {
|
|
21
|
+
try {
|
|
22
|
+
await access(path);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
const code = error && typeof error === 'object' && 'code' in error
|
|
27
|
+
? String(error.code)
|
|
28
|
+
: null;
|
|
29
|
+
if (code !== 'ENOENT') {
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function listMarkdownFiles(path) {
|
|
36
|
+
try {
|
|
37
|
+
const entries = await readdir(path, { withFileTypes: true });
|
|
38
|
+
return entries
|
|
39
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
|
|
40
|
+
.map((entry) => join(path, entry.name))
|
|
41
|
+
.sort();
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const code = error && typeof error === 'object' && 'code' in error
|
|
45
|
+
? String(error.code)
|
|
46
|
+
: null;
|
|
47
|
+
if (code !== 'ENOENT') {
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function stripMarkdownExtension(path) {
|
|
54
|
+
return basename(path, '.md');
|
|
55
|
+
}
|
|
56
|
+
function relativeToRepo(repoRoot, path) {
|
|
57
|
+
return path.startsWith(`${repoRoot}/`)
|
|
58
|
+
? path.slice(repoRoot.length + 1)
|
|
59
|
+
: path;
|
|
60
|
+
}
|
|
61
|
+
function parseFrontmatter(content, filePath) {
|
|
62
|
+
const match = content.match(/^---\n([\s\S]*?)\n---(\r?\n[\s\S]*)?$/);
|
|
63
|
+
if (!match) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const parsed = YAML.parse(match[1] ?? '');
|
|
67
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
68
|
+
throw new Error(`Frontmatter in ${filePath} must be a YAML object.`);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
frontmatter: parsed,
|
|
72
|
+
body: match[2] ?? '\n',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function renderFrontmatterRecord(frontmatter, body) {
|
|
76
|
+
return `---\n${YAML.stringify(frontmatter).trimEnd()}\n---${body}`;
|
|
77
|
+
}
|
|
78
|
+
async function createdAtForBacklogRecord(frontmatter, filePath) {
|
|
79
|
+
const created = frontmatter.created;
|
|
80
|
+
if (typeof created === 'string' && created.trim()) {
|
|
81
|
+
return created;
|
|
82
|
+
}
|
|
83
|
+
return (await stat(filePath)).mtime.toISOString();
|
|
84
|
+
}
|
|
85
|
+
function withNumericSuffix(id, suffix) {
|
|
86
|
+
return `${id}-${suffix}`;
|
|
87
|
+
}
|
|
88
|
+
async function allocateBacklogId(initialId, currentPath, targetDir, plannedTargets) {
|
|
89
|
+
let id = initialId;
|
|
90
|
+
let suffix = 2;
|
|
91
|
+
let targetPath = join(targetDir, `${id}.md`);
|
|
92
|
+
while (plannedTargets.has(targetPath) ||
|
|
93
|
+
(targetPath !== currentPath && (await pathExists(targetPath)))) {
|
|
94
|
+
id = withNumericSuffix(initialId, suffix);
|
|
95
|
+
targetPath = join(targetDir, `${id}.md`);
|
|
96
|
+
suffix += 1;
|
|
97
|
+
}
|
|
98
|
+
plannedTargets.add(targetPath);
|
|
99
|
+
return { id, targetPath };
|
|
100
|
+
}
|
|
101
|
+
async function prepareBacklogMigrations(backlogRoot) {
|
|
102
|
+
const prepared = [];
|
|
103
|
+
const plannedTargets = new Set();
|
|
104
|
+
for (const bucket of ['items', 'archived']) {
|
|
105
|
+
const bucketRoot = join(backlogRoot, bucket);
|
|
106
|
+
const files = await listMarkdownFiles(bucketRoot);
|
|
107
|
+
for (const sourcePath of files) {
|
|
108
|
+
const content = await readFile(sourcePath, 'utf8');
|
|
109
|
+
const parsed = parseFrontmatter(content, sourcePath);
|
|
110
|
+
if (!parsed) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const legacyId = String(parsed.frontmatter.id ?? stripMarkdownExtension(sourcePath));
|
|
114
|
+
const title = String(parsed.frontmatter.title ?? legacyId);
|
|
115
|
+
const createdAt = await createdAtForBacklogRecord(parsed.frontmatter, sourcePath);
|
|
116
|
+
const initialId = generateBacklogId(title, createdAt);
|
|
117
|
+
const { id, targetPath } = await allocateBacklogId(initialId, sourcePath, bucketRoot, plannedTargets);
|
|
118
|
+
if (id === legacyId && targetPath === sourcePath) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const nextFrontmatter = {
|
|
122
|
+
...parsed.frontmatter,
|
|
123
|
+
id,
|
|
124
|
+
};
|
|
125
|
+
// Migrated items are instantiated records, never raw templates. Drop the
|
|
126
|
+
// template-marker keys a legacy item may still carry so `pjm doctor`
|
|
127
|
+
// (prev2-t05) does not flag the migrated record. The shared
|
|
128
|
+
// `stripTemplateFrontmatter` defines which markers identify a raw
|
|
129
|
+
// template; mirror that key set here rather than re-parsing.
|
|
130
|
+
delete nextFrontmatter.oat_template;
|
|
131
|
+
delete nextFrontmatter.oat_template_name;
|
|
132
|
+
if (nextFrontmatter.legacy_id === undefined) {
|
|
133
|
+
nextFrontmatter.legacy_id = legacyId;
|
|
134
|
+
}
|
|
135
|
+
// Defense-in-depth: run the rebuilt record through the shared helper so any
|
|
136
|
+
// residual template frontmatter is stripped with the same rules doctor and
|
|
137
|
+
// `decision new` use. It is a no-op once the marker keys above are removed.
|
|
138
|
+
const migratedContent = stripTemplateFrontmatter(renderFrontmatterRecord(nextFrontmatter, parsed.body));
|
|
139
|
+
prepared.push({
|
|
140
|
+
sourcePath,
|
|
141
|
+
targetPath,
|
|
142
|
+
content: migratedContent,
|
|
143
|
+
mapping: {
|
|
144
|
+
legacyId,
|
|
145
|
+
id,
|
|
146
|
+
title,
|
|
147
|
+
filePath: targetPath,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return prepared;
|
|
153
|
+
}
|
|
154
|
+
async function applyBacklogMigrations(preparedMigrations) {
|
|
155
|
+
const written = [];
|
|
156
|
+
for (const migration of preparedMigrations) {
|
|
157
|
+
await mkdir(dirname(migration.targetPath), { recursive: true });
|
|
158
|
+
await writeFile(migration.sourcePath, migration.content, 'utf8');
|
|
159
|
+
if (migration.sourcePath !== migration.targetPath) {
|
|
160
|
+
await rename(migration.sourcePath, migration.targetPath);
|
|
161
|
+
}
|
|
162
|
+
written.push(migration.targetPath);
|
|
163
|
+
}
|
|
164
|
+
return written;
|
|
165
|
+
}
|
|
166
|
+
async function planActiveMoves(repoRoot) {
|
|
167
|
+
const actions = [];
|
|
168
|
+
for (const move of ACTIVE_MOVES) {
|
|
169
|
+
const sourcePath = join(repoRoot, move.source);
|
|
170
|
+
const targetPath = join(repoRoot, move.target);
|
|
171
|
+
const sourceExists = await pathExists(sourcePath);
|
|
172
|
+
const targetExists = await pathExists(targetPath);
|
|
173
|
+
if (sourceExists && !targetExists) {
|
|
174
|
+
actions.push({ type: 'move', ...move, result: 'planned' });
|
|
175
|
+
}
|
|
176
|
+
else if (sourceExists && targetExists) {
|
|
177
|
+
actions.push({
|
|
178
|
+
type: 'move',
|
|
179
|
+
...move,
|
|
180
|
+
result: 'skipped',
|
|
181
|
+
reason: 'target already exists; leaving source for manual review',
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return actions;
|
|
186
|
+
}
|
|
187
|
+
async function applyActiveMoves(repoRoot, actions) {
|
|
188
|
+
const moved = [];
|
|
189
|
+
for (const action of actions) {
|
|
190
|
+
if (action.type !== 'move' ||
|
|
191
|
+
action.result !== 'planned' ||
|
|
192
|
+
!action.source ||
|
|
193
|
+
!action.target) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const sourcePath = join(repoRoot, action.source);
|
|
197
|
+
const targetPath = join(repoRoot, action.target);
|
|
198
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
199
|
+
await rename(sourcePath, targetPath);
|
|
200
|
+
action.result = 'applied';
|
|
201
|
+
moved.push(targetPath);
|
|
202
|
+
}
|
|
203
|
+
return moved;
|
|
204
|
+
}
|
|
205
|
+
async function collectJudgmentProposals(repoRoot) {
|
|
206
|
+
const actions = [];
|
|
207
|
+
for (const target of JUDGMENT_TARGETS) {
|
|
208
|
+
if (await pathExists(join(repoRoot, target))) {
|
|
209
|
+
actions.push({
|
|
210
|
+
type: 'propose',
|
|
211
|
+
source: target,
|
|
212
|
+
result: 'planned',
|
|
213
|
+
reason: 'legacy backlog file retirement requires explicit review',
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const referenceRoot = join(repoRoot, 'reference');
|
|
218
|
+
for (const filePath of await listMarkdownFiles(referenceRoot)) {
|
|
219
|
+
const name = basename(filePath);
|
|
220
|
+
if (name !== 'roadmap.md' && name.toLowerCase().includes('roadmap')) {
|
|
221
|
+
actions.push({
|
|
222
|
+
type: 'propose',
|
|
223
|
+
source: relativeToRepo(repoRoot, filePath),
|
|
224
|
+
result: 'planned',
|
|
225
|
+
reason: 'second roadmap disposition requires explicit review',
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return actions;
|
|
230
|
+
}
|
|
231
|
+
async function isAlreadyMigrated(repoRoot) {
|
|
232
|
+
const hasPjm = await pathExists(join(repoRoot, 'pjm'));
|
|
233
|
+
const hasDecisions = await pathExists(join(repoRoot, 'reference', 'decisions'));
|
|
234
|
+
if (!hasPjm || !hasDecisions) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
for (const legacyPath of [
|
|
238
|
+
'reference/current-state.md',
|
|
239
|
+
'reference/roadmap.md',
|
|
240
|
+
'reference/backlog',
|
|
241
|
+
'reference/decision-record.md',
|
|
242
|
+
]) {
|
|
243
|
+
if (await pathExists(join(repoRoot, legacyPath))) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
async function collectDecisionMappings(repoRoot) {
|
|
250
|
+
const referenceRoot = join(repoRoot, 'reference');
|
|
251
|
+
const legacyPath = join(referenceRoot, 'decision-record.md');
|
|
252
|
+
if (!(await pathExists(legacyPath))) {
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
return (await migrateDecisionRecords({
|
|
256
|
+
referenceRoot,
|
|
257
|
+
dryRun: true,
|
|
258
|
+
})).mappings;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Preflights the decision-migration step without mutating anything.
|
|
262
|
+
*
|
|
263
|
+
* Runs the same guards the apply step will run, including the destructive
|
|
264
|
+
* delete-safety guard (`deleteLegacy: true`), but in dry-run mode so it writes
|
|
265
|
+
* and deletes nothing. This is the failure-prone precondition surfaced by
|
|
266
|
+
* dogfooding: an unparseable `decision-record.md` previously aborted only after
|
|
267
|
+
* mechanical moves had already happened. Validating it up front keeps
|
|
268
|
+
* `--apply` atomic — any decision-parse problem fails before the tree changes.
|
|
269
|
+
*/
|
|
270
|
+
async function preflightDecisionMigration(repoRoot) {
|
|
271
|
+
const referenceRoot = join(repoRoot, 'reference');
|
|
272
|
+
const legacyPath = join(referenceRoot, 'decision-record.md');
|
|
273
|
+
if (!(await pathExists(legacyPath))) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
await migrateDecisionRecords({
|
|
277
|
+
referenceRoot,
|
|
278
|
+
deleteLegacy: true,
|
|
279
|
+
dryRun: true,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
async function migrateDecisions(repoRoot) {
|
|
283
|
+
const referenceRoot = join(repoRoot, 'reference');
|
|
284
|
+
const legacyPath = join(referenceRoot, 'decision-record.md');
|
|
285
|
+
if (!(await pathExists(legacyPath))) {
|
|
286
|
+
await initializeDecisionRecords(join(referenceRoot, 'decisions'));
|
|
287
|
+
return { mappings: [], written: [] };
|
|
288
|
+
}
|
|
289
|
+
const result = await migrateDecisionRecords({
|
|
290
|
+
referenceRoot,
|
|
291
|
+
deleteLegacy: true,
|
|
292
|
+
});
|
|
293
|
+
return { mappings: result.mappings, written: result.written };
|
|
294
|
+
}
|
|
295
|
+
function buildEmptyResult(options, status, reason) {
|
|
296
|
+
return {
|
|
297
|
+
repoRoot: options.repoRoot,
|
|
298
|
+
status,
|
|
299
|
+
reason,
|
|
300
|
+
dryRun: !options.apply,
|
|
301
|
+
actions: [],
|
|
302
|
+
backlogMappings: [],
|
|
303
|
+
decisionMappings: [],
|
|
304
|
+
written: [],
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
export async function migratePjmRepo(options) {
|
|
308
|
+
if (!options.projectManagementEnabled) {
|
|
309
|
+
return buildEmptyResult(options, 'skipped', 'project-management pack is disabled');
|
|
310
|
+
}
|
|
311
|
+
if (await isAlreadyMigrated(options.repoRoot)) {
|
|
312
|
+
return buildEmptyResult(options, 'already-migrated');
|
|
313
|
+
}
|
|
314
|
+
const apply = options.apply ?? false;
|
|
315
|
+
const activeMoves = await planActiveMoves(options.repoRoot);
|
|
316
|
+
const judgmentProposals = await collectJudgmentProposals(options.repoRoot);
|
|
317
|
+
const legacyBacklogRoot = join(options.repoRoot, 'reference', 'backlog');
|
|
318
|
+
const pjmBacklogRoot = join(options.repoRoot, 'pjm', 'backlog');
|
|
319
|
+
const backlogRoot = (await pathExists(legacyBacklogRoot))
|
|
320
|
+
? legacyBacklogRoot
|
|
321
|
+
: pjmBacklogRoot;
|
|
322
|
+
const preparedBacklogMigrations = await prepareBacklogMigrations(backlogRoot);
|
|
323
|
+
const decisionMappings = await collectDecisionMappings(options.repoRoot);
|
|
324
|
+
const backlogMappings = preparedBacklogMigrations.map((migration) => migration.mapping);
|
|
325
|
+
const migrationActions = [];
|
|
326
|
+
if (backlogMappings.length > 0) {
|
|
327
|
+
migrationActions.push({
|
|
328
|
+
type: 'migrate-backlog',
|
|
329
|
+
source: relativeToRepo(options.repoRoot, backlogRoot),
|
|
330
|
+
target: 'pjm/backlog',
|
|
331
|
+
result: 'planned',
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
if (decisionMappings.length > 0) {
|
|
335
|
+
migrationActions.push({
|
|
336
|
+
type: 'migrate-decisions',
|
|
337
|
+
source: 'reference/decision-record.md',
|
|
338
|
+
target: 'reference/decisions',
|
|
339
|
+
result: 'planned',
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
const actions = [...activeMoves, ...migrationActions, ...judgmentProposals];
|
|
343
|
+
if (!apply) {
|
|
344
|
+
return {
|
|
345
|
+
repoRoot: options.repoRoot,
|
|
346
|
+
status: 'dry-run',
|
|
347
|
+
dryRun: true,
|
|
348
|
+
actions,
|
|
349
|
+
backlogMappings,
|
|
350
|
+
decisionMappings,
|
|
351
|
+
written: [],
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
// Preflight every failure-prone precondition BEFORE any mechanical mutation so
|
|
355
|
+
// `--apply` is atomic: if a step would fail, we abort here with the tree
|
|
356
|
+
// unchanged. The decision-record parse is the dogfood-surfaced failure mode —
|
|
357
|
+
// an unparseable source previously aborted only after files had already moved,
|
|
358
|
+
// leaving a half-migrated tree.
|
|
359
|
+
await preflightDecisionMigration(options.repoRoot);
|
|
360
|
+
const written = [];
|
|
361
|
+
written.push(...(await applyActiveMoves(options.repoRoot, activeMoves)));
|
|
362
|
+
await initializeRepoReference({
|
|
363
|
+
repoRoot: options.repoRoot,
|
|
364
|
+
assetsRoot: options.assetsRoot,
|
|
365
|
+
templatesRoot: options.templatesRoot,
|
|
366
|
+
});
|
|
367
|
+
const preparedAfterMove = await prepareBacklogMigrations(pjmBacklogRoot);
|
|
368
|
+
written.push(...(await applyBacklogMigrations(preparedAfterMove)));
|
|
369
|
+
if (await pathExists(join(pjmBacklogRoot, 'index.md'))) {
|
|
370
|
+
await regenerateBacklogIndex(pjmBacklogRoot);
|
|
371
|
+
written.push(join(pjmBacklogRoot, 'index.md'));
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
await initializeBacklog(pjmBacklogRoot);
|
|
375
|
+
}
|
|
376
|
+
const decisionResult = await migrateDecisions(options.repoRoot);
|
|
377
|
+
written.push(...decisionResult.written);
|
|
378
|
+
for (const action of migrationActions) {
|
|
379
|
+
action.result = 'applied';
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
repoRoot: options.repoRoot,
|
|
383
|
+
status: 'migrated',
|
|
384
|
+
dryRun: false,
|
|
385
|
+
actions: [...activeMoves, ...migrationActions, ...judgmentProposals],
|
|
386
|
+
backlogMappings: preparedAfterMove.map((migration) => migration.mapping),
|
|
387
|
+
decisionMappings: decisionResult.mappings,
|
|
388
|
+
written,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
export async function readPjmMigrationPrompt(assetsRoot) {
|
|
392
|
+
return readFile(join(assetsRoot, 'migration', 'pjm-restructure.md'), 'utf8');
|
|
393
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-id.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/date-id.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAavD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function yymmdd(isoOrDate) {
|
|
2
|
+
const date = isoOrDate instanceof Date ? new Date(isoOrDate) : new Date(isoOrDate);
|
|
3
|
+
if (Number.isNaN(date.getTime())) {
|
|
4
|
+
throw new Error(`Invalid date for OAT identifier: ${String(isoOrDate)}`);
|
|
5
|
+
}
|
|
6
|
+
const year = String(date.getUTCFullYear() % 100).padStart(2, '0');
|
|
7
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
8
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
9
|
+
return `${year}${month}${day}`;
|
|
10
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ManagedIndexUpdate {
|
|
2
|
+
/**
|
|
3
|
+
* The full file content to write, or `null` when the existing managed block
|
|
4
|
+
* is already content-equal to the target (callers must skip the write to
|
|
5
|
+
* preserve the on-disk bytes, including any external formatter's padding).
|
|
6
|
+
*/
|
|
7
|
+
content: string | null;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Compute the content-idempotent result of regenerating a managed index block.
|
|
11
|
+
*
|
|
12
|
+
* @param existingContent Current on-disk file content (already known to contain
|
|
13
|
+
* the marker pair; bounds are passed in to avoid re-scanning).
|
|
14
|
+
* @param startIndex Index of the start marker within `existingContent`.
|
|
15
|
+
* @param endMarkerEnd Index just past the end marker within `existingContent`.
|
|
16
|
+
* @param renderedBlock Freshly rendered managed block (start marker ... end
|
|
17
|
+
* marker) built from the record files.
|
|
18
|
+
* @returns `{ content: null }` when the logical rows match (skip the write), or
|
|
19
|
+
* `{ content: <full file text> }` when the block must be rewritten.
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeManagedIndexUpdate(existingContent: string, startIndex: number, endMarkerEnd: number, renderedBlock: string): ManagedIndexUpdate;
|
|
22
|
+
//# sourceMappingURL=managed-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managed-index.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/managed-index.ts"],"names":[],"mappings":"AA8EA,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,kBAAkB,CAYpB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Shared helper for content-idempotent managed-index regeneration.
|
|
2
|
+
//
|
|
3
|
+
// Managed index files (decision + backlog) contain a CLI-managed block bounded
|
|
4
|
+
// by a start/end marker pair. The block holds a markdown table whose rows are
|
|
5
|
+
// rebuilt from the per-record files on each `regenerate-index` run.
|
|
6
|
+
//
|
|
7
|
+
// External formatters (oxfmt/prettier/etc.) frequently re-pad the table cells
|
|
8
|
+
// to align columns. Without an idempotence gate, the next `regenerate-index`
|
|
9
|
+
// rewrites the formatter's padding back to CLI padding, producing churn and
|
|
10
|
+
// noise in the "resolve a merge conflict by re-running regenerate" story.
|
|
11
|
+
//
|
|
12
|
+
// This helper compares the EXISTING managed block against the freshly rendered
|
|
13
|
+
// target block by their LOGICAL content (each table cell trimmed of surrounding
|
|
14
|
+
// whitespace), ignoring column padding. When the logical content matches it
|
|
15
|
+
// preserves the on-disk bytes verbatim; only a genuine content change (added,
|
|
16
|
+
// removed, reordered, or changed record) triggers a rewrite. It makes no
|
|
17
|
+
// assumptions about any specific formatter.
|
|
18
|
+
// A markdown table delimiter cell (e.g. `---`, `:---`, `:---:`, `-----`).
|
|
19
|
+
// Formatters freely re-pad the dash count, so any delimiter cell normalizes to
|
|
20
|
+
// a single canonical token and dash-width differences never count as a change.
|
|
21
|
+
//
|
|
22
|
+
// Require at least three dashes so the single-`-` data placeholder (the empty
|
|
23
|
+
// cell value rendered by the index formatters, e.g. `| - |`) is NOT collapsed to
|
|
24
|
+
// the delimiter token. A real markdown delimiter cell always has >= 3 dashes
|
|
25
|
+
// (the existing formatter-repad test uses `---` and `-----`), and formatters
|
|
26
|
+
// only ever widen the dash count, never shrink it below three. Without the lower
|
|
27
|
+
// bound, a data cell whose literal value is `-`/`--`/`:-:` would be
|
|
28
|
+
// indistinguishable from a delimiter cell, so a genuine change between two
|
|
29
|
+
// dash-shaped values could be masked as a no-op and the rewrite skipped.
|
|
30
|
+
const DELIMITER_CELL = /^:?-{3,}:?$/;
|
|
31
|
+
function normalizeCell(cell) {
|
|
32
|
+
const trimmed = cell.trim();
|
|
33
|
+
return DELIMITER_CELL.test(trimmed) ? '---' : trimmed;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parse a managed block's text into a normalized list of rows, where each row
|
|
37
|
+
* is a list of cells trimmed of surrounding whitespace. The marker lines and
|
|
38
|
+
* any blank lines are ignored so that formatter-introduced blank lines or
|
|
39
|
+
* column padding never count as a logical difference.
|
|
40
|
+
*/
|
|
41
|
+
function parseManagedRows(blockText) {
|
|
42
|
+
return blockText
|
|
43
|
+
.split('\n')
|
|
44
|
+
.map((line) => line.trim())
|
|
45
|
+
.filter((line) => line.length > 0)
|
|
46
|
+
.filter((line) => !line.startsWith('<!--'))
|
|
47
|
+
.map((line) => {
|
|
48
|
+
// A markdown table row is `| cell | cell | ... |`. Drop the leading and
|
|
49
|
+
// trailing pipe, then split on unescaped pipes and normalize each cell.
|
|
50
|
+
const inner = line.replace(/^\|/, '').replace(/\|$/, '');
|
|
51
|
+
return inner.split('|').map((cell) => normalizeCell(cell));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function rowsEqual(a, b) {
|
|
55
|
+
if (a.length !== b.length) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
for (let rowIndex = 0; rowIndex < a.length; rowIndex += 1) {
|
|
59
|
+
const rowA = a[rowIndex];
|
|
60
|
+
const rowB = b[rowIndex];
|
|
61
|
+
if (rowA.length !== rowB.length) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
for (let cellIndex = 0; cellIndex < rowA.length; cellIndex += 1) {
|
|
65
|
+
if (rowA[cellIndex] !== rowB[cellIndex]) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Compute the content-idempotent result of regenerating a managed index block.
|
|
74
|
+
*
|
|
75
|
+
* @param existingContent Current on-disk file content (already known to contain
|
|
76
|
+
* the marker pair; bounds are passed in to avoid re-scanning).
|
|
77
|
+
* @param startIndex Index of the start marker within `existingContent`.
|
|
78
|
+
* @param endMarkerEnd Index just past the end marker within `existingContent`.
|
|
79
|
+
* @param renderedBlock Freshly rendered managed block (start marker ... end
|
|
80
|
+
* marker) built from the record files.
|
|
81
|
+
* @returns `{ content: null }` when the logical rows match (skip the write), or
|
|
82
|
+
* `{ content: <full file text> }` when the block must be rewritten.
|
|
83
|
+
*/
|
|
84
|
+
export function computeManagedIndexUpdate(existingContent, startIndex, endMarkerEnd, renderedBlock) {
|
|
85
|
+
const existingBlock = existingContent.slice(startIndex, endMarkerEnd);
|
|
86
|
+
if (rowsEqual(parseManagedRows(existingBlock), parseManagedRows(renderedBlock))) {
|
|
87
|
+
return { content: null };
|
|
88
|
+
}
|
|
89
|
+
const before = existingContent.slice(0, startIndex);
|
|
90
|
+
const after = existingContent.slice(endMarkerEnd);
|
|
91
|
+
return { content: `${before}${renderedBlock}${after}` };
|
|
92
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/slug.ts"],"names":[],"mappings":"AAiDA,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmB7C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const MAX_SLUG_LENGTH = 30;
|
|
2
|
+
const STOP_WORDS = new Set([
|
|
3
|
+
'a',
|
|
4
|
+
'an',
|
|
5
|
+
'the',
|
|
6
|
+
'of',
|
|
7
|
+
'for',
|
|
8
|
+
'and',
|
|
9
|
+
'to',
|
|
10
|
+
'in',
|
|
11
|
+
'on',
|
|
12
|
+
'as',
|
|
13
|
+
'with',
|
|
14
|
+
]);
|
|
15
|
+
function truncateToWordBoundary(slug) {
|
|
16
|
+
if (slug.length <= MAX_SLUG_LENGTH) {
|
|
17
|
+
return slug;
|
|
18
|
+
}
|
|
19
|
+
const [first, ...rest] = slug.split('-');
|
|
20
|
+
const firstWord = first ?? '';
|
|
21
|
+
// Edge case: the first word alone exceeds the limit. Hard-truncate it.
|
|
22
|
+
if (firstWord.length > MAX_SLUG_LENGTH) {
|
|
23
|
+
return firstWord.slice(0, MAX_SLUG_LENGTH);
|
|
24
|
+
}
|
|
25
|
+
let result = firstWord;
|
|
26
|
+
for (const word of rest) {
|
|
27
|
+
const candidate = `${result}-${word}`;
|
|
28
|
+
if (candidate.length > MAX_SLUG_LENGTH) {
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
result = candidate;
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
function stripTrailingStopWords(slug) {
|
|
36
|
+
const words = slug.split('-');
|
|
37
|
+
while (words.length > 0 && STOP_WORDS.has(words[words.length - 1] ?? '')) {
|
|
38
|
+
words.pop();
|
|
39
|
+
}
|
|
40
|
+
return words.join('-');
|
|
41
|
+
}
|
|
42
|
+
export function slugify(input) {
|
|
43
|
+
const normalized = input
|
|
44
|
+
.normalize('NFKD')
|
|
45
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
46
|
+
.toLowerCase();
|
|
47
|
+
const slug = normalized
|
|
48
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
49
|
+
.replace(/^-+|-+$/g, '')
|
|
50
|
+
.replace(/-+/g, '-');
|
|
51
|
+
if (slug.length === 0) {
|
|
52
|
+
return 'untitled';
|
|
53
|
+
}
|
|
54
|
+
const truncated = truncateToWordBoundary(slug);
|
|
55
|
+
const trimmed = stripTrailingStopWords(truncated);
|
|
56
|
+
return trimmed || 'untitled';
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strip-template-frontmatter.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/strip-template-frontmatter.ts"],"names":[],"mappings":"AAAA,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBhE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function stripTemplateFrontmatter(content) {
|
|
2
|
+
if (!content.startsWith('---\n')) {
|
|
3
|
+
return content;
|
|
4
|
+
}
|
|
5
|
+
const end = content.indexOf('\n---', 4);
|
|
6
|
+
if (end === -1) {
|
|
7
|
+
return content;
|
|
8
|
+
}
|
|
9
|
+
const frontmatter = content.slice(4, end);
|
|
10
|
+
if (!/\boat_template\s*:/i.test(frontmatter) &&
|
|
11
|
+
!/\boat_template_name\s*:/i.test(frontmatter)) {
|
|
12
|
+
return content;
|
|
13
|
+
}
|
|
14
|
+
const afterFrontmatter = content.slice(end + '\n---'.length);
|
|
15
|
+
return afterFrontmatter.replace(/^\r?\n+/, '');
|
|
16
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/engine/hook.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,iBAAiB,kCAAkC,CAAC;AACjE,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,eAAO,MAAM,kBAAkB,iFACiD,CAAC;AACjF,eAAO,MAAM,eAAe,wFAC2D,CAAC;AACxF,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,eAAe,GAAG,YAAY,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,UAAU,mBAAmB;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/engine/hook.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,iBAAiB,kCAAkC,CAAC;AACjE,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,eAAO,MAAM,kBAAkB,iFACiD,CAAC;AACjF,eAAO,MAAM,eAAe,wFAC2D,CAAC;AACxF,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,eAAe,GAAG,YAAY,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,UAAU,mBAAmB;IAC3B,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAuID,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB3E;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgCtE;AAuBD,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCtE;AA8BD,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CA2BjC"}
|
package/dist/engine/hook.js
CHANGED
|
@@ -74,6 +74,19 @@ async function resolveHooksDirectory(projectRoot, options = {}) {
|
|
|
74
74
|
}
|
|
75
75
|
return configuredPath;
|
|
76
76
|
}
|
|
77
|
+
try {
|
|
78
|
+
const { stdout } = await execFileAsync('git', ['rev-parse', '--path-format=absolute', '--git-path', 'hooks'], { cwd: projectRoot });
|
|
79
|
+
const gitHooksDir = stdout.trim();
|
|
80
|
+
if (gitHooksDir) {
|
|
81
|
+
if (shouldCreate) {
|
|
82
|
+
await ensureDir(gitHooksDir);
|
|
83
|
+
}
|
|
84
|
+
return gitHooksDir;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Fall back to filesystem resolution for tests and nonstandard fixtures.
|
|
89
|
+
}
|
|
77
90
|
const gitDir = await resolveGitDirectory(projectRoot);
|
|
78
91
|
const hooksDir = join(gitDir, 'hooks');
|
|
79
92
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-package-contract.d.ts","sourceRoot":"","sources":["../../src/release/public-package-contract.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,KAAK,GAAG,cAAc,GAAG,iBAAiB,CAAC;IACjD,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,4BAA4B,EAAE,MAAM,EAAE,CAAC;IACvC,2BAA2B,EAAE,MAAM,EAAE,CAAC;CACvC;
|
|
1
|
+
{"version":3,"file":"public-package-contract.d.ts","sourceRoot":"","sources":["../../src/release/public-package-contract.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,KAAK,GAAG,cAAc,GAAG,iBAAiB,CAAC;IACjD,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,4BAA4B,EAAE,MAAM,EAAE,CAAC;IACvC,2BAA2B,EAAE,MAAM,EAAE,CAAC;CACvC;AAmHD,wBAAgB,yBAAyB,IAAI,qBAAqB,EAAE,CASnE;AAED,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,EAAE,qBAAqB,GAC9B,MAAM,EAAE,CAIV;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,QAAQ,EAAE,qBAAqB,GAC9B,MAAM,EAAE,CAIV;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,QAAQ,EAAE,qBAAqB,GAC9B,MAAM,EAAE,CAMV;AAED,wBAAgB,oCAAoC,CAClD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,MAAM,EAAE,CAmBV;AAED,wBAAgB,qCAAqC,CACnD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,kBAAkB,EAAE,SAAS,MAAM,EAAE,EACrC,qBAAqB,EAAE,SAAS,MAAM,EAAE,GACvC,MAAM,EAAE,CA0BV"}
|