pm4ai 0.0.6
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.
Potentially problematic release.
This version of pm4ai might be problematic. Click here for more details.
- package/dist/audit.d.ts +20 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +254 -0
- package/dist/audit.js.map +1 -0
- package/dist/check-cache.d.ts +21 -0
- package/dist/check-cache.d.ts.map +1 -0
- package/dist/check-cache.js +89 -0
- package/dist/check-cache.js.map +1 -0
- package/dist/check-worker.d.ts +2 -0
- package/dist/check-worker.d.ts.map +1 -0
- package/dist/check-worker.js +42 -0
- package/dist/check-worker.js.map +1 -0
- package/dist/checks.d.ts +11 -0
- package/dist/checks.d.ts.map +1 -0
- package/dist/checks.js +176 -0
- package/dist/checks.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +44 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.d.ts +22 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +22 -0
- package/dist/constants.js.map +1 -0
- package/dist/discover.d.ts +19 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +132 -0
- package/dist/discover.js.map +1 -0
- package/dist/fix.d.ts +5 -0
- package/dist/fix.d.ts.map +1 -0
- package/dist/fix.js +182 -0
- package/dist/fix.js.map +1 -0
- package/dist/format.d.ts +9 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +93 -0
- package/dist/format.js.map +1 -0
- package/dist/guide.d.ts +2 -0
- package/dist/guide.d.ts.map +1 -0
- package/dist/guide.js +50 -0
- package/dist/guide.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/infer.d.ts +4 -0
- package/dist/infer.d.ts.map +1 -0
- package/dist/infer.js +56 -0
- package/dist/infer.js.map +1 -0
- package/dist/init.d.ts +3 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +75 -0
- package/dist/init.js.map +1 -0
- package/dist/log.d.ts +12 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +26 -0
- package/dist/log.js.map +1 -0
- package/dist/preflight.d.ts +3 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +29 -0
- package/dist/preflight.js.map +1 -0
- package/dist/setup.d.ts +3 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +67 -0
- package/dist/setup.js.map +1 -0
- package/dist/status.d.ts +4 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +66 -0
- package/dist/status.js.map +1 -0
- package/dist/sync.d.ts +9 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +301 -0
- package/dist/sync.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +15 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +83 -0
- package/dist/utils.js.map +1 -0
- package/package.json +42 -0
package/dist/fix.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { $ } from 'bun';
|
|
3
|
+
import { closeSync, copyFileSync, existsSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { audit } from './audit.js';
|
|
7
|
+
import { writeCheckResult } from './check-cache.js';
|
|
8
|
+
import { READONLY_UI } from './constants.js';
|
|
9
|
+
import { discover, discoverSources } from './discover.js';
|
|
10
|
+
import { updateLog } from './log.js';
|
|
11
|
+
import { syncClaudeMd, syncConfigs, syncPackageJson, syncSubPackages, syncTsconfig, syncUi } from './sync.js';
|
|
12
|
+
import { isInsideProject, projectName } from './utils.js';
|
|
13
|
+
const violationRe = /(?<count>\d+)\s*(?:error|violation|problem|issue)/iu;
|
|
14
|
+
const maintain = async (projectPath) => {
|
|
15
|
+
const issues = [];
|
|
16
|
+
const upSh = join(projectPath, 'up.sh');
|
|
17
|
+
if (!existsSync(upSh)) {
|
|
18
|
+
issues.push({ detail: 'missing, cannot maintain', type: 'up.sh' });
|
|
19
|
+
return issues;
|
|
20
|
+
}
|
|
21
|
+
const result = await $ `sh up.sh`.cwd(projectPath).quiet().nothrow();
|
|
22
|
+
const { exitCode } = result;
|
|
23
|
+
const stderr = result.stderr.toString().trim();
|
|
24
|
+
if (exitCode === 0) {
|
|
25
|
+
const snapshotDir = join(homedir(), '.pm4ai', 'snapshots', projectName(projectPath));
|
|
26
|
+
const lockfile = join(projectPath, 'bun.lock');
|
|
27
|
+
if (existsSync(lockfile)) {
|
|
28
|
+
mkdirSync(snapshotDir, { recursive: true });
|
|
29
|
+
copyFileSync(lockfile, join(snapshotDir, 'bun.lock'));
|
|
30
|
+
}
|
|
31
|
+
writeCheckResult({ pass: true, projectPath, violations: 0 });
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const errorLine = stderr.split('\n').findLast(Boolean) ?? 'unknown error';
|
|
35
|
+
issues.push({ detail: `failed: ${errorLine}`, type: 'up.sh' });
|
|
36
|
+
const violationMatch = violationRe.exec(stderr);
|
|
37
|
+
const violations = violationMatch?.groups?.count ? Number.parseInt(violationMatch.groups.count, 10) : 1;
|
|
38
|
+
writeCheckResult({ pass: false, projectPath, summary: errorLine, violations });
|
|
39
|
+
}
|
|
40
|
+
updateLog({
|
|
41
|
+
at: new Date().toISOString(),
|
|
42
|
+
error: exitCode === 0 ? undefined : stderr.slice(0, 500),
|
|
43
|
+
pass: exitCode === 0,
|
|
44
|
+
path: projectPath,
|
|
45
|
+
project: projectName(projectPath)
|
|
46
|
+
});
|
|
47
|
+
return issues;
|
|
48
|
+
};
|
|
49
|
+
export { maintain };
|
|
50
|
+
export const fix = async (all = false) => {
|
|
51
|
+
const lockFile = join(homedir(), '.pm4ai', 'fix.lock');
|
|
52
|
+
mkdirSync(join(homedir(), '.pm4ai'), { recursive: true });
|
|
53
|
+
const lockData = JSON.stringify({ at: new Date().toISOString(), pid: process.pid });
|
|
54
|
+
const tryAcquireLock = () => {
|
|
55
|
+
try {
|
|
56
|
+
const fd = openSync(lockFile, 'wx');
|
|
57
|
+
writeFileSync(fd, lockData);
|
|
58
|
+
closeSync(fd);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
if (!tryAcquireLock()) {
|
|
66
|
+
try {
|
|
67
|
+
const lock = JSON.parse(readFileSync(lockFile, 'utf8'));
|
|
68
|
+
const age = Date.now() - new Date(lock.at).getTime();
|
|
69
|
+
let alive = false;
|
|
70
|
+
try {
|
|
71
|
+
process.kill(lock.pid, 0);
|
|
72
|
+
alive = true;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
/* Process not found */
|
|
76
|
+
}
|
|
77
|
+
if (alive && age < 600_000) {
|
|
78
|
+
console.log('another fix is already running');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
/* Corrupt lock */
|
|
84
|
+
}
|
|
85
|
+
rmSync(lockFile, { force: true });
|
|
86
|
+
if (!tryAcquireLock()) {
|
|
87
|
+
console.log('another fix is already running');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const resolveTargets = async () => {
|
|
93
|
+
if (all)
|
|
94
|
+
return discover();
|
|
95
|
+
const projectPath = await isInsideProject();
|
|
96
|
+
if (projectPath) {
|
|
97
|
+
const { self, cnsync } = await discoverSources();
|
|
98
|
+
return {
|
|
99
|
+
cnsync,
|
|
100
|
+
consumers: [{ isCnsync: false, isSelf: false, name: projectName(projectPath), path: projectPath }],
|
|
101
|
+
self
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return discover();
|
|
105
|
+
};
|
|
106
|
+
const { cnsync, consumers, self } = await resolveTargets();
|
|
107
|
+
console.log(`found ${consumers.length} projects`);
|
|
108
|
+
console.log();
|
|
109
|
+
const allRepos = [self, cnsync, ...consumers];
|
|
110
|
+
const blocked = [];
|
|
111
|
+
const pullable = [];
|
|
112
|
+
const checkResults = await Promise.all(allRepos.map(async (repo) => {
|
|
113
|
+
const name = projectName(repo.path);
|
|
114
|
+
const dirty = await $ `git status --porcelain`.cwd(repo.path).quiet().nothrow();
|
|
115
|
+
if (dirty.stdout.toString().trim())
|
|
116
|
+
return { name, reason: 'uncommitted changes' };
|
|
117
|
+
await $ `git fetch`.cwd(repo.path).quiet().nothrow();
|
|
118
|
+
const behind = await $ `git rev-list --count HEAD..@{u}`.cwd(repo.path).quiet().nothrow();
|
|
119
|
+
const ahead = await $ `git rev-list --count @{u}..HEAD`.cwd(repo.path).quiet().nothrow();
|
|
120
|
+
const b = Number.parseInt(behind.stdout.toString().trim(), 10);
|
|
121
|
+
const a = Number.parseInt(ahead.stdout.toString().trim(), 10);
|
|
122
|
+
if (b > 0 && a > 0)
|
|
123
|
+
return { name, reason: `diverged (${b} behind, ${a} ahead)` };
|
|
124
|
+
if (a > 0)
|
|
125
|
+
return { name, reason: `${a} commits ahead, push first` };
|
|
126
|
+
return { behind: b, name, path: repo.path };
|
|
127
|
+
}));
|
|
128
|
+
for (const r of checkResults)
|
|
129
|
+
if ('reason' in r)
|
|
130
|
+
blocked.push(`${r.name}: ${r.reason}`);
|
|
131
|
+
else if (r.behind > 0)
|
|
132
|
+
pullable.push({ name: r.name, path: r.path });
|
|
133
|
+
if (blocked.length > 0) {
|
|
134
|
+
console.log('fix requires clean git state:');
|
|
135
|
+
for (const msg of blocked)
|
|
136
|
+
console.log(` ${msg}`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
await Promise.all(pullable.map(async (repo) => {
|
|
140
|
+
await $ `git pull`.cwd(repo.path).quiet().nothrow();
|
|
141
|
+
console.log(`${repo.name}: pulled`);
|
|
142
|
+
}));
|
|
143
|
+
const tasks = consumers.map(async (project) => {
|
|
144
|
+
const issues = [];
|
|
145
|
+
const [configIssues, claudeIssues, pkgIssues, tsconfigIssues] = await Promise.all([
|
|
146
|
+
syncConfigs(self.path, project.path),
|
|
147
|
+
syncClaudeMd(self.path, project.path),
|
|
148
|
+
syncPackageJson(project.path),
|
|
149
|
+
syncTsconfig(project.path)
|
|
150
|
+
]);
|
|
151
|
+
const subPkgIssues = await syncSubPackages(self.path, project.path);
|
|
152
|
+
issues.push(...configIssues, ...claudeIssues, ...pkgIssues, ...tsconfigIssues, ...subPkgIssues);
|
|
153
|
+
if (existsSync(join(project.path, READONLY_UI)))
|
|
154
|
+
issues.push(...syncUi(cnsync.path, project.path));
|
|
155
|
+
const auditIssues = await audit(project.path);
|
|
156
|
+
issues.push(...auditIssues);
|
|
157
|
+
const maintainIssues = await maintain(project.path);
|
|
158
|
+
issues.push(...maintainIssues);
|
|
159
|
+
if (issues.length > 0) {
|
|
160
|
+
const lines = [project.path, ...issues.map(i => ` ${i.type} ${i.detail}`)];
|
|
161
|
+
console.log(lines.join('\n'));
|
|
162
|
+
console.log();
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
await Promise.all(tasks);
|
|
166
|
+
console.log('--- changes ---');
|
|
167
|
+
const summaries = await Promise.all(consumers.map(async (project) => {
|
|
168
|
+
const diff = await $ `git status --porcelain`.cwd(project.path).quiet().nothrow();
|
|
169
|
+
const changed = diff.stdout.toString().trim();
|
|
170
|
+
const count = changed ? changed.split('\n').length : 0;
|
|
171
|
+
return count > 0 ? `${projectName(project.path)}: ${count} files modified` : `${projectName(project.path)}: clean`;
|
|
172
|
+
}));
|
|
173
|
+
for (const s of summaries)
|
|
174
|
+
console.log(s);
|
|
175
|
+
if (process.platform === 'darwin')
|
|
176
|
+
await $ `open swiftbar://refreshplugin?name=pm4ai`.quiet().nothrow();
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
rmSync(lockFile, { force: true });
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
//# sourceMappingURL=fix.js.map
|
package/dist/fix.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.js","sourceRoot":"","sources":["../src/fix.ts"],"names":[],"mappings":"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"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Issue } from './types.js';
|
|
2
|
+
declare const shellEscape: (s: string) => string;
|
|
3
|
+
declare const hasRealIssues: (issues: Issue[]) => boolean;
|
|
4
|
+
declare const formatIssues: (projectPath: string, issues: Issue[]) => string;
|
|
5
|
+
declare const timeAgo: (iso: string) => string;
|
|
6
|
+
declare const getUiSyncTime: (allPaths: string[]) => Promise<string>;
|
|
7
|
+
declare const formatSwiftBar: (allIssues: Map<string, Issue[]>) => Promise<string>;
|
|
8
|
+
export { formatIssues, formatSwiftBar, getUiSyncTime, hasRealIssues, shellEscape, timeAgo };
|
|
9
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGvC,QAAA,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,MAAoD,CAAA;AAErF,QAAA,MAAM,aAAa,GAAI,QAAQ,KAAK,EAAE,YAAqC,CAAA;AAC3E,QAAA,MAAM,YAAY,GAAI,aAAa,MAAM,EAAE,QAAQ,KAAK,EAAE,KAAG,MAI5D,CAAA;AACD,QAAA,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MAO9B,CAAA;AACD,QAAA,MAAM,aAAa,GAAU,UAAU,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAS/D,CAAA;AACD,QAAA,MAAM,cAAc,GAAU,WAAW,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,KAAG,OAAO,CAAC,MAAM,CAsD7E,CAAA;AACD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,CAAA"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { $ } from 'bun';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { getBunVersion, getGhRepo, projectName } from './utils.js';
|
|
5
|
+
const shellMetaRe = /[^\w\s./:@=-]/gu;
|
|
6
|
+
const shellEscape = (s) => s.replaceAll(shellMetaRe, String.raw `\$&`);
|
|
7
|
+
const isInfoOnly = (i) => i.type === 'info' || (i.type === 'check' && !i.detail.startsWith('failed'));
|
|
8
|
+
const hasRealIssues = (issues) => issues.some(i => !isInfoOnly(i));
|
|
9
|
+
const formatIssues = (projectPath, issues) => {
|
|
10
|
+
if (issues.length === 0)
|
|
11
|
+
return '';
|
|
12
|
+
const lines = [projectPath, ...issues.map(issue => ` ${issue.type} ${issue.detail}`)];
|
|
13
|
+
return lines.join('\n');
|
|
14
|
+
};
|
|
15
|
+
const timeAgo = (iso) => {
|
|
16
|
+
const ms = Date.now() - new Date(iso).getTime();
|
|
17
|
+
const mins = Math.floor(ms / 60_000);
|
|
18
|
+
if (mins < 60)
|
|
19
|
+
return `${mins}m ago`;
|
|
20
|
+
const hours = Math.floor(mins / 60);
|
|
21
|
+
if (hours < 24)
|
|
22
|
+
return `${hours}h ago`;
|
|
23
|
+
return `${Math.floor(hours / 24)}d ago`;
|
|
24
|
+
};
|
|
25
|
+
const getUiSyncTime = async (allPaths) => {
|
|
26
|
+
const uiDirs = allPaths.map(p => join(p, 'readonly', 'ui', 'src')).filter(d => existsSync(d));
|
|
27
|
+
if (uiDirs.length === 0)
|
|
28
|
+
return '?';
|
|
29
|
+
const r = await $ `git log -1 --format=%ci -- readonly/ui`
|
|
30
|
+
.cwd(allPaths.find(p => existsSync(join(p, 'readonly', 'ui', 'src'))) ?? '')
|
|
31
|
+
.quiet()
|
|
32
|
+
.nothrow();
|
|
33
|
+
const out = r.stdout.toString().trim();
|
|
34
|
+
return out ? timeAgo(new Date(out).toISOString()) : '?';
|
|
35
|
+
};
|
|
36
|
+
const formatSwiftBar = async (allIssues) => {
|
|
37
|
+
const anyReal = [...allIssues.values()].some(hasRealIssues);
|
|
38
|
+
const total = allIssues.size;
|
|
39
|
+
const clean = [...allIssues.values()].filter(i => !hasRealIssues(i)).length;
|
|
40
|
+
const totalIssues = [...allIssues.values()].flatMap(i => i.filter(x => x.type !== 'info')).length;
|
|
41
|
+
const paths = [...allIssues.keys()];
|
|
42
|
+
const [repos, bunVer, uiSync] = await Promise.all([
|
|
43
|
+
Promise.all(paths.map(async (p) => getGhRepo(p))),
|
|
44
|
+
getBunVersion(),
|
|
45
|
+
getUiSyncTime(paths)
|
|
46
|
+
]);
|
|
47
|
+
const repoMap = new Map(paths.map((p, i) => [p, repos[i]]));
|
|
48
|
+
const lines = [];
|
|
49
|
+
if (anyReal)
|
|
50
|
+
lines.push(`${clean}/${total} | sfimage=xmark.circle.fill sfcolor=red`);
|
|
51
|
+
else
|
|
52
|
+
lines.push(`${total}/${total} | sfimage=checkmark.circle.fill sfcolor=green`);
|
|
53
|
+
const f = '| font=Menlo size=13';
|
|
54
|
+
lines.push('---');
|
|
55
|
+
lines.push(`${total} projects ${totalIssues} issues bun ${bunVer} ui ${uiSync} ${f}`);
|
|
56
|
+
lines.push('---');
|
|
57
|
+
const maxName = Math.max(...[...allIssues.keys()].map(p => projectName(p).length));
|
|
58
|
+
const allIssueLines = [];
|
|
59
|
+
for (const [path, issues] of allIssues) {
|
|
60
|
+
const name = projectName(path).padEnd(maxName);
|
|
61
|
+
const repo = repoMap.get(path);
|
|
62
|
+
const ghUrl = repo ? `https://github.com/${repo}` : '';
|
|
63
|
+
const ciInfo = issues.find(i => i.type === 'info');
|
|
64
|
+
const ciTime = (ciInfo ? timeAgo(ciInfo.detail.replace('passed ', '').replace('failed ', '')) : '').padEnd(6);
|
|
65
|
+
const realIssues = issues.filter(i => i.type !== 'info');
|
|
66
|
+
const mark = realIssues.length > 0 ? '🔴' : '🟢';
|
|
67
|
+
const warn = realIssues.length > 0 ? ` ${realIssues.length} issues` : '';
|
|
68
|
+
lines.push(`${mark} ${name} ${ciTime}${warn} ${f}`);
|
|
69
|
+
if (realIssues.length > 0)
|
|
70
|
+
for (const issue of realIssues) {
|
|
71
|
+
lines.push(`--${issue.detail} ${f} color=#ff6b6b`);
|
|
72
|
+
allIssueLines.push(`${name.trim()}: ${issue.detail}`);
|
|
73
|
+
}
|
|
74
|
+
if (ghUrl)
|
|
75
|
+
lines.push(`--GitHub | href=${ghUrl}`);
|
|
76
|
+
lines.push(`--VS Code | bash=/usr/bin/open param1=-a param2=Visual\\ Studio\\ Code param3=${path} terminal=false`);
|
|
77
|
+
lines.push(`--Ghostty | bash=/usr/bin/open param1=-a param2=Ghostty param3=--working-directory=${path} terminal=false`);
|
|
78
|
+
if (realIssues.length > 0) {
|
|
79
|
+
const issueText = realIssues.map(i => shellEscape(i.detail)).join(String.raw `\n`);
|
|
80
|
+
lines.push(`--Copy Issues | bash=/bin/bash param1=-c param2='echo "${issueText}" | pbcopy' terminal=false`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (totalIssues > 0) {
|
|
84
|
+
lines.push('---');
|
|
85
|
+
const allText = allIssueLines.map(l => shellEscape(l)).join(String.raw `\n`);
|
|
86
|
+
lines.push(`Copy All Issues (${totalIssues}) | bash=/bin/bash param1=-c param2='echo "${allText}" | pbcopy' terminal=false`);
|
|
87
|
+
}
|
|
88
|
+
lines.push('---');
|
|
89
|
+
lines.push('Refresh | refresh=true');
|
|
90
|
+
return lines.join('\n');
|
|
91
|
+
};
|
|
92
|
+
export { formatIssues, formatSwiftBar, getUiSyncTime, hasRealIssues, shellEscape, timeAgo };
|
|
93
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/guide.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const guide = "pm4ai \u2014 agent-first anti-slop project management for TypeScript monorepos\ndiscovers projects by scanning for lintmax in package.json deps\ndiscovers itself and cnsync the same way (auto-clones if not found)\ncontext-aware: inside a project, operates on that project only\ncommands:\n pm4ai this guide\n pm4ai status check current project (or all if outside a project)\n pm4ai fix sync + maintain current project (requires clean git)\n pm4ai init <n> scaffold a new pm4ai-ready project\n pm4ai setup install swiftbar menubar plugin + launchd daily auto-run\nflags:\n --all force global scan across all projects\n --swiftbar output in SwiftBar menubar format\n --verbose print debug info to stderr\nfix behavior:\n blocks if git is dirty, behind remote, or ahead (unpushed)\n syncs: clean.sh, up.sh, bunfig.toml, .gitignore, CLAUDE.md, readonly/ui\n maintains: runs sh up.sh (clean + install + build + fix + check)\n shows file change summary after completion\nstatus output (only issues shown, healthy projects omitted):\n /path/to/project\n git 3 commits behind remote\n file clean.sh out of sync\n missing turbo.json\n drift clean should start with \"sh clean.sh\"\n dep react should be \"latest\" or \"^major\"\n duplicate ai already provided by workspace dep\n forbidden npm found, use bun only\n ci failed 2026-04-02\n deploy vercel deployment failed\n check failed 5m ago (current), 15 violations\n check passed 0m ago (current)\nchecks:\n git status, behind/ahead remote\n config drift (synced files match source)\n missing infra (turbo.json, tsconfig.json, ci.yml)\n root package.json (private, packageManager, hooks, sherif, prepare, clean)\n tsconfig extends lintmax/tsconfig\n vercel.json installCommand is bun i\n vercel deployment status\n deps on latest or ^major, no duplicates across workspaces\n no npm/yarn/pnpm in scripts or lockfiles\n turbo scripts have --output-logs=errors-only\n published packages have type:module, exports, files, license, repository\n workspace devDependencies hoisted to root\n no nested .gitignore, no postcss.config.mjs, no @ts-nocheck\n no bun.lock tracked in git, no redundant clean scripts in sub-packages\n ci status via github api\n background lint check with commit-aware staleness detection";
|
|
2
|
+
//# sourceMappingURL=guide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../src/guide.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,g0EAgD4C,CAAA"}
|
package/dist/guide.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const guide = `pm4ai — agent-first anti-slop project management for TypeScript monorepos
|
|
2
|
+
discovers projects by scanning for lintmax in package.json deps
|
|
3
|
+
discovers itself and cnsync the same way (auto-clones if not found)
|
|
4
|
+
context-aware: inside a project, operates on that project only
|
|
5
|
+
commands:
|
|
6
|
+
pm4ai this guide
|
|
7
|
+
pm4ai status check current project (or all if outside a project)
|
|
8
|
+
pm4ai fix sync + maintain current project (requires clean git)
|
|
9
|
+
pm4ai init <n> scaffold a new pm4ai-ready project
|
|
10
|
+
pm4ai setup install swiftbar menubar plugin + launchd daily auto-run
|
|
11
|
+
flags:
|
|
12
|
+
--all force global scan across all projects
|
|
13
|
+
--swiftbar output in SwiftBar menubar format
|
|
14
|
+
--verbose print debug info to stderr
|
|
15
|
+
fix behavior:
|
|
16
|
+
blocks if git is dirty, behind remote, or ahead (unpushed)
|
|
17
|
+
syncs: clean.sh, up.sh, bunfig.toml, .gitignore, CLAUDE.md, readonly/ui
|
|
18
|
+
maintains: runs sh up.sh (clean + install + build + fix + check)
|
|
19
|
+
shows file change summary after completion
|
|
20
|
+
status output (only issues shown, healthy projects omitted):
|
|
21
|
+
/path/to/project
|
|
22
|
+
git 3 commits behind remote
|
|
23
|
+
file clean.sh out of sync
|
|
24
|
+
missing turbo.json
|
|
25
|
+
drift clean should start with "sh clean.sh"
|
|
26
|
+
dep react should be "latest" or "^major"
|
|
27
|
+
duplicate ai already provided by workspace dep
|
|
28
|
+
forbidden npm found, use bun only
|
|
29
|
+
ci failed 2026-04-02
|
|
30
|
+
deploy vercel deployment failed
|
|
31
|
+
check failed 5m ago (current), 15 violations
|
|
32
|
+
check passed 0m ago (current)
|
|
33
|
+
checks:
|
|
34
|
+
git status, behind/ahead remote
|
|
35
|
+
config drift (synced files match source)
|
|
36
|
+
missing infra (turbo.json, tsconfig.json, ci.yml)
|
|
37
|
+
root package.json (private, packageManager, hooks, sherif, prepare, clean)
|
|
38
|
+
tsconfig extends lintmax/tsconfig
|
|
39
|
+
vercel.json installCommand is bun i
|
|
40
|
+
vercel deployment status
|
|
41
|
+
deps on latest or ^major, no duplicates across workspaces
|
|
42
|
+
no npm/yarn/pnpm in scripts or lockfiles
|
|
43
|
+
turbo scripts have --output-logs=errors-only
|
|
44
|
+
published packages have type:module, exports, files, license, repository
|
|
45
|
+
workspace devDependencies hoisted to root
|
|
46
|
+
no nested .gitignore, no postcss.config.mjs, no @ts-nocheck
|
|
47
|
+
no bun.lock tracked in git, no redundant clean scripts in sub-packages
|
|
48
|
+
ci status via github api
|
|
49
|
+
background lint check with commit-aware staleness detection`;
|
|
50
|
+
//# sourceMappingURL=guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guide.js","sourceRoot":"","sources":["../src/guide.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8DAgDyC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { audit } from './audit.js';
|
|
2
|
+
export { discover } from './discover.js';
|
|
3
|
+
export { fix } from './fix.js';
|
|
4
|
+
export { guide } from './guide.js';
|
|
5
|
+
export { inferRules } from './infer.js';
|
|
6
|
+
export { status } from './status.js';
|
|
7
|
+
export type { Issue, IssueType, PackageJson } from './types.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { audit } from './audit.js';
|
|
2
|
+
export { discover } from './discover.js';
|
|
3
|
+
export { fix } from './fix.js';
|
|
4
|
+
export { guide } from './guide.js';
|
|
5
|
+
export { inferRules } from './infer.js';
|
|
6
|
+
export { status } from './status.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/infer.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infer.d.ts","sourceRoot":"","sources":["../src/infer.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,gBAAgB,GAAI,SAAS,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAUhE,CAAA;AAkBD,QAAA,MAAM,UAAU,GAAU,aAAa,MAAM,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CAelF,CAAA;AACD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAA"}
|
package/dist/infer.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { collectWorkspacePackages } from './utils.js';
|
|
4
|
+
const parseFrontmatter = (content) => {
|
|
5
|
+
if (!content.startsWith('---'))
|
|
6
|
+
return {};
|
|
7
|
+
const endIdx = content.indexOf('---', 3);
|
|
8
|
+
if (endIdx === -1)
|
|
9
|
+
return {};
|
|
10
|
+
const fm = {};
|
|
11
|
+
for (const line of content.slice(3, endIdx).trim().split('\n')) {
|
|
12
|
+
const colon = line.indexOf(':');
|
|
13
|
+
if (colon > 0)
|
|
14
|
+
fm[line.slice(0, colon).trim()] = line.slice(colon + 1).trim();
|
|
15
|
+
}
|
|
16
|
+
return fm;
|
|
17
|
+
};
|
|
18
|
+
const getRulesDir = () => {
|
|
19
|
+
const candidates = [
|
|
20
|
+
join(import.meta.dir, '..', '..', '..', 'apps', 'web', 'content', 'rules'),
|
|
21
|
+
join(import.meta.dir, '..', 'apps', 'web', 'content', 'rules')
|
|
22
|
+
];
|
|
23
|
+
return candidates.find(c => existsSync(c));
|
|
24
|
+
};
|
|
25
|
+
const getAllDeps = async (projectPath) => {
|
|
26
|
+
const deps = new Set();
|
|
27
|
+
const entries = await collectWorkspacePackages(projectPath);
|
|
28
|
+
for (const { pkg } of entries)
|
|
29
|
+
for (const field of ['dependencies', 'devDependencies', 'peerDependencies']) {
|
|
30
|
+
const d = pkg[field];
|
|
31
|
+
if (d)
|
|
32
|
+
for (const name of Object.keys(d))
|
|
33
|
+
deps.add(name);
|
|
34
|
+
}
|
|
35
|
+
return deps;
|
|
36
|
+
};
|
|
37
|
+
const inferRules = async (projectPath, rulesDir) => {
|
|
38
|
+
const dir = rulesDir ?? getRulesDir();
|
|
39
|
+
if (!(dir && existsSync(dir)))
|
|
40
|
+
return [];
|
|
41
|
+
const deps = await getAllDeps(projectPath);
|
|
42
|
+
const rules = [];
|
|
43
|
+
const mdxFiles = readdirSync(dir).filter(f => f.endsWith('.mdx'));
|
|
44
|
+
const indexFile = mdxFiles.find(f => f === 'index.mdx');
|
|
45
|
+
const sorted = [...(indexFile ? [indexFile] : []), ...mdxFiles.filter(f => f !== 'index.mdx').toSorted()];
|
|
46
|
+
for (const mdxFile of sorted) {
|
|
47
|
+
const content = readFileSync(join(dir, mdxFile), 'utf8');
|
|
48
|
+
const fm = parseFrontmatter(content);
|
|
49
|
+
const { infer } = fm;
|
|
50
|
+
if (infer && (infer === 'always' || deps.has(infer)))
|
|
51
|
+
rules.push(mdxFile.replace('.mdx', ''));
|
|
52
|
+
}
|
|
53
|
+
return rules;
|
|
54
|
+
};
|
|
55
|
+
export { inferRules, parseFrontmatter };
|
|
56
|
+
//# sourceMappingURL=infer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infer.js","sourceRoot":"","sources":["../src/infer.ts"],"names":[],"mappings":"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"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAsCA,QAAA,MAAM,IAAI,GAAU,MAAM,MAAM,kBA8C/B,CAAA;AACD,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { $, write } from 'bun';
|
|
3
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { join, resolve } from 'node:path';
|
|
5
|
+
import { getBunVersion } from './utils.js';
|
|
6
|
+
const TURBO_JSON = JSON.stringify({
|
|
7
|
+
$schema: 'https://turbo.build/schema.json',
|
|
8
|
+
tasks: {
|
|
9
|
+
build: { dependsOn: ['^build'], outputs: ['.next/**', 'dist/**'] },
|
|
10
|
+
check: { cache: false, dependsOn: ['build'] },
|
|
11
|
+
fix: { cache: false, dependsOn: ['build'] }
|
|
12
|
+
}
|
|
13
|
+
}, null, 2);
|
|
14
|
+
const TSCONFIG_JSON = JSON.stringify({
|
|
15
|
+
compilerOptions: { types: ['bun-types'] },
|
|
16
|
+
extends: 'lintmax/tsconfig'
|
|
17
|
+
}, null, 2);
|
|
18
|
+
const CI_YML = `name: ' '
|
|
19
|
+
on:
|
|
20
|
+
push:
|
|
21
|
+
schedule:
|
|
22
|
+
- cron: '0 0 * * 1'
|
|
23
|
+
jobs:
|
|
24
|
+
ci:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v5
|
|
28
|
+
- uses: oven-sh/setup-bun@v2
|
|
29
|
+
- run: sh up.sh
|
|
30
|
+
`;
|
|
31
|
+
const init = async (name) => {
|
|
32
|
+
const dir = resolve(process.cwd(), name);
|
|
33
|
+
if (existsSync(dir)) {
|
|
34
|
+
console.log(`${dir} already exists`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
mkdirSync(dir, { recursive: true });
|
|
38
|
+
const bunVersion = await getBunVersion();
|
|
39
|
+
const pkg = JSON.stringify({
|
|
40
|
+
devDependencies: {
|
|
41
|
+
'@types/bun': 'latest',
|
|
42
|
+
'@types/node': 'latest',
|
|
43
|
+
lintmax: 'latest',
|
|
44
|
+
sherif: 'latest',
|
|
45
|
+
'simple-git-hooks': 'latest',
|
|
46
|
+
turbo: 'latest',
|
|
47
|
+
typescript: 'latest'
|
|
48
|
+
},
|
|
49
|
+
name,
|
|
50
|
+
packageManager: `bun@${bunVersion}`,
|
|
51
|
+
private: true,
|
|
52
|
+
scripts: {
|
|
53
|
+
build: 'turbo build --output-logs=errors-only',
|
|
54
|
+
check: 'lintmax check',
|
|
55
|
+
clean: 'sh clean.sh',
|
|
56
|
+
fix: 'lintmax fix',
|
|
57
|
+
postinstall: 'sherif',
|
|
58
|
+
prepare: 'bunx simple-git-hooks'
|
|
59
|
+
},
|
|
60
|
+
'simple-git-hooks': { 'pre-commit': 'sh up.sh && git add -u' },
|
|
61
|
+
workspaces: ['packages/*', 'apps/*', 'readonly/*']
|
|
62
|
+
}, null, 2);
|
|
63
|
+
await Promise.all([
|
|
64
|
+
write(join(dir, 'package.json'), `${pkg}\n`),
|
|
65
|
+
write(join(dir, 'turbo.json'), `${TURBO_JSON}\n`),
|
|
66
|
+
write(join(dir, 'tsconfig.json'), `${TSCONFIG_JSON}\n`)
|
|
67
|
+
]);
|
|
68
|
+
mkdirSync(join(dir, '.github', 'workflows'), { recursive: true });
|
|
69
|
+
await write(join(dir, '.github', 'workflows', 'ci.yml'), CI_YML);
|
|
70
|
+
await $ `git init`.cwd(dir).quiet();
|
|
71
|
+
console.log(`created ${name}`);
|
|
72
|
+
console.log('run: cd', name, '&& bunx pm4ai@latest fix');
|
|
73
|
+
};
|
|
74
|
+
export { init };
|
|
75
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface LogEntry {
|
|
2
|
+
at: string;
|
|
3
|
+
error?: string;
|
|
4
|
+
pass: boolean;
|
|
5
|
+
path: string;
|
|
6
|
+
project: string;
|
|
7
|
+
}
|
|
8
|
+
declare const readLog: () => LogEntry[];
|
|
9
|
+
declare const updateLog: (entry: LogEntry) => void;
|
|
10
|
+
export type { LogEntry };
|
|
11
|
+
export { readLog, updateLog };
|
|
12
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAGA,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAID,QAAA,MAAM,OAAO,QAAO,QAAQ,EAW3B,CAAA;AACD,QAAA,MAAM,SAAS,GAAI,OAAO,QAAQ,SAGjC,CAAA;AACD,YAAY,EAAE,QAAQ,EAAE,CAAA;AACxB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA"}
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
const logDir = join(homedir(), '.pm4ai', 'logs');
|
|
5
|
+
const leadingSepRe = /^--/u;
|
|
6
|
+
const logPath = (path) => join(logDir, `${path.replaceAll('/', '--').replace(leadingSepRe, '')}.json`);
|
|
7
|
+
const readLog = () => {
|
|
8
|
+
if (!existsSync(logDir))
|
|
9
|
+
return [];
|
|
10
|
+
const files = readdirSync(logDir).filter(f => f.endsWith('.json'));
|
|
11
|
+
const entries = [];
|
|
12
|
+
for (const f of files)
|
|
13
|
+
try {
|
|
14
|
+
entries.push(JSON.parse(readFileSync(join(logDir, f), 'utf8')));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
/* Corrupt file */
|
|
18
|
+
}
|
|
19
|
+
return entries;
|
|
20
|
+
};
|
|
21
|
+
const updateLog = (entry) => {
|
|
22
|
+
mkdirSync(logDir, { recursive: true });
|
|
23
|
+
writeFileSync(logPath(entry.path), JSON.stringify(entry));
|
|
24
|
+
};
|
|
25
|
+
export { readLog, updateLog };
|
|
26
|
+
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACzF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAQhC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;AAChD,MAAM,YAAY,GAAG,MAAM,CAAA;AAC3B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,OAAO,CAAC,CAAA;AAC9G,MAAM,OAAO,GAAG,GAAe,EAAE;IAC/B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAA;IAClC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;IAClE,MAAM,OAAO,GAAe,EAAE,CAAA;IAC9B,KAAK,MAAM,CAAC,IAAI,KAAK;QACnB,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAa,CAAC,CAAA;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AACD,MAAM,SAAS,GAAG,CAAC,KAAe,EAAE,EAAE;IACpC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACtC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;AAC3D,CAAC,CAAA;AAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA"}
|