lalph 0.1.78 → 0.1.80

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lalph",
3
3
  "type": "module",
4
- "version": "0.1.78",
4
+ "version": "0.1.80",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -74,7 +74,7 @@ export class CurrentIssueSource extends ServiceMap.Service<
74
74
  source.layer,
75
75
  yield* Layer.CurrentMemoMap,
76
76
  yield* Effect.scope,
77
- )
77
+ ).pipe(Effect.withSpan("CurrentIssueSource.build"))
78
78
  return ServiceMap.add(services, CurrentIssueSource, source)
79
79
  }),
80
80
  )
package/src/Prd.ts CHANGED
@@ -136,65 +136,67 @@ export class Prd extends ServiceMap.Service<
136
136
 
137
137
  const updatedIssues = new Map<string, PrdIssue>()
138
138
 
139
- const sync = syncSemaphore.withPermit(
140
- Effect.gen(function* () {
141
- const updated = yield* readPrd
142
- const anyChanges =
143
- updated.length !== current.length ||
144
- updated.some((u, i) => u.isChangedComparedTo(current[i]!))
145
- if (!anyChanges) {
146
- return
147
- }
139
+ const sync = Effect.gen(function* () {
140
+ const updated = yield* readPrd
141
+ const anyChanges =
142
+ updated.length !== current.length ||
143
+ updated.some((u, i) => u.isChangedComparedTo(current[i]!))
144
+ if (!anyChanges) {
145
+ return
146
+ }
148
147
 
149
- const githubPrs = new Map<string, number>()
150
- const toRemove = new Set(
151
- current.filter((i) => i.id !== null).map((i) => i.id!),
152
- )
148
+ const githubPrs = new Map<string, number>()
149
+ const toRemove = new Set(
150
+ current.filter((i) => i.id !== null).map((i) => i.id!),
151
+ )
153
152
 
154
- for (const issue of updated) {
155
- toRemove.delete(issue.id!)
153
+ for (const issue of updated) {
154
+ toRemove.delete(issue.id!)
156
155
 
157
- if (issue.id === null) {
158
- yield* source.createIssue(issue)
159
- continue
160
- }
156
+ if (issue.id === null) {
157
+ yield* source.createIssue(issue)
158
+ continue
159
+ }
161
160
 
162
- if (issue.githubPrNumber) {
163
- githubPrs.set(issue.id, issue.githubPrNumber)
164
- }
161
+ if (issue.githubPrNumber) {
162
+ githubPrs.set(issue.id, issue.githubPrNumber)
163
+ }
165
164
 
166
- const existing = current.find((i) => i.id === issue.id)
167
- if (!existing || !existing.isChangedComparedTo(issue)) continue
165
+ const existing = current.find((i) => i.id === issue.id)
166
+ if (!existing || !existing.isChangedComparedTo(issue)) continue
168
167
 
169
- yield* source.updateIssue({
170
- issueId: issue.id,
171
- title: issue.title,
172
- description: issue.description,
173
- state: issue.state,
174
- blockedBy: issue.blockedBy,
175
- })
168
+ yield* source.updateIssue({
169
+ issueId: issue.id,
170
+ title: issue.title,
171
+ description: issue.description,
172
+ state: issue.state,
173
+ blockedBy: issue.blockedBy,
174
+ })
176
175
 
177
- updatedIssues.set(issue.id, issue)
178
- }
176
+ updatedIssues.set(issue.id, issue)
177
+ }
179
178
 
180
- yield* Effect.forEach(
181
- toRemove,
182
- (issueId) => source.cancelIssue(issueId),
183
- { concurrency: "unbounded" },
184
- )
179
+ yield* Effect.forEach(
180
+ toRemove,
181
+ (issueId) => source.cancelIssue(issueId),
182
+ { concurrency: "unbounded" },
183
+ )
185
184
 
186
- current = yield* source.issues
187
- yield* fs.writeFileString(
188
- prdFile,
189
- PrdIssue.arrayToYaml(
190
- current.map((issue) => {
191
- const prNumber = githubPrs.get(issue.id!)
192
- if (!prNumber) return issue
193
- return new PrdIssue({ ...issue, githubPrNumber: prNumber })
194
- }),
195
- ),
196
- )
197
- }).pipe(Effect.uninterruptible),
185
+ current = yield* source.issues
186
+ yield* fs.writeFileString(
187
+ prdFile,
188
+ PrdIssue.arrayToYaml(
189
+ current.map((issue) => {
190
+ const prNumber = githubPrs.get(issue.id!)
191
+ if (!prNumber) return issue
192
+ return new PrdIssue({ ...issue, githubPrNumber: prNumber })
193
+ }),
194
+ ),
195
+ )
196
+ }).pipe(
197
+ Effect.uninterruptible,
198
+ syncSemaphore.withPermit,
199
+ Effect.withSpan("Prd.sync"),
198
200
  )
199
201
 
200
202
  const updateSyncHandle = yield* FiberHandle.make()
@@ -255,7 +257,7 @@ export class Prd extends ServiceMap.Service<
255
257
  flagUnmergable,
256
258
  findById,
257
259
  }
