pm4ai 0.0.73
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/README.md +34 -0
- package/dist/audit-oQQfgtxr.mjs +287 -0
- package/dist/cleanup-M-ALxTqh.mjs +35 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +77 -0
- package/dist/dashboard-DVRNZGun.mjs +39 -0
- package/dist/discover-d8ENQC1K.mjs +172 -0
- package/dist/fix-BcMN_cuG.mjs +260 -0
- package/dist/fix-DvtItv_V.mjs +2 -0
- package/dist/guide-BS7-RqpH.d.mts +4 -0
- package/dist/guide-CifUmtQN.mjs +59 -0
- package/dist/guide.d.mts +2 -0
- package/dist/guide.mjs +2 -0
- package/dist/ignores-BBl55eUM.mjs +37 -0
- package/dist/index.d.mts +83 -0
- package/dist/index.mjs +11 -0
- package/dist/init-C-073mRX.mjs +120 -0
- package/dist/list-QdJPgkEO.mjs +31 -0
- package/dist/package-NpIViQjo.mjs +4 -0
- package/dist/schemas-Dsbtf6P2.mjs +51 -0
- package/dist/schemas.d.mts +48 -0
- package/dist/schemas.mjs +2 -0
- package/dist/setup-BPuE4oWT.mjs +164 -0
- package/dist/status-ByiuW1iF.mjs +2 -0
- package/dist/status-CzCNkG58.mjs +1775 -0
- package/dist/sync-DN1rgN3P.mjs +732 -0
- package/dist/templates/cli/package.json +30 -0
- package/dist/templates/cli/src/cli.ts +16 -0
- package/dist/templates/cli/src/index.ts +2 -0
- package/dist/templates/cli/src/tui.tsx +57 -0
- package/dist/templates/cli/tsdown.config.ts +9 -0
- package/dist/templates/docs/content/docs/index.mdx +6 -0
- package/dist/templates/docs/package.json +20 -0
- package/dist/templates/docs/source.config.ts +16 -0
- package/dist/templates/docs/src/app/(home)/page.tsx +11 -0
- package/dist/templates/lib/package.json +22 -0
- package/dist/templates/lib/src/index.ts +2 -0
- package/dist/templates/lib/tsdown.config.ts +9 -0
- package/dist/templates/root-package.txt +38 -0
- package/dist/templates/web/package.json +17 -0
- package/dist/templates/web/src/app/page.tsx +6 -0
- package/dist/templates/web/src/app/providers.tsx +15 -0
- package/dist/utils-CpkOMuQN.mjs +221 -0
- package/dist/watch-D4OSFClu.mjs +566 -0
- package/dist/watch-emitter-uTmZ3oQd.mjs +177 -0
- package/dist/watch-state-DIMHiLr5.d.mts +118 -0
- package/dist/watch-state-wF-NfC-k.mjs +274 -0
- package/dist/watch-state.d.mts +2 -0
- package/dist/watch-state.mjs +2 -0
- package/dist/watch-types-BzSNCGb2.mjs +22 -0
- package/package.json +65 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
//#region src/schemas.ts
|
|
3
|
+
/** biome-ignore-all lint/suspicious/noEmptyBlockStatements: intentional catch-swallow */
|
|
4
|
+
const lockSchema = z.object({
|
|
5
|
+
at: z.string(),
|
|
6
|
+
pid: z.number()
|
|
7
|
+
});
|
|
8
|
+
const npmVersionSchema = z.object({ version: z.string() });
|
|
9
|
+
const ghReleaseSchema = z.object({ tag_name: z.string() });
|
|
10
|
+
const checkResultSchema = z.object({
|
|
11
|
+
at: z.string(),
|
|
12
|
+
commit: z.string().optional(),
|
|
13
|
+
pass: z.boolean(),
|
|
14
|
+
summary: z.string().optional(),
|
|
15
|
+
violations: z.number()
|
|
16
|
+
});
|
|
17
|
+
const logEntrySchema = z.object({
|
|
18
|
+
at: z.string(),
|
|
19
|
+
error: z.string().optional(),
|
|
20
|
+
pass: z.boolean(),
|
|
21
|
+
path: z.string(),
|
|
22
|
+
project: z.string()
|
|
23
|
+
});
|
|
24
|
+
const watchEventSchema = z.object({
|
|
25
|
+
at: z.string(),
|
|
26
|
+
detail: z.string().optional(),
|
|
27
|
+
project: z.string(),
|
|
28
|
+
status: z.enum([
|
|
29
|
+
"fail",
|
|
30
|
+
"ok",
|
|
31
|
+
"start"
|
|
32
|
+
]),
|
|
33
|
+
step: z.enum([
|
|
34
|
+
"audit",
|
|
35
|
+
"check",
|
|
36
|
+
"done",
|
|
37
|
+
"maintain",
|
|
38
|
+
"sync"
|
|
39
|
+
])
|
|
40
|
+
});
|
|
41
|
+
const safeParse = (schema, data) => {
|
|
42
|
+
const result = schema.safeParse(data);
|
|
43
|
+
return result.success ? result.data : void 0;
|
|
44
|
+
};
|
|
45
|
+
const safeParseJson = (schema, text) => {
|
|
46
|
+
try {
|
|
47
|
+
return safeParse(schema, JSON.parse(text));
|
|
48
|
+
} catch {}
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { npmVersionSchema as a, watchEventSchema as c, logEntrySchema as i, ghReleaseSchema as n, safeParse as o, lockSchema as r, safeParseJson as s, checkResultSchema as t };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
|
|
3
|
+
//#region src/schemas.d.ts
|
|
4
|
+
declare const lockSchema: z.ZodObject<{
|
|
5
|
+
at: z.ZodString;
|
|
6
|
+
pid: z.ZodNumber;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
declare const npmVersionSchema: z.ZodObject<{
|
|
9
|
+
version: z.ZodString;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
declare const ghReleaseSchema: z.ZodObject<{
|
|
12
|
+
tag_name: z.ZodString;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
declare const checkResultSchema: z.ZodObject<{
|
|
15
|
+
at: z.ZodString;
|
|
16
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
17
|
+
pass: z.ZodBoolean;
|
|
18
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
19
|
+
violations: z.ZodNumber;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
declare const logEntrySchema: z.ZodObject<{
|
|
22
|
+
at: z.ZodString;
|
|
23
|
+
error: z.ZodOptional<z.ZodString>;
|
|
24
|
+
pass: z.ZodBoolean;
|
|
25
|
+
path: z.ZodString;
|
|
26
|
+
project: z.ZodString;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
declare const watchEventSchema: z.ZodObject<{
|
|
29
|
+
at: z.ZodString;
|
|
30
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
31
|
+
project: z.ZodString;
|
|
32
|
+
status: z.ZodEnum<{
|
|
33
|
+
fail: "fail";
|
|
34
|
+
ok: "ok";
|
|
35
|
+
start: "start";
|
|
36
|
+
}>;
|
|
37
|
+
step: z.ZodEnum<{
|
|
38
|
+
audit: "audit";
|
|
39
|
+
check: "check";
|
|
40
|
+
done: "done";
|
|
41
|
+
maintain: "maintain";
|
|
42
|
+
sync: "sync";
|
|
43
|
+
}>;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
declare const safeParse: <T>(schema: z.ZodType<T>, data: unknown) => T | undefined;
|
|
46
|
+
declare const safeParseJson: <T>(schema: z.ZodType<T>, text: string) => T | undefined;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { checkResultSchema, ghReleaseSchema, lockSchema, logEntrySchema, npmVersionSchema, safeParse, safeParseJson, watchEventSchema };
|
package/dist/schemas.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as npmVersionSchema, c as watchEventSchema, i as logEntrySchema, n as ghReleaseSchema, o as safeParse, r as lockSchema, s as safeParseJson, t as checkResultSchema } from "./schemas-Dsbtf6P2.mjs";
|
|
2
|
+
export { checkResultSchema, ghReleaseSchema, lockSchema, logEntrySchema, npmVersionSchema, safeParse, safeParseJson, watchEventSchema };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { write } from "bun";
|
|
2
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
//#region src/setup.ts
|
|
6
|
+
const SWIFTBAR_PLUGIN = `#!/bin/bash
|
|
7
|
+
# <swiftbar.hideAbout>true</swiftbar.hideAbout>
|
|
8
|
+
# <swiftbar.hideRunInTerminal>true</swiftbar.hideRunInTerminal>
|
|
9
|
+
# <swiftbar.hideLastUpdated>true</swiftbar.hideLastUpdated>
|
|
10
|
+
# <swiftbar.hideDisablePlugin>true</swiftbar.hideDisablePlugin>
|
|
11
|
+
# <swiftbar.hideSwiftBar>true</swiftbar.hideSwiftBar>
|
|
12
|
+
export PATH="$HOME/.bun/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
|
|
13
|
+
bunx pm4ai@latest status --swiftbar
|
|
14
|
+
`;
|
|
15
|
+
const SWIFTBAR_STREAMING_PLUGIN = `#!/usr/bin/env bun
|
|
16
|
+
// <swiftbar.hideAbout>true</swiftbar.hideAbout>
|
|
17
|
+
// <swiftbar.hideRunInTerminal>true</swiftbar.hideRunInTerminal>
|
|
18
|
+
// <swiftbar.hideLastUpdated>true</swiftbar.hideLastUpdated>
|
|
19
|
+
// <swiftbar.hideDisablePlugin>true</swiftbar.hideDisablePlugin>
|
|
20
|
+
// <swiftbar.hideSwiftBar>true</swiftbar.hideSwiftBar>
|
|
21
|
+
// <swiftbar.type>streamable</swiftbar.type>
|
|
22
|
+
import { createConnection } from 'node:net'
|
|
23
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
24
|
+
import { homedir } from 'node:os'
|
|
25
|
+
import { join } from 'node:path'
|
|
26
|
+
const SOCK = join(homedir(), '.pm4ai', 'watch.sock')
|
|
27
|
+
const CHECKS = join(homedir(), '.pm4ai', 'checks')
|
|
28
|
+
const f = '| font=Menlo size=13'
|
|
29
|
+
const SPINNER = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏']
|
|
30
|
+
const state = new Map()
|
|
31
|
+
let tick = 0
|
|
32
|
+
const getIdle = () => {
|
|
33
|
+
if (!existsSync(CHECKS)) return '? | sfimage=questionmark.circle sfcolor=gray'
|
|
34
|
+
const files = readdirSync(CHECKS).filter(f => f.endsWith('.json'))
|
|
35
|
+
let pass = 0
|
|
36
|
+
let total = 0
|
|
37
|
+
const lines = []
|
|
38
|
+
for (const file of files) {
|
|
39
|
+
const path = '/' + file.replace('.json','').replaceAll('--','/')
|
|
40
|
+
if (!existsSync(path) || path.startsWith('/tmp/')) continue
|
|
41
|
+
total++
|
|
42
|
+
try {
|
|
43
|
+
const r = JSON.parse(readFileSync(join(CHECKS, file), 'utf8'))
|
|
44
|
+
if (r.pass) pass++
|
|
45
|
+
const name = path.split('/').pop()
|
|
46
|
+
const mark = r.pass ? '🟢' : '🔴'
|
|
47
|
+
lines.push(mark + ' ' + name + ' ' + f)
|
|
48
|
+
} catch {}
|
|
49
|
+
}
|
|
50
|
+
const ok = pass === total
|
|
51
|
+
const header = ok
|
|
52
|
+
? total + '/' + total + ' | sfimage=checkmark.circle.fill sfcolor=green'
|
|
53
|
+
: pass + '/' + total + ' | sfimage=xmark.circle.fill sfcolor=red'
|
|
54
|
+
return header + '\\n---\\n' + lines.join('\\n')
|
|
55
|
+
}
|
|
56
|
+
const render = () => {
|
|
57
|
+
tick++
|
|
58
|
+
const entries = [...state.entries()]
|
|
59
|
+
if (entries.length === 0) return getIdle()
|
|
60
|
+
const done = entries.filter(([,v]) => v.step === 'done').length
|
|
61
|
+
const total = entries.length
|
|
62
|
+
const spinner = SPINNER[tick % SPINNER.length]
|
|
63
|
+
const active = entries.some(([,v]) => v.step !== 'done')
|
|
64
|
+
const header = active
|
|
65
|
+
? spinner + ' ' + done + '/' + total + ' | sfimage=arrow.triangle.2.circlepath sfcolor=orange'
|
|
66
|
+
: done + '/' + total + ' | sfimage=checkmark.circle.fill sfcolor=green'
|
|
67
|
+
const lines = entries.map(([name, v]) => {
|
|
68
|
+
if (v.step === 'done') return '✓ ' + name + ' ' + (v.detail || '') + ' ' + f + ' color=green'
|
|
69
|
+
if (v.step) return spinner + ' ' + v.step + '... ' + name + ' ' + f + ' color=orange'
|
|
70
|
+
return '● ' + name + ' ' + f + ' color=gray'
|
|
71
|
+
})
|
|
72
|
+
return header + '\\n---\\n' + lines.join('\\n')
|
|
73
|
+
}
|
|
74
|
+
const output = (s) => process.stdout.write(s.replace(/\\\\n/g, '\\n') + '\\n')
|
|
75
|
+
const sep = () => process.stdout.write('~~~\\n')
|
|
76
|
+
output(render())
|
|
77
|
+
if (!existsSync(SOCK)) process.exit(0)
|
|
78
|
+
const connect = () => {
|
|
79
|
+
let buf = ''
|
|
80
|
+
const sock = createConnection(SOCK)
|
|
81
|
+
sock.on('data', chunk => {
|
|
82
|
+
buf += chunk.toString()
|
|
83
|
+
const lines = buf.split('\\n')
|
|
84
|
+
buf = lines.pop()
|
|
85
|
+
for (const line of lines) {
|
|
86
|
+
if (!line) continue
|
|
87
|
+
try {
|
|
88
|
+
const e = JSON.parse(line)
|
|
89
|
+
state.set(e.project, { step: e.step, status: e.status, detail: e.detail })
|
|
90
|
+
sep()
|
|
91
|
+
output(render())
|
|
92
|
+
} catch {}
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
sock.on('close', () => {
|
|
96
|
+
state.clear()
|
|
97
|
+
sep()
|
|
98
|
+
output(render())
|
|
99
|
+
setTimeout(connect, 2000)
|
|
100
|
+
})
|
|
101
|
+
sock.on('error', () => {})
|
|
102
|
+
}
|
|
103
|
+
connect()
|
|
104
|
+
setInterval(() => {
|
|
105
|
+
if (state.size > 0) {
|
|
106
|
+
sep()
|
|
107
|
+
output(render())
|
|
108
|
+
}
|
|
109
|
+
}, 100)
|
|
110
|
+
`;
|
|
111
|
+
const launchdPlist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
112
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
113
|
+
<plist version="1.0">
|
|
114
|
+
<dict>
|
|
115
|
+
<key>Label</key>
|
|
116
|
+
<string>com.pm4ai.fix</string>
|
|
117
|
+
<key>ProgramArguments</key>
|
|
118
|
+
<array>
|
|
119
|
+
<string>${join(homedir(), ".bun", "bin", "bunx")}</string>
|
|
120
|
+
<string>pm4ai@latest</string>
|
|
121
|
+
<string>fix</string>
|
|
122
|
+
</array>
|
|
123
|
+
<key>StartCalendarInterval</key>
|
|
124
|
+
<dict>
|
|
125
|
+
<key>Hour</key>
|
|
126
|
+
<integer>9</integer>
|
|
127
|
+
<key>Minute</key>
|
|
128
|
+
<integer>0</integer>
|
|
129
|
+
</dict>
|
|
130
|
+
<key>EnvironmentVariables</key>
|
|
131
|
+
<dict>
|
|
132
|
+
<key>PATH</key>
|
|
133
|
+
<string>${homedir()}/.bun/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
|
|
134
|
+
</dict>
|
|
135
|
+
<key>StandardOutPath</key>
|
|
136
|
+
<string>/tmp/pm4ai.stdout.log</string>
|
|
137
|
+
<key>StandardErrorPath</key>
|
|
138
|
+
<string>/tmp/pm4ai.stderr.log</string>
|
|
139
|
+
</dict>
|
|
140
|
+
</plist>
|
|
141
|
+
`;
|
|
142
|
+
const setup = async () => {
|
|
143
|
+
const swiftbarDir = join(homedir(), "Library", "Application Support", "SwiftBar", "plugins");
|
|
144
|
+
if (existsSync(join(homedir(), "Library", "Application Support", "SwiftBar"))) {
|
|
145
|
+
mkdirSync(swiftbarDir, { recursive: true });
|
|
146
|
+
const pollingPath = join(swiftbarDir, "pm4ai.1h.sh");
|
|
147
|
+
const streamingPath = join(swiftbarDir, "pm4ai-stream.1h.ts");
|
|
148
|
+
await write(pollingPath, SWIFTBAR_PLUGIN);
|
|
149
|
+
await write(streamingPath, SWIFTBAR_STREAMING_PLUGIN);
|
|
150
|
+
const { chmod } = await import("node:fs/promises");
|
|
151
|
+
await chmod(pollingPath, 493);
|
|
152
|
+
await chmod(streamingPath, 493);
|
|
153
|
+
console.log(`swiftbar polling plugin: ${pollingPath}`);
|
|
154
|
+
console.log(`swiftbar streaming plugin: ${streamingPath}`);
|
|
155
|
+
} else console.log("swiftbar not found, install with: brew install swiftbar");
|
|
156
|
+
const launchdDir = join(homedir(), "Library", "LaunchAgents");
|
|
157
|
+
mkdirSync(launchdDir, { recursive: true });
|
|
158
|
+
const plistPath = join(launchdDir, "com.pm4ai.fix.plist");
|
|
159
|
+
await write(plistPath, launchdPlist);
|
|
160
|
+
console.log(`launchd plist: ${plistPath}`);
|
|
161
|
+
console.log("load with: launchctl load ~/Library/LaunchAgents/com.pm4ai.fix.plist");
|
|
162
|
+
};
|
|
163
|
+
//#endregion
|
|
164
|
+
export { setup };
|