everything-dev 1.27.0 → 1.28.0

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 (104) hide show
  1. package/dist/cli/infra.cjs +1 -1
  2. package/dist/cli/infra.mjs +1 -1
  3. package/dist/cli/init.cjs +7 -9
  4. package/dist/cli/init.cjs.map +1 -1
  5. package/dist/cli/init.d.cts +1 -1
  6. package/dist/cli/init.d.cts.map +1 -1
  7. package/dist/cli/init.d.mts +1 -1
  8. package/dist/cli/init.d.mts.map +1 -1
  9. package/dist/cli/init.mjs +7 -9
  10. package/dist/cli/init.mjs.map +1 -1
  11. package/dist/cli/prompts.cjs +28 -24
  12. package/dist/cli/prompts.cjs.map +1 -1
  13. package/dist/cli/prompts.mjs +27 -24
  14. package/dist/cli/prompts.mjs.map +1 -1
  15. package/dist/cli/sync.cjs +4 -1
  16. package/dist/cli/sync.cjs.map +1 -1
  17. package/dist/cli/sync.mjs +4 -1
  18. package/dist/cli/sync.mjs.map +1 -1
  19. package/dist/cli.cjs +187 -12
  20. package/dist/cli.cjs.map +1 -1
  21. package/dist/cli.mjs +186 -11
  22. package/dist/cli.mjs.map +1 -1
  23. package/dist/contract.cjs +1 -1
  24. package/dist/contract.cjs.map +1 -1
  25. package/dist/contract.d.cts +38 -34
  26. package/dist/contract.d.cts.map +1 -1
  27. package/dist/contract.d.mts +38 -34
  28. package/dist/contract.d.mts.map +1 -1
  29. package/dist/contract.mjs +1 -0
  30. package/dist/contract.mjs.map +1 -1
  31. package/dist/dev-session.cjs +0 -1
  32. package/dist/dev-session.mjs +1 -1
  33. package/dist/index.cjs +0 -2
  34. package/dist/index.d.cts +2 -2
  35. package/dist/index.d.mts +2 -2
  36. package/dist/index.mjs +0 -1
  37. package/dist/near-cli.cjs +1 -1
  38. package/dist/near-cli.mjs +1 -1
  39. package/dist/orchestrator.cjs +1 -1
  40. package/dist/orchestrator.mjs +1 -1
  41. package/dist/plugin.cjs +163 -139
  42. package/dist/plugin.cjs.map +1 -1
  43. package/dist/plugin.d.cts +67 -34
  44. package/dist/plugin.d.cts.map +1 -1
  45. package/dist/plugin.d.mts +66 -34
  46. package/dist/plugin.d.mts.map +1 -1
  47. package/dist/plugin.mjs +153 -130
  48. package/dist/plugin.mjs.map +1 -1
  49. package/dist/service-descriptor.d.cts +34 -0
  50. package/dist/service-descriptor.d.cts.map +1 -0
  51. package/dist/service-descriptor.d.mts +36 -0
  52. package/dist/service-descriptor.d.mts.map +1 -0
  53. package/dist/types.d.cts +2 -2
  54. package/dist/types.d.mts +2 -2
  55. package/package.json +2 -2
  56. package/src/api-contract.ts +0 -623
  57. package/src/app.ts +0 -193
  58. package/src/cli/catalog.ts +0 -49
  59. package/src/cli/framework-version.ts +0 -61
  60. package/src/cli/help.ts +0 -13
  61. package/src/cli/infra.ts +0 -190
  62. package/src/cli/init.ts +0 -1145
  63. package/src/cli/parse.ts +0 -147
  64. package/src/cli/prompts.ts +0 -135
  65. package/src/cli/snapshot.ts +0 -46
  66. package/src/cli/status.ts +0 -99
  67. package/src/cli/sync.ts +0 -429
  68. package/src/cli/timing.ts +0 -63
  69. package/src/cli/upgrade.ts +0 -869
  70. package/src/cli.ts +0 -516
  71. package/src/components/dev-view.tsx +0 -352
  72. package/src/components/streaming-view.ts +0 -177
  73. package/src/config.ts +0 -893
  74. package/src/contract.meta.ts +0 -140
  75. package/src/contract.ts +0 -326
  76. package/src/dev-logs.ts +0 -92
  77. package/src/dev-session.ts +0 -283
  78. package/src/fastkv.ts +0 -181
  79. package/src/index.ts +0 -8
  80. package/src/integrity.ts +0 -138
  81. package/src/internal/manifest-normalizer.ts +0 -290
  82. package/src/merge.ts +0 -187
  83. package/src/mf.ts +0 -147
  84. package/src/near-cli.ts +0 -259
  85. package/src/network.ts +0 -3
  86. package/src/orchestrator.ts +0 -493
  87. package/src/plugin.ts +0 -1799
  88. package/src/sdk.ts +0 -14
  89. package/src/service-descriptor.ts +0 -281
  90. package/src/shared.ts +0 -249
  91. package/src/sidebar.ts +0 -140
  92. package/src/types.ts +0 -330
  93. package/src/ui/head.ts +0 -83
  94. package/src/ui/index.ts +0 -5
  95. package/src/ui/metadata.ts +0 -95
  96. package/src/ui/router.ts +0 -88
  97. package/src/ui/runtime.ts +0 -42
  98. package/src/ui/types.ts +0 -65
  99. package/src/utils/banner.ts +0 -21
  100. package/src/utils/linkify.ts +0 -11
  101. package/src/utils/path-match.ts +0 -16
  102. package/src/utils/run.ts +0 -31
  103. package/src/utils/save-config.ts +0 -20
  104. package/src/utils/theme.ts +0 -39