258
- }),
260
+ }).pipe(Effect.withSpan("Prd.build")),
259
261
  }) {
260
262
  static layerNoWorktree = Layer.effect(this, this.make)
261
263
  static layer = this.layerNoWorktree.pipe(Layer.provideMerge(Worktree.layer))
package/src/Tracing.ts ADDED
@@ -0,0 +1,64 @@
1
+ import {
2
+ Cause,
3
+ Duration,
4
+ Effect,
5
+ Fiber,
6
+ Layer,
7
+ Logger,
8
+ LogLevel,
9
+ Tracer,
10
+ } from "effect"
11
+ import { CurrentLoggers } from "effect/Logger"
12
+ import { MinimumLogLevel } from "effect/References"
13
+
14
+ export const TracingLayer = Layer.unwrap(
15
+ Effect.gen(function* () {
16
+ const logLevel = yield* MinimumLogLevel
17
+ if (LogLevel.isLessThan("Trace", logLevel)) {
18
+ return Layer.empty
19
+ }
20
+ return TracerLogger
21
+ }),
22
+ )
23
+
24
+ const TracerLogger = Effect.gen(function* () {
25
+ const loggers = yield* CurrentLoggers
26
+ const tracer = yield* Tracer.Tracer
27
+ const fiber = Fiber.getCurrent()!
28
+
29
+ const log = (message: string, time: bigint) => {
30
+ const date = new Date(Number(time / BigInt(1e6)))
31
+ const options: Logger.Logger.Options<string> = {
32
+ message,
33
+ fiber,
34
+ date,
35
+ logLevel: "Trace",
36
+ cause: Cause.empty,
37
+ }
38
+ loggers.forEach((logger) => {
39
+ logger.log(options)
40
+ })
41
+ }
42
+
43
+ return Tracer.make({
44
+ span(name, parent, annotations, links, startTime, kind, options) {
45
+ const span = tracer.span(
46
+ name,
47
+ parent,
48
+ annotations,
49
+ links,
50
+ startTime,
51
+ kind,
52
+ options,
53
+ )
54
+ log(`${name}: started`, startTime)
55
+ const oldEnd = span.end
56
+ span.end = (endTime, cause) => {
57
+ const duration = Duration.nanos(endTime - span.status.startTime)
58
+ log(`${name}: completed. Took ${Duration.format(duration)}`, endTime)
59
+ return oldEnd.call(span, endTime, cause)
60
+ }
61
+ return span
62
+ },
63
+ })
64
+ }).pipe(Layer.effect(Tracer.Tracer))
package/src/cli.ts CHANGED
@@ -14,6 +14,8 @@ import { commandAgent } from "./commands/agent.ts"
14
14
  import PackageJson from "../package.json" with { type: "json" }
15
15
  import { resetCurrentIssueSource } from "./IssueSources.ts"
16
16
  import { GithubCli } from "./Github/Cli.ts"
17
+ import { TracingLayer } from "./Tracing.ts"
18
+ import { MinimumLogLevel } from "effect/References"
17
19
 
18
20
  commandRoot.pipe(
19
21
  Command.withSubcommands([
@@ -32,6 +34,10 @@ commandRoot.pipe(
32
34
  }
33
35
  }),
34
36
  ),
37
+ Command.provide(TracingLayer),
38
+ Command.provide(({ verbose }) =>
39
+ verbose ? Layer.succeed(MinimumLogLevel, "All") : Layer.empty,
40
+ ),
35
41
  (_) =>
36
42
  Command.run(_, {
37
43
  version: PackageJson.version,
@@ -90,6 +90,11 @@ const specsDirectory = Flag.directory("specs").pipe(
90
90
  Flag.withDefault(".specs"),
91
91
  )
92
92
 
93
+ const verbose = Flag.boolean("verbose").pipe(
94
+ Flag.withDescription("Enable verbose logging"),
95
+ Flag.withAlias("v"),
96
+ )
97
+
93
98
  // handled in cli.ts
94
99
  const reset = Flag.boolean("reset").pipe(
95
100
  Flag.withDescription("Reset the current issue source before running"),
@@ -104,6 +109,7 @@ export const commandRoot = Command.make("lalph", {
104
109
  stallMinutes,
105
110
  reset,
106
111
  specsDirectory,
112
+ verbose,
107
113
  }).pipe(
108
114
  Command.withHandler(
109
115
  Effect.fnUntraced(function* ({
@@ -124,7 +130,10 @@ export const commandRoot = Command.make("lalph", {
124
130
  const semaphore = Effect.makeSemaphoreUnsafe(runConcurrency)
125
131
  const fibers = yield* FiberSet.make()
126
132
 
127
- yield* resetInProgress.pipe(Effect.provide(source))
133
+ yield* resetInProgress.pipe(
134
+ Effect.provide(source),
135
+ Effect.withSpan("Main.resetInProgress"),
136
+ )
128
137
 
129
138
  yield* Effect.log(
130
139
  `Executing ${iterationsDisplay} iteration(s) with concurrency ${runConcurrency}`,