@knpkv/jira-clockify 1.3.0 → 1.4.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.
- package/README.md +245 -1
- package/dist/package.json +36 -12
- package/dist/src/agent/agentSettings.d.ts +18 -0
- package/dist/src/agent/agentSettings.d.ts.map +1 -0
- package/dist/src/agent/agentSettings.js +23 -0
- package/dist/src/agent/agentSettings.js.map +1 -0
- package/dist/src/agent/schedule.d.ts +20 -0
- package/dist/src/agent/schedule.d.ts.map +1 -0
- package/dist/src/agent/schedule.js +189 -0
- package/dist/src/agent/schedule.js.map +1 -0
- package/dist/src/agent/sessions.d.ts +427 -0
- package/dist/src/agent/sessions.d.ts.map +1 -0
- package/dist/src/agent/sessions.js +868 -0
- package/dist/src/agent/sessions.js.map +1 -0
- package/dist/src/agent/sourceConsumption.d.ts +79 -0
- package/dist/src/agent/sourceConsumption.d.ts.map +1 -0
- package/dist/src/agent/sourceConsumption.js +191 -0
- package/dist/src/agent/sourceConsumption.js.map +1 -0
- package/dist/src/agent/watch.d.ts +76 -0
- package/dist/src/agent/watch.d.ts.map +1 -0
- package/dist/src/agent/watch.js +45 -0
- package/dist/src/agent/watch.js.map +1 -0
- package/dist/src/agent/writePlanning.d.ts +154 -0
- package/dist/src/agent/writePlanning.d.ts.map +1 -0
- package/dist/src/agent/writePlanning.js +210 -0
- package/dist/src/agent/writePlanning.js.map +1 -0
- package/dist/src/bin.d.ts +3 -0
- package/dist/src/bin.d.ts.map +1 -0
- package/dist/src/bin.js +9 -3
- package/dist/src/bin.js.map +1 -1
- package/dist/src/cli/agentWrite.d.ts +164 -0
- package/dist/src/cli/agentWrite.d.ts.map +1 -0
- package/dist/src/cli/agentWrite.js +362 -0
- package/dist/src/cli/agentWrite.js.map +1 -0
- package/dist/src/cli/auth.d.ts +8 -0
- package/dist/src/cli/auth.d.ts.map +1 -0
- package/dist/src/cli/auth.js +10 -10
- package/dist/src/cli/auth.js.map +1 -1
- package/dist/src/cli/calendar.d.ts +42 -0
- package/dist/src/cli/calendar.d.ts.map +1 -0
- package/dist/src/cli/calendar.js +189 -0
- package/dist/src/cli/calendar.js.map +1 -0
- package/dist/src/cli/config.d.ts +12 -0
- package/dist/src/cli/config.d.ts.map +1 -0
- package/dist/src/cli/config.js +163 -21
- package/dist/src/cli/config.js.map +1 -1
- package/dist/src/cli/fetchTicket.d.ts +51 -0
- package/dist/src/cli/fetchTicket.d.ts.map +1 -0
- package/dist/src/cli/fetchTicket.js +18 -2
- package/dist/src/cli/fetchTicket.js.map +1 -1
- package/dist/src/cli/fuzzySelect.d.ts +24 -0
- package/dist/src/cli/fuzzySelect.d.ts.map +1 -0
- package/dist/src/cli/layers.d.ts +40 -0
- package/dist/src/cli/layers.d.ts.map +1 -0
- package/dist/src/cli/layers.js +56 -12
- package/dist/src/cli/layers.js.map +1 -1
- package/dist/src/cli/list.d.ts +8 -0
- package/dist/src/cli/list.d.ts.map +1 -0
- package/dist/src/cli/list.js +2 -2
- package/dist/src/cli/list.js.map +1 -1
- package/dist/src/cli/reconcile.d.ts +129 -0
- package/dist/src/cli/reconcile.d.ts.map +1 -0
- package/dist/src/cli/reconcile.js +635 -46
- package/dist/src/cli/reconcile.js.map +1 -1
- package/dist/src/cli/root.d.ts +15 -0
- package/dist/src/cli/root.d.ts.map +1 -0
- package/dist/src/cli/root.js +4 -3
- package/dist/src/cli/root.js.map +1 -1
- package/dist/src/cli/runtimeFailure.d.ts +10 -0
- package/dist/src/cli/runtimeFailure.d.ts.map +1 -0
- package/dist/src/cli/runtimeFailure.js +17 -0
- package/dist/src/cli/runtimeFailure.js.map +1 -0
- package/dist/src/cli/setup.d.ts +10 -0
- package/dist/src/cli/setup.d.ts.map +1 -0
- package/dist/src/cli/setup.js +7 -7
- package/dist/src/cli/setup.js.map +1 -1
- package/dist/src/cli/timer/discard.d.ts +4 -0
- package/dist/src/cli/timer/discard.d.ts.map +1 -0
- package/dist/src/cli/timer/discard.js +2 -2
- package/dist/src/cli/timer/discard.js.map +1 -1
- package/dist/src/cli/timer/edit.d.ts +22 -0
- package/dist/src/cli/timer/edit.d.ts.map +1 -0
- package/dist/src/cli/timer/edit.js +62 -42
- package/dist/src/cli/timer/edit.js.map +1 -1
- package/dist/src/cli/timer/index.d.ts +12 -0
- package/dist/src/cli/timer/index.d.ts.map +1 -0
- package/dist/src/cli/timer/log.d.ts +16 -0
- package/dist/src/cli/timer/log.d.ts.map +1 -0
- package/dist/src/cli/timer/log.js +6 -6
- package/dist/src/cli/timer/log.js.map +1 -1
- package/dist/src/cli/timer/start.d.ts +21 -0
- package/dist/src/cli/timer/start.d.ts.map +1 -0
- package/dist/src/cli/timer/start.js +9 -9
- package/dist/src/cli/timer/start.js.map +1 -1
- package/dist/src/cli/timer/status.d.ts +22 -0
- package/dist/src/cli/timer/status.d.ts.map +1 -0
- package/dist/src/cli/timer/status.js +3 -3
- package/dist/src/cli/timer/status.js.map +1 -1
- package/dist/src/cli/timer/stop.d.ts +48 -0
- package/dist/src/cli/timer/stop.d.ts.map +1 -0
- package/dist/src/cli/timer/stop.js +19 -19
- package/dist/src/cli/timer/stop.js.map +1 -1
- package/dist/src/cli/timer.d.ts +11 -0
- package/dist/src/cli/timer.d.ts.map +1 -0
- package/dist/src/cli/timer.js +1 -1
- package/dist/src/cli/timer.js.map +1 -1
- package/dist/src/cli/watch.d.ts +54 -0
- package/dist/src/cli/watch.d.ts.map +1 -0
- package/dist/src/cli/watch.js +412 -0
- package/dist/src/cli/watch.js.map +1 -0
- package/dist/src/cli/watchLease.d.ts +99 -0
- package/dist/src/cli/watchLease.d.ts.map +1 -0
- package/dist/src/cli/watchLease.js +204 -0
- package/dist/src/cli/watchLease.js.map +1 -0
- package/dist/src/cli/writerGuard.d.ts +37 -0
- package/dist/src/cli/writerGuard.d.ts.map +1 -0
- package/dist/src/cli/writerGuard.js +92 -0
- package/dist/src/cli/writerGuard.js.map +1 -0
- package/dist/src/index.d.ts +46 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +46 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/main.d.ts +4 -0
- package/dist/src/main.d.ts.map +1 -0
- package/dist/src/services/AgentSessionReader.d.ts +121 -0
- package/dist/src/services/AgentSessionReader.d.ts.map +1 -0
- package/dist/src/services/AgentSessionReader.js +392 -0
- package/dist/src/services/AgentSessionReader.js.map +1 -0
- package/dist/src/services/ClockifyAuth.d.ts +47 -0
- package/dist/src/services/ClockifyAuth.d.ts.map +1 -0
- package/dist/src/services/ClockifyAuth.js +2 -2
- package/dist/src/services/ClockifyAuth.js.map +1 -1
- package/dist/src/services/CodexTranscript.d.ts +112 -0
- package/dist/src/services/CodexTranscript.d.ts.map +1 -0
- package/dist/src/services/CodexTranscript.js +96 -0
- package/dist/src/services/CodexTranscript.js.map +1 -0
- package/dist/src/services/ConfigService.d.ts +99 -0
- package/dist/src/services/ConfigService.d.ts.map +1 -0
- package/dist/src/services/ConfigService.js +79 -7
- package/dist/src/services/ConfigService.js.map +1 -1
- package/dist/src/services/HomeDirectory.d.ts +17 -0
- package/dist/src/services/HomeDirectory.d.ts.map +1 -0
- package/dist/src/services/HomeDirectory.js +1 -1
- package/dist/src/services/IssueFacts.d.ts +127 -0
- package/dist/src/services/IssueFacts.d.ts.map +1 -0
- package/dist/src/services/IssueFacts.js +277 -0
- package/dist/src/services/IssueFacts.js.map +1 -0
- package/dist/src/services/ProviderDeletion.d.ts +19 -0
- package/dist/src/services/ProviderDeletion.d.ts.map +1 -0
- package/dist/src/services/ProviderDeletion.js +37 -0
- package/dist/src/services/ProviderDeletion.js.map +1 -0
- package/dist/src/services/ReconcileService.d.ts +378 -0
- package/dist/src/services/ReconcileService.d.ts.map +1 -0
- package/dist/src/services/ReconcileService.js +1270 -79
- package/dist/src/services/ReconcileService.js.map +1 -1
- package/dist/src/services/SavedEntries.d.ts +40 -0
- package/dist/src/services/SavedEntries.d.ts.map +1 -0
- package/dist/src/services/SavedEntries.js +209 -0
- package/dist/src/services/SavedEntries.js.map +1 -0
- package/dist/src/services/SessionAttributor.d.ts +114 -0
- package/dist/src/services/SessionAttributor.d.ts.map +1 -0
- package/dist/src/services/SessionAttributor.js +240 -0
- package/dist/src/services/SessionAttributor.js.map +1 -0
- package/dist/src/services/SourceLedger.d.ts +104 -0
- package/dist/src/services/SourceLedger.d.ts.map +1 -0
- package/dist/src/services/SourceLedger.js +302 -0
- package/dist/src/services/SourceLedger.js.map +1 -0
- package/dist/src/services/StateWriter.d.ts +39 -0
- package/dist/src/services/StateWriter.d.ts.map +1 -0
- package/dist/src/services/TicketService.d.ts +63 -0
- package/dist/src/services/TicketService.d.ts.map +1 -0
- package/dist/src/services/TimerService.d.ts +145 -0
- package/dist/src/services/TimerService.d.ts.map +1 -0
- package/dist/src/services/TimerService.js +113 -80
- package/dist/src/services/TimerService.js.map +1 -1
- package/dist/src/services/internal/JiraWorklogPost.d.ts +7 -0
- package/dist/src/services/internal/JiraWorklogPost.d.ts.map +1 -0
- package/dist/src/services/internal/JiraWorklogPost.js +32 -0
- package/dist/src/services/internal/JiraWorklogPost.js.map +1 -0
- package/dist/src/testing/fakeHeadless.d.ts +318 -0
- package/dist/src/testing/fakeHeadless.d.ts.map +1 -0
- package/dist/src/testing/fakeHeadless.js +1149 -0
- package/dist/src/testing/fakeHeadless.js.map +1 -0
- package/dist/src/tui/App.d.ts +6 -0
- package/dist/src/tui/App.d.ts.map +1 -0
- package/dist/src/tui/App.js +1 -1
- package/dist/src/tui/App.js.map +1 -1
- package/dist/src/tui/atoms/runtime.d.ts +8 -0
- package/dist/src/tui/atoms/runtime.d.ts.map +1 -0
- package/dist/src/tui/atoms/runtime.js +1 -1
- package/dist/src/tui/atoms/runtime.js.map +1 -1
- package/dist/src/tui/atoms/tickets.d.ts +3 -0
- package/dist/src/tui/atoms/tickets.d.ts.map +1 -0
- package/dist/src/tui/atoms/timer.d.ts +11 -0
- package/dist/src/tui/atoms/timer.d.ts.map +1 -0
- package/dist/src/tui/atoms/timer.js +1 -1
- package/dist/src/tui/atoms/timer.js.map +1 -1
- package/dist/src/tui/atoms/ui.d.ts +11 -0
- package/dist/src/tui/atoms/ui.d.ts.map +1 -0
- package/dist/src/tui/atoms/ui.js +1 -1
- package/dist/src/tui/atoms/ui.js.map +1 -1
- package/dist/src/tui/components/BigTimer.d.ts +2 -0
- package/dist/src/tui/components/BigTimer.d.ts.map +1 -0
- package/dist/src/tui/components/Footer.d.ts +2 -0
- package/dist/src/tui/components/Footer.d.ts.map +1 -0
- package/dist/src/tui/components/Header.d.ts +2 -0
- package/dist/src/tui/components/Header.d.ts.map +1 -0
- package/dist/src/tui/components/Header.js +1 -1
- package/dist/src/tui/components/Header.js.map +1 -1
- package/dist/src/tui/components/PopupInput.d.ts +18 -0
- package/dist/src/tui/components/PopupInput.d.ts.map +1 -0
- package/dist/src/tui/components/PopupMessage.d.ts +20 -0
- package/dist/src/tui/components/PopupMessage.d.ts.map +1 -0
- package/dist/src/tui/components/TicketList.d.ts +2 -0
- package/dist/src/tui/components/TicketList.d.ts.map +1 -0
- package/dist/src/tui/components/TicketList.js +1 -1
- package/dist/src/tui/components/TicketList.js.map +1 -1
- package/dist/src/tui/components/TicketRow.d.ts +8 -0
- package/dist/src/tui/components/TicketRow.d.ts.map +1 -0
- package/dist/src/tui/components/TimerDisplay.d.ts +2 -0
- package/dist/src/tui/components/TimerDisplay.d.ts.map +1 -0
- package/dist/src/tui/components/index.d.ts +12 -0
- package/dist/src/tui/components/index.d.ts.map +1 -0
- package/dist/src/tui/context/theme.d.ts +15 -0
- package/dist/src/tui/context/theme.d.ts.map +1 -0
- package/dist/src/tui/hooks/useElapsedTimer.d.ts +6 -0
- package/dist/src/tui/hooks/useElapsedTimer.d.ts.map +1 -0
- package/dist/src/tui/hooks/useElapsedTimer.js +1 -1
- package/dist/src/tui/hooks/useElapsedTimer.js.map +1 -1
- package/dist/src/tui/hooks/useTerminalSize.d.ts +5 -0
- package/dist/src/tui/hooks/useTerminalSize.d.ts.map +1 -0
- package/dist/src/utils/hints.d.ts +12 -0
- package/dist/src/utils/hints.d.ts.map +1 -0
- package/dist/src/utils/hints.js +12 -0
- package/dist/src/utils/hints.js.map +1 -0
- package/dist/src/utils/time.d.ts +104 -0
- package/dist/src/utils/time.d.ts.map +1 -0
- package/dist/src/utils/time.js +74 -8
- package/dist/src/utils/time.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +36 -18
- package/skills/jcf/SKILL.md +93 -1
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ask a Coding Agent two things about an Agent Session: which Issue Key it was *worked on*, among
|
|
3
|
+
* the keys the session itself mentions, and what was done in it.
|
|
4
|
+
*
|
|
5
|
+
* **Mental model**
|
|
6
|
+
*
|
|
7
|
+
* - **Two questions, one boundary**: attribution decides *where* time goes, description says *what*
|
|
8
|
+
* the time was. They share this module because they share the model, the batching and the
|
|
9
|
+
* no-tools policy — and because keeping `LanguageModel` in one place is the point of the seam.
|
|
10
|
+
*
|
|
11
|
+
* - **Last resort, in batches**: attribution is asked for only where no deterministic Attribution
|
|
12
|
+
* Signal could place a session — long-lived integration branches, mostly — so a run of
|
|
13
|
+
* branch-attributed work never asks it at all. Description is asked for only about the rows a user
|
|
14
|
+
* has *confirmed*, so nothing is spent describing a row that is never written. Either way the
|
|
15
|
+
* outstanding work goes in one call, because a call's cost is almost entirely fixed overhead.
|
|
16
|
+
* - **Closed choice set**: the candidates come from the transcript's own text and a key outside
|
|
17
|
+
* that set is rejected by the caller, so an invented Issue Key is structurally impossible
|
|
18
|
+
* rather than merely discouraged by the prompt.
|
|
19
|
+
* - **"None" is a first-class answer**: a release-notes document mentions dozens of tickets it
|
|
20
|
+
* describes and works on none of them. Frequency is anti-correlated with what should be
|
|
21
|
+
* billed, so the question asked is "worked on, or only referenced?".
|
|
22
|
+
*
|
|
23
|
+
* **Gotchas**
|
|
24
|
+
*
|
|
25
|
+
* - The narrow interface is deliberate: `LanguageModel` stays inside this module so no consumer
|
|
26
|
+
* or test has to know a model exists.
|
|
27
|
+
* - Failures are typed, not fatal. A caller that cannot reach a Coding Agent still reports the
|
|
28
|
+
* deterministic proposals and lists the rest as Unattributed Sessions.
|
|
29
|
+
*
|
|
30
|
+
* @module
|
|
31
|
+
*/
|
|
32
|
+
import { model as claudeModel } from "@knpkv/ai-claude";
|
|
33
|
+
import { model as codexModel } from "@knpkv/ai-codex";
|
|
34
|
+
import { LanguageModel } from "effect/ai";
|
|
35
|
+
import * as Context from "effect/Context";
|
|
36
|
+
import * as Data from "effect/Data";
|
|
37
|
+
import * as Duration from "effect/Duration";
|
|
38
|
+
import * as Effect from "effect/Effect";
|
|
39
|
+
import * as FileSystem from "effect/FileSystem";
|
|
40
|
+
import * as Layer from "effect/Layer";
|
|
41
|
+
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
42
|
+
import * as Schema from "effect/Schema";
|
|
43
|
+
import { ConfigService } from "./ConfigService.js";
|
|
44
|
+
import { HomeDirectory } from "./HomeDirectory.js";
|
|
45
|
+
export class SessionAttributorError extends Data.TaggedError("SessionAttributorError") {
|
|
46
|
+
}
|
|
47
|
+
export class SessionAttributor extends Context.Service()("jcf/SessionAttributor") {
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Prompt
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
const Answer = Schema.Struct({
|
|
53
|
+
/** Echoes the session the answer is for, so a reordered or partial reply still lines up. */
|
|
54
|
+
sessionId: Schema.String,
|
|
55
|
+
/** One of *that session's* candidates, or null for "none of these". */
|
|
56
|
+
ticketKey: Schema.NullOr(Schema.String),
|
|
57
|
+
/** How sure the choice is, 0 to 1. */
|
|
58
|
+
confidence: Schema.Number,
|
|
59
|
+
/** One short sentence of justification. Requested to improve the choice; not displayed. */
|
|
60
|
+
reason: Schema.String
|
|
61
|
+
});
|
|
62
|
+
const Answers = Schema.Struct({ answers: Schema.Array(Answer) });
|
|
63
|
+
/**
|
|
64
|
+
* One prompt covering every session in the batch, each with its *own* candidate list.
|
|
65
|
+
*
|
|
66
|
+
* Keeping the candidate lists per session is what makes batching safe: an answer naming a key from
|
|
67
|
+
* a different session's list is rejected downstream, because a choice is only accepted when it
|
|
68
|
+
* appears in the candidates of the session it claims to describe.
|
|
69
|
+
*/
|
|
70
|
+
const buildPrompt = (requests) => [
|
|
71
|
+
"For each coding session below, decide which Jira issue it was WORKED ON.",
|
|
72
|
+
"",
|
|
73
|
+
"Answer once per session, echoing its id. Choose only from that session's own candidate list, or",
|
|
74
|
+
"null. A session's answer must never use a key from another session's list.",
|
|
75
|
+
"",
|
|
76
|
+
"An issue that is merely REFERENCED is not the answer. A release-notes or known-issues document",
|
|
77
|
+
"mentions many issues it describes while working on none of them, and mentioning an issue often",
|
|
78
|
+
"says nothing about whether it was worked on. If a session's real subject is not among its own",
|
|
79
|
+
"candidates, or you cannot tell, answer with ticketKey: null.",
|
|
80
|
+
"",
|
|
81
|
+
"Set confidence between 0 and 1: how sure you are that the session's work should be logged",
|
|
82
|
+
"against that issue.",
|
|
83
|
+
"",
|
|
84
|
+
...requests.flatMap((request) => [
|
|
85
|
+
`--- session ${request.sessionId} ---`,
|
|
86
|
+
`Candidates: ${request.candidateKeys.join(", ")}`,
|
|
87
|
+
"Digest:",
|
|
88
|
+
request.digest,
|
|
89
|
+
""
|
|
90
|
+
])
|
|
91
|
+
].join("\n");
|
|
92
|
+
/** The longest note that belongs on a worklog line. Past this it stops being a summary. */
|
|
93
|
+
const MAX_NOTE_CHARS = 120;
|
|
94
|
+
const Note = Schema.Struct({
|
|
95
|
+
/** Echoes the work item the note is for, so a reordered or partial reply still lines up. */
|
|
96
|
+
id: Schema.String,
|
|
97
|
+
/** One sentence, or null when the digest does not say what was done. */
|
|
98
|
+
note: Schema.NullOr(Schema.String)
|
|
99
|
+
});
|
|
100
|
+
const Notes = Schema.Struct({ notes: Schema.Array(Note) });
|
|
101
|
+
/**
|
|
102
|
+
* One prompt covering every work item in the batch.
|
|
103
|
+
*
|
|
104
|
+
* The instructions are mostly prohibitions, because the failure mode here is not a wrong sentence
|
|
105
|
+
* but a *padded* one: a worklog line has no room for a preamble, a restatement of the issue title, or
|
|
106
|
+
* an apology for uncertainty. Silence is a correct answer and is asked for explicitly, so a session
|
|
107
|
+
* whose prompts say nothing useful produces no note rather than an invented one.
|
|
108
|
+
*/
|
|
109
|
+
const buildDescribePrompt = (requests) => [
|
|
110
|
+
"For each work item below, write ONE short sentence saying what was actually done, read from the",
|
|
111
|
+
"session prompts.",
|
|
112
|
+
"",
|
|
113
|
+
"Answer once per item, echoing its id. Rules:",
|
|
114
|
+
`- Past tense, at most ${MAX_NOTE_CHARS} characters, no trailing full stop.`,
|
|
115
|
+
"- Describe the work, not the conversation: no \"asked about\", no \"discussed\", no \"the user\".",
|
|
116
|
+
"- Do not repeat the issue key or the issue title, and do not add a preamble.",
|
|
117
|
+
"- If the prompts do not say what was done, answer with note: null. Do not guess.",
|
|
118
|
+
"",
|
|
119
|
+
...requests.flatMap((request) => [
|
|
120
|
+
`--- item ${request.id} ---`,
|
|
121
|
+
request.ticketKey === null
|
|
122
|
+
? "No associated Jira issue"
|
|
123
|
+
: `Issue: ${request.ticketKey}${request.summary === null ? "" : ` — ${request.summary}`}`,
|
|
124
|
+
"Digest:",
|
|
125
|
+
request.digest,
|
|
126
|
+
""
|
|
127
|
+
])
|
|
128
|
+
].join("\n");
|
|
129
|
+
/**
|
|
130
|
+
* Per-call ceiling. The provider default is two minutes, which is a long time to wait for a
|
|
131
|
+
* one-line classification when a run makes several calls.
|
|
132
|
+
*
|
|
133
|
+
* Measured, not guessed: at 45 seconds two of seven real sessions timed out, because several CLI
|
|
134
|
+
* processes run at once and compete for the machine. 90 seconds cleared them while still bounding
|
|
135
|
+
* a run to roughly two rounds. A session that does time out is reported as unattributed, which is
|
|
136
|
+
* the safe direction.
|
|
137
|
+
*/
|
|
138
|
+
const ATTRIBUTION_TIMEOUT = Duration.seconds(90);
|
|
139
|
+
const clipNote = (note) => note.length <= MAX_NOTE_CHARS ? note : `${note.slice(0, MAX_NOTE_CHARS - 1).trimEnd()}…`;
|
|
140
|
+
const clampConfidence = (value) => {
|
|
141
|
+
if (!Number.isFinite(value))
|
|
142
|
+
return 0;
|
|
143
|
+
return Math.min(1, Math.max(0, value));
|
|
144
|
+
};
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// Service
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
export const layer = Layer.effect(SessionAttributor, Effect.gen(function* () {
|
|
149
|
+
const home = (yield* HomeDirectory).path;
|
|
150
|
+
const config = yield* ConfigService;
|
|
151
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
152
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
153
|
+
// Both adapters receive all work material in the prompt and grant no tool authority.
|
|
154
|
+
// Capture platform services here so operation callers only require SessionAttributor.
|
|
155
|
+
const provider = (settings, onActivity) => {
|
|
156
|
+
const common = {
|
|
157
|
+
cwd: home,
|
|
158
|
+
timeout: ATTRIBUTION_TIMEOUT,
|
|
159
|
+
onActivity,
|
|
160
|
+
...(settings.model !== null && { model: settings.model })
|
|
161
|
+
};
|
|
162
|
+
return settings.provider === "claude"
|
|
163
|
+
? claudeModel({
|
|
164
|
+
...common,
|
|
165
|
+
access: "prompt-only",
|
|
166
|
+
...(settings.effort !== null && { effort: settings.effort })
|
|
167
|
+
})
|
|
168
|
+
: codexModel({
|
|
169
|
+
...common,
|
|
170
|
+
access: "read-only",
|
|
171
|
+
promptOnly: true,
|
|
172
|
+
...(settings.effort !== null && { effort: settings.effort })
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
const attribute = (requests, onActivity) => Effect.gen(function* () {
|
|
176
|
+
// Nothing to choose from anywhere — no point spending a call to learn that.
|
|
177
|
+
const askable = requests.filter((request) => request.candidateKeys.length > 0);
|
|
178
|
+
const none = (sessionId) => ({
|
|
179
|
+
sessionId,
|
|
180
|
+
choice: { _tag: "None" }
|
|
181
|
+
});
|
|
182
|
+
if (askable.length === 0)
|
|
183
|
+
return requests.map((request) => none(request.sessionId));
|
|
184
|
+
const settings = (yield* config.get).sessionAgent;
|
|
185
|
+
const response = yield* LanguageModel.generateObject({
|
|
186
|
+
prompt: buildPrompt(askable),
|
|
187
|
+
schema: Answers,
|
|
188
|
+
objectName: "attributions"
|
|
189
|
+
}).pipe(
|
|
190
|
+
// The provider is built per call and lives exactly as long as the call does, which is the
|
|
191
|
+
// scope this diagnostic exists to protect rather than one it puts at risk.
|
|
192
|
+
// @effect-diagnostics-next-line strictEffectProvide:off
|
|
193
|
+
Effect.provide(provider(settings, onActivity)), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.mapError((cause) => new SessionAttributorError({ message: `Coding Agent attribution failed: ${cause.message}`, cause })));
|
|
194
|
+
const bySession = new Map(response.value.answers.map((answer) => [answer.sessionId, answer]));
|
|
195
|
+
// Answered in request order, so a reply that omits, duplicates or reorders sessions cannot
|
|
196
|
+
// shift an answer onto the wrong one.
|
|
197
|
+
return requests.map((request) => {
|
|
198
|
+
const answer = bySession.get(request.sessionId);
|
|
199
|
+
if (answer === undefined || answer.ticketKey === null)
|
|
200
|
+
return none(request.sessionId);
|
|
201
|
+
return {
|
|
202
|
+
sessionId: request.sessionId,
|
|
203
|
+
choice: {
|
|
204
|
+
_tag: "Chosen",
|
|
205
|
+
ticketKey: answer.ticketKey,
|
|
206
|
+
confidence: clampConfidence(answer.confidence)
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
const describe = (requests) => Effect.gen(function* () {
|
|
212
|
+
// Nothing to read means nothing to say, and no reason to spend a call learning that.
|
|
213
|
+
const askable = requests.filter((request) => request.digest.trim() !== "");
|
|
214
|
+
const silent = (id) => ({ id, note: null });
|
|
215
|
+
if (askable.length === 0)
|
|
216
|
+
return requests.map((request) => silent(request.id));
|
|
217
|
+
const settings = (yield* config.get).sessionAgent;
|
|
218
|
+
const response = yield* LanguageModel.generateObject({
|
|
219
|
+
prompt: buildDescribePrompt(askable),
|
|
220
|
+
schema: Notes,
|
|
221
|
+
objectName: "notes"
|
|
222
|
+
}).pipe(
|
|
223
|
+
// The provider is built per call and lives exactly as long as the call does, which is the
|
|
224
|
+
// scope this diagnostic exists to protect rather than one it puts at risk.
|
|
225
|
+
// @effect-diagnostics-next-line strictEffectProvide:off
|
|
226
|
+
Effect.provide(provider(settings)), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.mapError((cause) => new SessionAttributorError({ message: `Coding Agent description failed: ${cause.message}`, cause })));
|
|
227
|
+
const byId = new Map(response.value.notes.map((note) => [note.id, note]));
|
|
228
|
+
return requests.map((request) => {
|
|
229
|
+
const answer = byId.get(request.id);
|
|
230
|
+
if (answer === undefined || answer.note === null)
|
|
231
|
+
return silent(request.id);
|
|
232
|
+
const note = answer.note.trim();
|
|
233
|
+
// Clipped rather than rejected: an over-long sentence is still a useful one, and a worklog
|
|
234
|
+
// line is the wrong place to find out that a model ignored a character budget.
|
|
235
|
+
return { id: request.id, note: note === "" ? null : clipNote(note) };
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
return { attribute, describe };
|
|
239
|
+
}));
|
|
240
|
+
//# sourceMappingURL=SessionAttributor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionAttributor.js","sourceRoot":"","sources":["../../../src/services/SessionAttributor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Private, versioned bindings between confirmed session writes and provider entries. */
|
|
2
|
+
import * as Context from "effect/Context";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as FileSystem from "effect/FileSystem";
|
|
5
|
+
import * as Layer from "effect/Layer";
|
|
6
|
+
import * as Path from "effect/Path";
|
|
7
|
+
import * as Schema from "effect/Schema";
|
|
8
|
+
import { ConfigService } from "./ConfigService.js";
|
|
9
|
+
declare const Identity: Schema.Struct<{
|
|
10
|
+
readonly provider: Schema.Literals<readonly ["clockify", "jira"]>;
|
|
11
|
+
readonly scope: Schema.NonEmptyString;
|
|
12
|
+
readonly rowId: Schema.NonEmptyString;
|
|
13
|
+
readonly sourceStartMs: Schema.Finite;
|
|
14
|
+
readonly startMs: Schema.Finite;
|
|
15
|
+
readonly endMs: Schema.Finite;
|
|
16
|
+
readonly seconds: Schema.Finite;
|
|
17
|
+
readonly ticketKey: Schema.NonEmptyString;
|
|
18
|
+
}>;
|
|
19
|
+
export interface SourceIdentity extends Schema.Schema.Type<typeof Identity> {
|
|
20
|
+
}
|
|
21
|
+
declare const Binding: Schema.Struct<{
|
|
22
|
+
readonly provider: Schema.Literals<readonly ["clockify", "jira"]>;
|
|
23
|
+
readonly scope: Schema.NonEmptyString;
|
|
24
|
+
readonly rowId: Schema.NonEmptyString;
|
|
25
|
+
readonly sourceStartMs: Schema.Finite;
|
|
26
|
+
readonly startMs: Schema.Finite;
|
|
27
|
+
readonly endMs: Schema.Finite;
|
|
28
|
+
readonly seconds: Schema.Finite;
|
|
29
|
+
readonly ticketKey: Schema.NonEmptyString;
|
|
30
|
+
readonly entryId: Schema.NonEmptyString;
|
|
31
|
+
readonly jiraCreatedAtMs: Schema.optionalKey<Schema.Number>;
|
|
32
|
+
}>;
|
|
33
|
+
export interface SourceBinding extends Schema.Schema.Type<typeof Binding> {
|
|
34
|
+
}
|
|
35
|
+
declare const ReviewedWindow: Schema.Struct<{
|
|
36
|
+
readonly provider: Schema.Literals<readonly ["clockify", "jira"]>;
|
|
37
|
+
readonly scope: Schema.NonEmptyString;
|
|
38
|
+
readonly fromMs: Schema.Finite;
|
|
39
|
+
readonly toMs: Schema.Finite;
|
|
40
|
+
}>;
|
|
41
|
+
export interface SourceWindow extends Schema.Schema.Type<typeof ReviewedWindow> {
|
|
42
|
+
}
|
|
43
|
+
declare const LedgerFile: Schema.Struct<{
|
|
44
|
+
readonly version: Schema.Literal<4>;
|
|
45
|
+
readonly reviewedWindows: Schema.$Array<Schema.Struct<{
|
|
46
|
+
readonly provider: Schema.Literals<readonly ["clockify", "jira"]>;
|
|
47
|
+
readonly scope: Schema.NonEmptyString;
|
|
48
|
+
readonly fromMs: Schema.Finite;
|
|
49
|
+
readonly toMs: Schema.Finite;
|
|
50
|
+
}>>;
|
|
51
|
+
readonly pending: Schema.$Array<Schema.Struct<{
|
|
52
|
+
readonly provider: Schema.Literals<readonly ["clockify", "jira"]>;
|
|
53
|
+
readonly scope: Schema.NonEmptyString;
|
|
54
|
+
readonly rowId: Schema.NonEmptyString;
|
|
55
|
+
readonly sourceStartMs: Schema.Finite;
|
|
56
|
+
readonly startMs: Schema.Finite;
|
|
57
|
+
readonly endMs: Schema.Finite;
|
|
58
|
+
readonly seconds: Schema.Finite;
|
|
59
|
+
readonly ticketKey: Schema.NonEmptyString;
|
|
60
|
+
}>>;
|
|
61
|
+
readonly bindings: Schema.$Array<Schema.Struct<{
|
|
62
|
+
readonly provider: Schema.Literals<readonly ["clockify", "jira"]>;
|
|
63
|
+
readonly scope: Schema.NonEmptyString;
|
|
64
|
+
readonly rowId: Schema.NonEmptyString;
|
|
65
|
+
readonly sourceStartMs: Schema.Finite;
|
|
66
|
+
readonly startMs: Schema.Finite;
|
|
67
|
+
readonly endMs: Schema.Finite;
|
|
68
|
+
readonly seconds: Schema.Finite;
|
|
69
|
+
readonly ticketKey: Schema.NonEmptyString;
|
|
70
|
+
readonly entryId: Schema.NonEmptyString;
|
|
71
|
+
readonly jiraCreatedAtMs: Schema.optionalKey<Schema.Number>;
|
|
72
|
+
}>>;
|
|
73
|
+
readonly observedUnbound: Schema.$Array<Schema.Struct<{
|
|
74
|
+
readonly provider: Schema.Literals<readonly ["clockify", "jira"]>;
|
|
75
|
+
readonly scope: Schema.NonEmptyString;
|
|
76
|
+
readonly entryId: Schema.NonEmptyString;
|
|
77
|
+
readonly startMs: Schema.Finite;
|
|
78
|
+
}>>;
|
|
79
|
+
}>;
|
|
80
|
+
export type LedgerFile = typeof LedgerFile.Type;
|
|
81
|
+
declare const SourceLedgerError_base: Schema.Class<SourceLedgerError, Schema.TaggedStruct<"SourceLedgerError", {
|
|
82
|
+
readonly message: Schema.String;
|
|
83
|
+
readonly cause: Schema.optionalKey<Schema.Defect>;
|
|
84
|
+
}>, import("effect/Cause").YieldableError>;
|
|
85
|
+
export declare class SourceLedgerError extends SourceLedgerError_base {
|
|
86
|
+
}
|
|
87
|
+
export interface SourceLedgerContract {
|
|
88
|
+
readonly read: Effect.Effect<LedgerFile, SourceLedgerError>;
|
|
89
|
+
readonly assertNoLegacyClockify: (legacyScope: string) => Effect.Effect<void, SourceLedgerError>;
|
|
90
|
+
readonly reserve: (identity: SourceIdentity, legacyScope?: string) => Effect.Effect<void, SourceLedgerError>;
|
|
91
|
+
readonly bind: (identity: SourceIdentity, entryId: string, jiraCreatedAtMs?: number) => Effect.Effect<void, SourceLedgerError>;
|
|
92
|
+
readonly release: (identity: SourceIdentity) => Effect.Effect<void, SourceLedgerError>;
|
|
93
|
+
readonly ensureWindow: (window: SourceWindow, observed: ReadonlyArray<{
|
|
94
|
+
readonly entryId: string;
|
|
95
|
+
readonly startMs: number;
|
|
96
|
+
}>, markerBindings: ReadonlyArray<SourceBinding>, legacyScope?: string) => Effect.Effect<void, SourceLedgerError>;
|
|
97
|
+
}
|
|
98
|
+
declare const SourceLedger_base: Context.ServiceClass<SourceLedger, "jcf/SourceLedger", SourceLedgerContract>;
|
|
99
|
+
export declare class SourceLedger extends SourceLedger_base {
|
|
100
|
+
}
|
|
101
|
+
/** A pending remote create never becomes permission to repeat it after a crash. */
|
|
102
|
+
export declare const layer: Layer.Layer<SourceLedger, never, ConfigService | FileSystem.FileSystem | Path.Path>;
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=SourceLedger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SourceLedger.d.ts","sourceRoot":"","sources":["../../../src/services/SourceLedger.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAKlD,QAAA,MAAM,QAAQ;;;;;;;;;EAgBb,CAAA;AAED,MAAM,WAAW,cAAe,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,QAAQ,CAAC;CAAG;AAQ9E,QAAA,MAAM,OAAO;;;;;;;;;;;EAEV,CAAA;AACH,MAAM,WAAW,aAAc,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC;CAAG;AAE5E,QAAA,MAAM,cAAc;;;;;EAKsF,CAAA;AAC1G,MAAM,WAAW,YAAa,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,cAAc,CAAC;CAAG;AAgClF,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwB8E,CAAA;AAE9F,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAA;;;;;AA+B/C,qBAAa,iBAAkB,SAAQ,sBAGrC;CAAG;AAEL,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;IAC3D,QAAQ,CAAC,sBAAsB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IAChG,QAAQ,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IAC5G,QAAQ,CAAC,IAAI,EAAE,CACb,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,MAAM,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;IACtF,QAAQ,CAAC,YAAY,EAAE,CACrB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,EAC/E,cAAc,EAAE,aAAa,CAAC,aAAa,CAAC,EAC5C,WAAW,CAAC,EAAE,MAAM,KACjB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;CAC5C;;AAED,qBAAa,YAAa,SAAQ,iBAAyE;CAAG;AAkB9G,mFAAmF;AACnF,eAAO,MAAM,KAAK,qFAkSjB,CAAA"}
|