@@ -1,140 +0,0 @@
1
- export type CliCommandMeta = {
2
- commandPath?: string[];
3
- summary: string;
4
- description?: string;
5
- examples?: string[];
6
- interactive?: boolean;
7
- longRunning?: boolean;
8
- fields?: Record<string, { positional?: boolean; description?: string }>;
9
- };
10
-
11
- export const cliCommandMeta = {
12
- dev: {
13
- commandPath: ["dev"],
14
- summary: "Start a development session",
15
- interactive: true,
16
- longRunning: true,
17
- },
18
- start: {
19
- commandPath: ["start"],
20
- summary: "Start the production host",
21
- interactive: false,
22
- longRunning: true,
23
- fields: {
24
- env: { description: "Environment: production or staging" },
25
- },
26
- },
27
- build: {
28
- commandPath: ["build"],
29
- summary: "Build selected workspaces",
30
- interactive: false,
31
- fields: {
32
- packages: { positional: true, description: "Comma-separated package list" },
33
- },
34
- },
35
- config: {
36
- commandPath: ["config"],
37
- summary: "Print the loaded BOS configuration",
38
- interactive: false,
39
- },
40
- pluginAdd: {
41
- commandPath: ["plugin", "add"],
42
- summary: "Add a plugin attachment",
43
- interactive: false,
44
- fields: {
45
- source: {
46
- positional: true,
47
- description: "Plugin source (local:path, bos://account/domain, or URL)",
48
- },
49
- as: { description: "Plugin alias" },
50
- production: { description: "Production URL override" },
51
- },
52
- },
53
- pluginRemove: {
54
- commandPath: ["plugin", "remove"],
55
- summary: "Remove a plugin attachment",
56
- interactive: false,
57
- fields: { key: { positional: true, description: "Plugin key" } },
58
- },
59
- pluginList: {
60
- commandPath: ["plugin", "list"],
61
- summary: "List configured plugins",
62
- interactive: false,
63
- },
64
- pluginPublish: {
65
- commandPath: ["plugin", "publish"],
66
- summary: "Publish a single plugin",
67
- interactive: false,
68
- fields: { key: { positional: true, description: "Plugin key" } },
69
- },
70
- publish: {
71
- commandPath: ["publish"],
72
- summary: "Publish the current workspace configuration",
73
- interactive: false,
74
- },
75
- keyPublish: {
76
- commandPath: ["key", "publish"],
77
- summary: "Generate a publish access key",
78
- interactive: false,
79
- },
80
- init: {
81
- commandPath: ["init"],
82
- summary: "Scaffold a new project by extending a deployed app or template",
83
- interactive: true,
84
- fields: {
85
- domain: {
86
- positional: true,
87
- description: "New project domain (e.g. myapp.everything.dev)",
88
- },
89
- extends: {
90
- description: "Parent to extend from (e.g. bos://account/gateway or account/gateway)",
91
- },
92
- account: { description: "New project NEAR account (auto-derived from extends)" },
93
- directory: { description: "Target directory (auto-derived from domain)" },
94
- source: { description: "Local source dir (skips GitHub download)" },
95
- plugins: {
96
- description: "Comma-separated plugin keys to include (requires --overrides=plugins)",
97
- },
98
- overrides: {
99
- description: "Comma-separated sections to customize locally: ui,api,host,plugins",
100
- },
101
- noInteractive: { description: "Skip prompts, use flags only" },
102
- noInstall: { description: "Skip bun install" },
103
- },
104
- },
105
- sync: {
106
- commandPath: ["sync"],
107
- summary: "Sync template files from parent project",
108
- interactive: false,
109
- fields: {
110
- dryRun: { description: "Preview changes without writing files" },
111
- force: { description: "Overwrite user-modified files" },
112
- noInstall: { description: "Skip bun install" },
113
- },
114
- },
115
- upgrade: {
116
- commandPath: ["upgrade"],
117
- summary: "Upgrade framework packages and sync template files",
118
- interactive: true,
119
- fields: {
120
- dryRun: { description: "Preview changes without writing" },
121
- force: { description: "Overwrite user-modified files during sync" },
122
- noInstall: { description: "Skip bun install" },
123
- noSync: { description: "Only upgrade packages, skip template sync" },
124
- },
125
- },
126
- typesGen: {
127
- commandPath: ["types", "gen"],
128
- summary: "Generate type definitions from configured API and plugin contracts",
129
- interactive: false,
130
- fields: {
131
- env: { description: "Environment: development (default) or production" },
132
- dryRun: { description: "Preview what would be fetched without writing files" },
133
- },
134
- },
135
- status: {
136
- commandPath: ["status"],
137
- summary: "Show project health, versions, and update availability",
138
- interactive: false,
139
- },
140
- } as const satisfies Record<string, CliCommandMeta>;
package/src/contract.ts DELETED
@@ -1,326 +0,0 @@
1
- import * as z from "zod";
2
- import { oc } from "./sdk";
3
- import { BosConfigSchema, SourceModeSchema } from "./types";
4
-
5
- export const DevOptionsSchema = z.object({
6
- host: SourceModeSchema.default("local"),
7
- ui: SourceModeSchema.default("local"),
8
- api: SourceModeSchema.default("local"),
9
- auth: SourceModeSchema.default("local"),
10
- proxy: z.boolean().default(false),
11
- ssr: z.boolean().default(false),
12
- port: z.number().optional(),
13
- interactive: z.boolean().optional(),
14
- });
15
-
16
- export const DevResultSchema = z.object({
17
- status: z.enum(["started", "error"]),
18
- description: z.string(),
19
- processes: z.array(z.string()),
20
- });
21
-
22
- export const StartOptionsSchema = z.object({
23
- port: z.number().optional(),
24
- interactive: z.boolean().optional(),
25
- account: z.string().optional(),
26
- domain: z.string().optional(),
27
- env: z.enum(["production", "staging"]).default("production"),
28
- });
29
-
30
- export const StartResultSchema = z.object({
31
- status: z.enum(["running", "error"]),
32
- url: z.string(),
33
- error: z.string().optional(),
34
- });
35
-
36
- export const BuildOptionsSchema = z.object({
37
- packages: z.string().default("all"),
38
- force: z.boolean().default(false),
39
- deploy: z.boolean().default(false),
40
- });
41
-
42
- export const BuildResultSchema = z.object({
43
- status: z.enum(["success", "error"]),
44
- built: z.array(z.string()),
45
- skipped: z.array(z.string()).optional(),
46
- deployed: z.boolean().optional(),
47
- });
48
-
49
- export const ConfigResultSchema = z.object({
50
- config: BosConfigSchema.nullable(),
51
- packages: z.array(z.string()),
52
- remotes: z.array(z.string()),
53
- });
54
-
55
- export const PluginAddOptionsSchema = z.object({
56
- source: z.string(),
57
- as: z.string().optional(),
58
- production: z.string().optional(),
59
- });
60
-
61
- export const PluginAddResultSchema = z.object({
62
- status: z.enum(["added", "error"]),
63
- key: z.string(),
64
- development: z.string().optional(),
65
- production: z.string().optional(),
66
- integrity: z.string().optional(),
67
- version: z.string().optional(),
68
- error: z.string().optional(),
69
- });
70
-
71
- export const PluginRemoveOptionsSchema = z.object({
72
- key: z.string(),
73
- });
74
-
75
- export const PluginRemoveResultSchema = z.object({
76
- status: z.enum(["removed", "error"]),
77
- key: z.string(),
78
- error: z.string().optional(),
79
- });
80
-
81
- export const PluginListResultSchema = z.object({
82
- status: z.enum(["listed", "error"]),
83
- plugins: z.array(
84
- z.object({
85
- key: z.string(),
86
- development: z.string().optional(),
87
- production: z.string().optional(),
88
- localPath: z.string().optional(),
89
- source: z.enum(["local", "remote"]),
90
- integrity: z.string().optional(),
91
- version: z.string().optional(),
92
- name: z.string().optional(),
93
- }),
94
- ),
95
- error: z.string().optional(),
96
- });
97
-
98
- export const PluginPublishOptionsSchema = z.object({
99
- key: z.string(),
100
- });
101
-
102
- export const PluginPublishResultSchema = z.object({
103
- status: z.enum(["published", "error"]),
104
- key: z.string(),
105
- path: z.string().optional(),
106
- script: z.string().optional(),
107
- production: z.string().optional(),
108
- integrity: z.string().optional(),
109
- version: z.string().optional(),
110
- error: z.string().optional(),
111
- });
112
-
113
- export const PublishOptionsSchema = z.object({
114
- deploy: z.boolean().default(false),
115
- dryRun: z.boolean().default(false),
116
- packages: z.string().default("all"),
117
- network: z.enum(["mainnet", "testnet"]).optional(),
118
- privateKey: z.string().optional(),
119
- });
120
-
121
- export const PublishResultSchema = z.object({
122
- status: z.enum(["published", "error", "dry-run"]),
123
- registryUrl: z.string(),
124
- txHash: z.string().optional(),
125
- error: z.string().optional(),
126
- built: z.array(z.string()).optional(),
127
- skipped: z.array(z.string()).optional(),
128
- });
129
-
130
- export const KeyPublishOptionsSchema = z.object({
131
- allowance: z.string().default("0.25NEAR"),
132
- });
133
-
134
- export const KeyPublishResultSchema = z.object({
135
- status: z.enum(["published", "error"]),
136
- account: z.string(),
137
- network: z.enum(["mainnet", "testnet"]),
138
- contract: z.string(),
139
- allowance: z.string(),
140
- functionNames: z.array(z.string()),
141
- publicKey: z.string().optional(),
142
- privateKey: z.string().optional(),
143
- error: z.string().optional(),
144
- });
145
-
146
- export const OverrideSectionSchema = z.enum(["ui", "api", "host", "plugins"]);
147
-
148
- export const InitOptionsSchema = z.object({
149
- extends: z.string().optional(),
150
- directory: z.string().optional(),
151
- account: z.string().optional(),
152
- domain: z.string().optional(),
153
- source: z.string().optional(),
154
- plugins: z.array(z.string()).optional(),
155
- overrides: z.array(OverrideSectionSchema).optional(),
156
- noInteractive: z.boolean().default(false),
157
- noInstall: z.boolean().default(false),
158
- });
159
-
160
- export const PhaseTimingSchema = z.object({
161
- name: z.string(),
162
- durationMs: z.number(),
163
- });
164
-
165
- export const InitResultSchema = z.object({
166
- status: z.enum(["initialized", "error"]),
167
- directory: z.string(),
168
- extendsRef: z.string(),
169
- account: z.string().optional(),
170
- domain: z.string().optional(),
171
- extends: z.string(),
172
- plugins: z.array(z.string()).optional(),
173
- overrides: z.array(OverrideSectionSchema).optional(),
174
- filesCopied: z.number(),
175
- timings: z.array(PhaseTimingSchema).optional(),
176
- error: z.string().optional(),
177
- });
178
-
179
- export const SyncOptionsSchema = z.object({
180
- dryRun: z.boolean().default(false),
181
- force: z.boolean().default(false),
182
- noInstall: z.boolean().default(false),
183
- });
184
-
185
- export const SyncResultSchema = z.object({
186
- status: z.enum(["synced", "dry-run", "error"]),
187
- updated: z.array(z.string()),
188
- skipped: z.array(z.string()),
189
- added: z.array(z.string()),
190
- error: z.string().optional(),
191
- });
192
-
193
- export const UpgradeOptionsSchema = z.object({
194
- dryRun: z.boolean().default(false),
195
- force: z.boolean().default(false),
196
- noInstall: z.boolean().default(false),
197
- noSync: z.boolean().default(false),
198
- });
199
-
200
- export const UpgradeResultSchema = z.object({
201
- status: z.enum(["upgraded", "dry-run", "error"]),
202
- packages: z.array(
203
- z.object({
204
- name: z.string(),
205
- from: z.string().optional(),
206
- to: z.string(),
207
- }),
208
- ),
209
- sync: SyncResultSchema.optional(),
210
- migrated: z.array(z.string()).optional(),
211
- availablePlugins: z.array(z.string()).optional(),
212
- selectedPlugins: z.array(z.string()).optional(),
213
- timings: z.array(PhaseTimingSchema).optional(),
214
- changelogUrl: z.string().optional(),
215
- error: z.string().optional(),
216
- });
217
-
218
- export const StatusResultSchema = z.object({
219
- status: z.enum(["ok", "error"]),
220
- extends: z.string().optional(),
221
- account: z.string().optional(),
222
- domain: z.string().optional(),
223
- packages: z.array(
224
- z.object({
225
- name: z.string(),
226
- installed: z.string().optional(),
227
- latest: z.string().optional(),
228
- }),
229
- ),
230
- lastSync: z.string().optional(),
231
- envFile: z.enum(["found", "missing", "example-only"]),
232
- parentReachable: z.boolean().optional(),
233
- error: z.string().optional(),
234
- });
235
-
236
- export const TypesGenOptionsSchema = z.object({
237
- env: z.enum(["development", "production"]).optional(),
238
- dryRun: z.boolean().default(false),
239
- });
240
-
241
- export const TypesGenResultSchema = z.object({
242
- status: z.enum(["success", "error"]),
243
- generated: z.array(z.string()),
244
- fetched: z.array(z.string()),
245
- skipped: z.array(z.string()),
246
- failed: z.array(z.string()),
247
- source: z.enum(["local", "remote"]).optional(),
248
- error: z.string().optional(),
249
- });
250
-
251
- export const bosContract = oc.router({
252
- dev: oc.route({ method: "POST", path: "/dev" }).input(DevOptionsSchema).output(DevResultSchema),
253
- start: oc
254
- .route({ method: "POST", path: "/start" })
255
- .input(StartOptionsSchema)
256
- .output(StartResultSchema),
257
- build: oc
258
- .route({ method: "POST", path: "/build" })
259
- .input(BuildOptionsSchema)
260
- .output(BuildResultSchema),
261
- config: oc.route({ method: "GET", path: "/config" }).output(ConfigResultSchema),
262
- pluginAdd: oc
263
- .route({ method: "POST", path: "/plugin/add" })
264
- .input(PluginAddOptionsSchema)
265
- .output(PluginAddResultSchema),
266
- pluginRemove: oc
267
- .route({ method: "POST", path: "/plugin/remove" })
268
- .input(PluginRemoveOptionsSchema)
269
- .output(PluginRemoveResultSchema),
270
- pluginList: oc.route({ method: "GET", path: "/plugin/list" }).output(PluginListResultSchema),
271
- pluginPublish: oc
272
- .route({ method: "POST", path: "/plugin/publish" })
273
- .input(PluginPublishOptionsSchema)
274
- .output(PluginPublishResultSchema),
275
- publish: oc
276
- .route({ method: "POST", path: "/publish" })
277
- .input(PublishOptionsSchema)
278
- .output(PublishResultSchema),
279
- keyPublish: oc
280
- .route({ method: "POST", path: "/key/publish" })
281
- .input(KeyPublishOptionsSchema)
282
- .output(KeyPublishResultSchema),
283
- init: oc
284
- .route({ method: "POST", path: "/init" })
285
- .input(InitOptionsSchema)
286
- .output(InitResultSchema),
287
- sync: oc
288
- .route({ method: "POST", path: "/sync" })
289
- .input(SyncOptionsSchema)
290
- .output(SyncResultSchema),
291
- upgrade: oc
292
- .route({ method: "POST", path: "/upgrade" })
293
- .input(UpgradeOptionsSchema)
294
- .output(UpgradeResultSchema),
295
- status: oc.route({ method: "GET", path: "/status" }).output(StatusResultSchema),
296
- typesGen: oc
297
- .route({ method: "POST", path: "/types/gen" })
298
- .input(TypesGenOptionsSchema)
299
- .output(TypesGenResultSchema),
300
- });
301
-
302
- export type DevOptions = z.infer<typeof DevOptionsSchema>;
303
- export type StartOptions = z.infer<typeof StartOptionsSchema>;
304
- export type BuildOptions = z.infer<typeof BuildOptionsSchema>;
305
- export type BosConfigResult = z.infer<typeof ConfigResultSchema>;
306
- export type PluginAddOptions = z.infer<typeof PluginAddOptionsSchema>;
307
- export type PluginAddResult = z.infer<typeof PluginAddResultSchema>;
308
- export type PluginRemoveOptions = z.infer<typeof PluginRemoveOptionsSchema>;
309
- export type PluginRemoveResult = z.infer<typeof PluginRemoveResultSchema>;
310
- export type PluginListResult = z.infer<typeof PluginListResultSchema>;
311
- export type PluginPublishOptions = z.infer<typeof PluginPublishOptionsSchema>;
312
- export type PluginPublishResult = z.infer<typeof PluginPublishResultSchema>;
313
- export type PublishOptions = z.infer<typeof PublishOptionsSchema>;
314
- export type KeyPublishOptions = z.infer<typeof KeyPublishOptionsSchema>;
315
- export type KeyPublishResult = z.infer<typeof KeyPublishResultSchema>;
316
- export type InitOptions = z.infer<typeof InitOptionsSchema>;
317
- export type InitResult = z.infer<typeof InitResultSchema>;
318
- export type OverrideSection = z.infer<typeof OverrideSectionSchema>;
319
- export type PhaseTiming = z.infer<typeof PhaseTimingSchema>;
320
- export type SyncOptions = z.infer<typeof SyncOptionsSchema>;
321
- export type SyncResult = z.infer<typeof SyncResultSchema>;
322
- export type UpgradeOptions = z.infer<typeof UpgradeOptionsSchema>;
323
- export type UpgradeResult = z.infer<typeof UpgradeResultSchema>;
324
- export type StatusResult = z.infer<typeof StatusResultSchema>;
325
- export type TypesGenOptions = z.infer<typeof TypesGenOptionsSchema>;
326
- export type TypesGenResult = z.infer<typeof TypesGenResultSchema>;
package/src/dev-logs.ts DELETED
@@ -1,92 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
3
- import { join } from "node:path";
4
-
5
- const ESC = "\x1b";
6
- const BEL = "\x07";
7
- const ANSI_RE = new RegExp(`${ESC}\\[[0-?]*[ -/]*[@-~]|${ESC}\\][^${BEL}]*${BEL}`, "g");
8
-
9
- const stripAnsi = (input: string): string => input.replace(ANSI_RE, "");
10
-
11
- export interface LogEntry {
12
- timestamp: number;
13
- source: string;
14
- line: string;
15
- isError?: boolean;
16
- }
17
-
18
- export interface DevLogger {
19
- logFile: string;
20
- latestFile: string;
21
- write: (entry: LogEntry) => Promise<void>;
22
- readLatest: (opts?: { tail?: number }) => Promise<string>;
23
- }
24
-
25
- export function getBosDir(configDir: string): string {
26
- return join(configDir, ".bos");
27
- }
28
-
29
- export function getLogsDir(configDir: string): string {
30
- return join(getBosDir(configDir), "logs");
31
- }
32
-
33
- function formatLogLine(entry: LogEntry): string {
34
- const ts = new Date(entry.timestamp).toISOString();
35
- const prefix = entry.isError ? "ERR" : "OUT";
36
- const clean = stripAnsi(entry.line);
37
- return `[${ts}] [${entry.source}] [${prefix}] ${clean}`;
38
- }
39
-
40
- export async function createDevLogger(configDir: string, description: string): Promise<DevLogger> {
41
- const dir = getLogsDir(configDir);
42
- if (!existsSync(dir)) {
43
- await mkdir(dir, { recursive: true });
44
- }
45
-
46
- const now = new Date();
47
- const ts = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
48
- const logFile = join(dir, `dev-${ts}.log`);
49
- const latestFile = join(dir, "dev-latest.log");
50
-
51
- const header =
52
- `# everything-dev dev session: ${description}\n` + `# Started: ${now.toISOString()}\n\n`;
53
- // Overwrite each run so dev-latest.log is always actionable.
54
- await writeFile(logFile, header, "utf8");
55
- await writeFile(latestFile, header, "utf8");
56
-
57
- let chain = Promise.resolve();
58
- const enqueue = (fn: () => Promise<void>) => {
59
- chain = chain.then(fn, fn);
60
- return chain;
61
- };
62
-
63
- return {
64
- logFile,
65
- latestFile,
66
- write: (entry) =>
67
- enqueue(async () => {
68
- const line = `${formatLogLine(entry)}\n`;
69
- await appendFile(logFile, line);
70
- await appendFile(latestFile, line);
71
- }),
72
- readLatest: async (opts) => {
73
- const text = await readFile(latestFile, "utf8").catch(() => "");
74
- const tail = opts?.tail;
75
- if (!tail || tail <= 0) return text;
76
- const lines = text.split("\n");
77
- return lines.slice(Math.max(0, lines.length - tail)).join("\n");
78
- },
79
- };
80
- }
81
-
82
- export async function readDevLatestLog(
83
- configDir: string,
84
- opts?: { tail?: number },
85
- ): Promise<string> {
86
- const latestFile = join(getLogsDir(configDir), "dev-latest.log");
87
- const text = await readFile(latestFile, "utf8").catch(() => "");
88
- const tail = opts?.tail;
89
- if (!tail || tail <= 0) return text;
90
- const lines = text.split("\n");
91
- return lines.slice(Math.max(0, lines.length - tail)).join("\n");
92
- }