@jinion/core 0.5.0 → 0.5.1

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 (217) hide show
  1. package/dist/agent/agent.d.ts +3 -0
  2. package/dist/agent/agent.d.ts.map +1 -1
  3. package/dist/agent/agent.js.map +1 -1
  4. package/dist/agent/claude/backend.d.ts +1 -1
  5. package/dist/agent/claude/backend.d.ts.map +1 -1
  6. package/dist/agent/claude/backend.js +2 -1
  7. package/dist/agent/claude/backend.js.map +1 -1
  8. package/dist/agent/claude/jinion-tools.d.ts +3 -1
  9. package/dist/agent/claude/jinion-tools.d.ts.map +1 -1
  10. package/dist/agent/claude/jinion-tools.js +10 -1
  11. package/dist/agent/claude/jinion-tools.js.map +1 -1
  12. package/dist/agent/claude/options.d.ts +4 -1
  13. package/dist/agent/claude/options.d.ts.map +1 -1
  14. package/dist/agent/claude/options.js +4 -4
  15. package/dist/agent/claude/options.js.map +1 -1
  16. package/dist/agent/claude/prompt.d.ts +2 -1
  17. package/dist/agent/claude/prompt.d.ts.map +1 -1
  18. package/dist/agent/claude/prompt.js +3 -1
  19. package/dist/agent/claude/prompt.js.map +1 -1
  20. package/dist/agent/claude/session.d.ts +9 -1
  21. package/dist/agent/claude/session.d.ts.map +1 -1
  22. package/dist/agent/claude/session.js +13 -3
  23. package/dist/agent/claude/session.js.map +1 -1
  24. package/dist/agent/claude/tool-calls.d.ts.map +1 -1
  25. package/dist/agent/claude/tool-calls.js +11 -2
  26. package/dist/agent/claude/tool-calls.js.map +1 -1
  27. package/dist/agent/codex/backend.d.ts +1 -1
  28. package/dist/agent/codex/backend.d.ts.map +1 -1
  29. package/dist/agent/codex/backend.js +2 -1
  30. package/dist/agent/codex/backend.js.map +1 -1
  31. package/dist/agent/codex/events.d.ts.map +1 -1
  32. package/dist/agent/codex/events.js +7 -4
  33. package/dist/agent/codex/events.js.map +1 -1
  34. package/dist/agent/codex/jinion-tools.d.ts +27 -4
  35. package/dist/agent/codex/jinion-tools.d.ts.map +1 -1
  36. package/dist/agent/codex/jinion-tools.js +18 -4
  37. package/dist/agent/codex/jinion-tools.js.map +1 -1
  38. package/dist/agent/codex/session.d.ts +3 -0
  39. package/dist/agent/codex/session.d.ts.map +1 -1
  40. package/dist/agent/codex/session.js +5 -2
  41. package/dist/agent/codex/session.js.map +1 -1
  42. package/dist/agent/demo/scenarios/pricing-card.d.ts +3 -0
  43. package/dist/agent/demo/scenarios/pricing-card.d.ts.map +1 -0
  44. package/dist/agent/demo/scenarios/pricing-card.js +43 -0
  45. package/dist/agent/demo/scenarios/pricing-card.js.map +1 -0
  46. package/dist/agent/demo/sessions.d.ts.map +1 -1
  47. package/dist/agent/demo/sessions.js +26 -1
  48. package/dist/agent/demo/sessions.js.map +1 -1
  49. package/dist/agent/review.d.ts +8 -2
  50. package/dist/agent/review.d.ts.map +1 -1
  51. package/dist/agent/review.js +27 -7
  52. package/dist/agent/review.js.map +1 -1
  53. package/dist/api/client.d.ts +212 -0
  54. package/dist/api/client.d.ts.map +1 -1
  55. package/dist/api/connection.d.ts +52 -0
  56. package/dist/api/connection.d.ts.map +1 -1
  57. package/dist/api/connection.js +2 -0
  58. package/dist/api/connection.js.map +1 -1
  59. package/dist/api/fields.d.ts +229 -1
  60. package/dist/api/fields.d.ts.map +1 -1
  61. package/dist/api/fields.js +3 -1
  62. package/dist/api/fields.js.map +1 -1
  63. package/dist/api/json-schema.d.ts +819 -181
  64. package/dist/api/json-schema.d.ts.map +1 -1
  65. package/dist/api/methods/git.js +1 -1
  66. package/dist/api/methods/git.js.map +1 -1
  67. package/dist/api/methods/sessions.d.ts.map +1 -1
  68. package/dist/api/methods/sessions.js +3 -2
  69. package/dist/api/methods/sessions.js.map +1 -1
  70. package/dist/api/methods/team.d.ts +4 -0
  71. package/dist/api/methods/team.d.ts.map +1 -0
  72. package/dist/api/methods/team.js +30 -0
  73. package/dist/api/methods/team.js.map +1 -0
  74. package/dist/api/protocol.d.ts +779 -2
  75. package/dist/api/protocol.d.ts.map +1 -1
  76. package/dist/api/protocol.js +36 -5
  77. package/dist/api/protocol.js.map +1 -1
  78. package/dist/api/schemas.d.ts +496 -0
  79. package/dist/api/schemas.d.ts.map +1 -1
  80. package/dist/api/schemas.js +6 -0
  81. package/dist/api/schemas.js.map +1 -1
  82. package/dist/commands/builtin.d.ts.map +1 -1
  83. package/dist/commands/builtin.js +3 -0
  84. package/dist/commands/builtin.js.map +1 -1
  85. package/dist/commands/team.d.ts +4 -0
  86. package/dist/commands/team.d.ts.map +1 -0
  87. package/dist/commands/team.js +11 -0
  88. package/dist/commands/team.js.map +1 -0
  89. package/dist/controllers/context.d.ts +4 -0
  90. package/dist/controllers/context.d.ts.map +1 -1
  91. package/dist/controllers/context.js +4 -0
  92. package/dist/controllers/context.js.map +1 -1
  93. package/dist/controllers/conversation.d.ts +16 -0
  94. package/dist/controllers/conversation.d.ts.map +1 -1
  95. package/dist/controllers/decision-view.d.ts +20 -0
  96. package/dist/controllers/decision-view.d.ts.map +1 -0
  97. package/dist/controllers/decision-view.js +59 -0
  98. package/dist/controllers/decision-view.js.map +1 -0
  99. package/dist/controllers/decisions.d.ts +29 -0
  100. package/dist/controllers/decisions.d.ts.map +1 -0
  101. package/dist/controllers/decisions.js +199 -0
  102. package/dist/controllers/decisions.js.map +1 -0
  103. package/dist/controllers/jinion.d.ts +17 -1
  104. package/dist/controllers/jinion.d.ts.map +1 -1
  105. package/dist/controllers/jinion.js +89 -5
  106. package/dist/controllers/jinion.js.map +1 -1
  107. package/dist/controllers/session.d.ts +21 -1
  108. package/dist/controllers/session.d.ts.map +1 -1
  109. package/dist/controllers/session.js +63 -1
  110. package/dist/controllers/session.js.map +1 -1
  111. package/dist/controllers/team.d.ts +216 -0
  112. package/dist/controllers/team.d.ts.map +1 -0
  113. package/dist/controllers/team.js +208 -0
  114. package/dist/controllers/team.js.map +1 -0
  115. package/dist/controllers/turns.d.ts +6 -0
  116. package/dist/controllers/turns.d.ts.map +1 -1
  117. package/dist/controllers/turns.js +17 -7
  118. package/dist/controllers/turns.js.map +1 -1
  119. package/dist/conversation/entries.d.ts +36 -0
  120. package/dist/conversation/entries.d.ts.map +1 -1
  121. package/dist/conversation/entries.js +26 -0
  122. package/dist/conversation/entries.js.map +1 -1
  123. package/dist/conversation/reducer.d.ts +132 -0
  124. package/dist/conversation/reducer.d.ts.map +1 -1
  125. package/dist/conversation/reducer.js +30 -1
  126. package/dist/conversation/reducer.js.map +1 -1
  127. package/dist/conversation/session.d.ts +24 -0
  128. package/dist/conversation/session.d.ts.map +1 -1
  129. package/dist/conversation/store.d.ts +13 -0
  130. package/dist/conversation/store.d.ts.map +1 -1
  131. package/dist/conversation/store.js +31 -7
  132. package/dist/conversation/store.js.map +1 -1
  133. package/dist/feedback/shared.d.ts +16 -0
  134. package/dist/feedback/shared.d.ts.map +1 -1
  135. package/dist/git/repos.d.ts.map +1 -1
  136. package/dist/git/repos.js +3 -1
  137. package/dist/git/repos.js.map +1 -1
  138. package/dist/git/staging.d.ts +2 -2
  139. package/dist/git/staging.d.ts.map +1 -1
  140. package/dist/git/staging.js +3 -3
  141. package/dist/git/staging.js.map +1 -1
  142. package/dist/git/types.d.ts +2 -0
  143. package/dist/git/types.d.ts.map +1 -1
  144. package/dist/git/types.js +2 -0
  145. package/dist/git/types.js.map +1 -1
  146. package/dist/jinion-account/account.d.ts +178 -0
  147. package/dist/jinion-account/account.d.ts.map +1 -1
  148. package/dist/jinion-account/account.js +30 -0
  149. package/dist/jinion-account/account.js.map +1 -1
  150. package/dist/jinion-account/api.d.ts +169 -0
  151. package/dist/jinion-account/api.d.ts.map +1 -1
  152. package/dist/jinion-account/api.js +39 -1
  153. package/dist/jinion-account/api.js.map +1 -1
  154. package/dist/jinion-account/user.d.ts +22 -0
  155. package/dist/jinion-account/user.d.ts.map +1 -1
  156. package/dist/jinion-account/user.js +9 -0
  157. package/dist/jinion-account/user.js.map +1 -1
  158. package/dist/map/review.d.ts +6 -4
  159. package/dist/map/review.d.ts.map +1 -1
  160. package/dist/map/review.js +21 -7
  161. package/dist/map/review.js.map +1 -1
  162. package/dist/state/jinion-account.d.ts +6 -0
  163. package/dist/state/jinion-account.d.ts.map +1 -1
  164. package/dist/state/session.d.ts +150 -0
  165. package/dist/state/session.d.ts.map +1 -1
  166. package/dist/state/session.js +2 -0
  167. package/dist/state/session.js.map +1 -1
  168. package/dist/state/team.d.ts +151 -0
  169. package/dist/state/team.d.ts.map +1 -0
  170. package/dist/state/team.js +4 -0
  171. package/dist/state/team.js.map +1 -0
  172. package/dist/team/anchoring.d.ts +9 -0
  173. package/dist/team/anchoring.d.ts.map +1 -0
  174. package/dist/team/anchoring.js +26 -0
  175. package/dist/team/anchoring.js.map +1 -0
  176. package/dist/team/config.d.ts +16 -0
  177. package/dist/team/config.d.ts.map +1 -0
  178. package/dist/team/config.js +37 -0
  179. package/dist/team/config.js.map +1 -0
  180. package/dist/team/decision.d.ts +255 -0
  181. package/dist/team/decision.d.ts.map +1 -0
  182. package/dist/team/decision.js +82 -0
  183. package/dist/team/decision.js.map +1 -0
  184. package/dist/team/decisions.d.ts +98 -0
  185. package/dist/team/decisions.d.ts.map +1 -0
  186. package/dist/team/decisions.js +166 -0
  187. package/dist/team/decisions.js.map +1 -0
  188. package/dist/team/history.d.ts +27 -0
  189. package/dist/team/history.d.ts.map +1 -0
  190. package/dist/team/history.js +49 -0
  191. package/dist/team/history.js.map +1 -0
  192. package/dist/team/prompt.d.ts +20 -0
  193. package/dist/team/prompt.d.ts.map +1 -0
  194. package/dist/team/prompt.js +44 -0
  195. package/dist/team/prompt.js.map +1 -0
  196. package/dist/team/repository.d.ts +12 -0
  197. package/dist/team/repository.d.ts.map +1 -0
  198. package/dist/team/repository.js +32 -0
  199. package/dist/team/repository.js.map +1 -0
  200. package/dist/team/secrets.d.ts +3 -0
  201. package/dist/team/secrets.d.ts.map +1 -0
  202. package/dist/team/secrets.js +18 -0
  203. package/dist/team/secrets.js.map +1 -0
  204. package/dist/team/tools.d.ts +82 -0
  205. package/dist/team/tools.d.ts.map +1 -0
  206. package/dist/team/tools.js +46 -0
  207. package/dist/team/tools.js.map +1 -0
  208. package/dist/team/types.d.ts +178 -0
  209. package/dist/team/types.d.ts.map +1 -0
  210. package/dist/team/types.js +60 -0
  211. package/dist/team/types.js.map +1 -0
  212. package/dist/team/visibility.d.ts +9 -0
  213. package/dist/team/visibility.d.ts.map +1 -0
  214. package/dist/team/visibility.js +36 -0
  215. package/dist/team/visibility.js.map +1 -0
  216. package/package.json +1 -1
  217. package/schema/api.json +3371 -503
@@ -0,0 +1,166 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { rmSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { ApiRefusal } from '../jinion-account/api.js';
5
+ import { readJson, updateJson } from '../lib/json-file.js';
6
+ import { jinionHome } from '../lib/paths.js';
7
+ const EMPTY = { cursor: '0', decisions: {}, queue: [], aliases: {} };
8
+ /**
9
+ * The project's decisions, as a copy under ~/.jinion that its sessions read without a network: never in the repository,
10
+ * kept up to date from api.jinion.co, and gone once the user loses access.
11
+ */
12
+ export class DecisionStore {
13
+ projectId;
14
+ account;
15
+ changed;
16
+ file;
17
+ constructor(projectId, account,
18
+ /** After every change to the copy, such as one a sync took in. */
19
+ changed = () => { }) {
20
+ this.projectId = projectId;
21
+ this.account = account;
22
+ this.changed = changed;
23
+ this.file = join(jinionHome(), 'team', projectId, 'decisions.json');
24
+ }
25
+ all() {
26
+ return Object.values(this.saved().decisions);
27
+ }
28
+ get(id) {
29
+ const saved = this.saved();
30
+ return saved.decisions[saved.aliases[id] ?? id];
31
+ }
32
+ /** Sends what waits, then takes in every change since the last sync. */
33
+ async sync() {
34
+ await this.flush();
35
+ for (let more = true; more;) {
36
+ const page = await this.account.decisionChanges(this.projectId, this.saved().cursor);
37
+ this.update((saved) => {
38
+ const decisions = { ...saved.decisions };
39
+ for (const change of page.changes) {
40
+ if ('deleted' in change)
41
+ delete decisions[change.id];
42
+ else
43
+ decisions[change.id] = change;
44
+ }
45
+ return { ...saved, decisions, cursor: page.cursor };
46
+ });
47
+ more = page.more;
48
+ }
49
+ }
50
+ /** Sent at once; while the API can't be reached, kept here under a local id and sent with the next sync. */
51
+ async record(draft) {
52
+ try {
53
+ const made = await this.account.recordDecision(this.projectId, draft);
54
+ this.update((saved) => ({ ...saved, decisions: { ...saved.decisions, [made.id]: made } }));
55
+ return made;
56
+ }
57
+ catch (error) {
58
+ if (!unreachable(error))
59
+ throw error;
60
+ const waiting = this.waiting(draft);
61
+ this.update((saved) => ({ ...saved, decisions: { ...saved.decisions, [waiting.id]: waiting }, queue: [...saved.queue, { kind: 'record', localId: waiting.id, draft }] }));
62
+ return waiting;
63
+ }
64
+ }
65
+ async delete(id) {
66
+ const saved = this.saved();
67
+ const known = saved.aliases[id] ?? id;
68
+ // Recorded and deleted while offline: the API never needs to hear of it.
69
+ if (saved.queue.some((write) => write.kind === 'record' && write.localId === known)) {
70
+ return this.update((current) => ({ ...current, decisions: without(current.decisions, known), queue: current.queue.filter((write) => write.kind !== 'record' || write.localId !== known) }));
71
+ }
72
+ this.update((current) => ({ ...current, decisions: without(current.decisions, known) }));
73
+ try {
74
+ await this.account.deleteDecision(this.projectId, known);
75
+ }
76
+ catch (error) {
77
+ if (!unreachable(error))
78
+ throw error;
79
+ this.update((current) => ({ ...current, queue: [...current.queue, { kind: 'delete', id: known }] }));
80
+ }
81
+ }
82
+ /** Its author's client telling which commit carries it; offline, it is anchored again at the next check. */
83
+ async anchor(id, shas, repository) {
84
+ try {
85
+ const anchored = await this.account.anchorDecision(this.projectId, id, shas, repository);
86
+ this.update((saved) => ({ ...saved, decisions: { ...saved.decisions, [anchored.id]: anchored } }));
87
+ }
88
+ catch (error) {
89
+ if (!unreachable(error))
90
+ throw error;
91
+ }
92
+ }
93
+ /** As the user lost access to the project, or signed out. */
94
+ purge() {
95
+ rmSync(join(this.file, '..'), { recursive: true, force: true });
96
+ }
97
+ /** The waiting writes in order, until the API can't be reached again; one it refuses for good is dropped. */
98
+ async flush() {
99
+ for (let write = this.saved().queue[0]; write; write = this.saved().queue[0]) {
100
+ try {
101
+ await this.send(write);
102
+ }
103
+ catch (error) {
104
+ if (unreachable(error))
105
+ return;
106
+ const refused = write;
107
+ if (refused.kind === 'record')
108
+ this.update((saved) => ({ ...saved, decisions: without(saved.decisions, refused.localId) }));
109
+ }
110
+ this.update((saved) => ({ ...saved, queue: saved.queue.slice(1) }));
111
+ }
112
+ }
113
+ async send(write) {
114
+ if (write.kind === 'delete')
115
+ return this.account.deleteDecision(this.projectId, write.id);
116
+ const made = await this.account.recordDecision(this.projectId, write.draft);
117
+ this.update((saved) => ({
118
+ ...saved,
119
+ decisions: { ...without(saved.decisions, write.localId), [made.id]: made },
120
+ aliases: { ...saved.aliases, [write.localId]: made.id },
121
+ }));
122
+ }
123
+ /** How a decision recorded offline shows until the API has it: its author's draft. */
124
+ waiting(draft) {
125
+ const user = this.account.user();
126
+ const now = new Date().toISOString();
127
+ return {
128
+ id: `local_${randomUUID()}`,
129
+ title: draft.title,
130
+ decision: draft.decision,
131
+ reason: draft.reason,
132
+ turnedDown: draft.turnedDown ?? null,
133
+ origin: draft.origin,
134
+ status: 'draft',
135
+ author: user && { id: user.id, name: user.name, email: user.email },
136
+ backend: draft.backend,
137
+ model: draft.model,
138
+ branch: draft.branch ?? null,
139
+ baseCommit: draft.baseCommit ?? null,
140
+ paths: draft.paths ?? [],
141
+ symbols: draft.symbols ?? [],
142
+ supersedes: draft.supersedes ?? null,
143
+ supersededBy: null,
144
+ anchors: [],
145
+ createdAt: now,
146
+ updatedAt: now,
147
+ version: '0',
148
+ };
149
+ }
150
+ saved() {
151
+ return readJson(this.file, EMPTY);
152
+ }
153
+ update(change) {
154
+ updateJson(this.file, EMPTY, change);
155
+ this.changed();
156
+ }
157
+ }
158
+ /** Offline, or api.jinion.co down; a refusal for what was sent is the caller's to hear. */
159
+ function unreachable(error) {
160
+ return !(error instanceof ApiRefusal) || error.status >= 500;
161
+ }
162
+ function without(decisions, id) {
163
+ const { [id]: _, ...rest } = decisions;
164
+ return rest;
165
+ }
166
+ //# sourceMappingURL=decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../src/team/decisions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /** Runs git in `folder` and answers with what it printed; rejects when git fails. */
2
+ export type Git = (folder: string, args: string[]) => Promise<string>;
3
+ export declare function runGit(folder: string, args: string[]): Promise<string>;
4
+ /** Which commits a folder has: HEAD's, and those its branch's upstream has beyond them, as of the last fetch. */
5
+ export interface Ancestry {
6
+ head: string;
7
+ /** Missing when HEAD is detached. */
8
+ branch?: string;
9
+ /** HEAD and every commit it descends from. */
10
+ inHead: ReadonlySet<string>;
11
+ upstreamOnly: ReadonlySet<string>;
12
+ }
13
+ /**
14
+ * Each folder's ancestry, read in two passes of git rather than one check per decision, and kept until git says
15
+ * something moved, so sorting the decisions again costs no git at all.
16
+ */
17
+ export declare class History {
18
+ private readonly git;
19
+ private readonly read;
20
+ constructor(git?: Git);
21
+ /** Undefined outside git, or before a first commit. */
22
+ of(folder: string): Promise<Ancestry | undefined>;
23
+ /** As HEAD, a branch or a fetch moved. */
24
+ forget(): void;
25
+ private readAncestry;
26
+ }
27
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/team/history.ts"],"names":[],"mappings":"AAKA,qFAAqF;AACrF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtE,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,mBAE1D;AAED,iHAAiH;AACjH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,qBAAa,OAAO;IAGN,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoD;IAEzE,YAA6B,GAAG,GAAE,GAAY,EAAI;IAElD,uDAAuD;IACvD,EAAE,CAAC,MAAM,EAAE,MAAM,iCAShB;IAED,0CAA0C;IAC1C,MAAM,SAEL;YAEa,YAAY;CAe3B"}
@@ -0,0 +1,49 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const run = promisify(execFile);
4
+ export async function runGit(folder, args) {
5
+ return (await run('git', args, { cwd: folder, timeout: 30_000, maxBuffer: 512 * 1024 * 1024 })).stdout;
6
+ }
7
+ /**
8
+ * Each folder's ancestry, read in two passes of git rather than one check per decision, and kept until git says
9
+ * something moved, so sorting the decisions again costs no git at all.
10
+ */
11
+ export class History {
12
+ git;
13
+ read = new Map();
14
+ constructor(git = runGit) {
15
+ this.git = git;
16
+ }
17
+ /** Undefined outside git, or before a first commit. */
18
+ of(folder) {
19
+ let ancestry = this.read.get(folder);
20
+ if (!ancestry) {
21
+ ancestry = this.readAncestry(folder);
22
+ this.read.set(folder, ancestry);
23
+ }
24
+ return ancestry;
25
+ }
26
+ /** As HEAD, a branch or a fetch moved. */
27
+ forget() {
28
+ this.read.clear();
29
+ }
30
+ async readAncestry(folder) {
31
+ try {
32
+ const [head, branch, inHead, upstreamOnly] = await Promise.all([
33
+ this.git(folder, ['rev-parse', 'HEAD']),
34
+ this.git(folder, ['branch', '--show-current']),
35
+ this.git(folder, ['rev-list', 'HEAD']),
36
+ // A branch with no upstream has nothing waiting to be pulled.
37
+ this.git(folder, ['rev-list', '@{upstream}', '^HEAD']).catch(() => ''),
38
+ ]);
39
+ return { head: head.trim(), ...(branch.trim() && { branch: branch.trim() }), inHead: shas(inHead), upstreamOnly: shas(upstreamOnly) };
40
+ }
41
+ catch {
42
+ return undefined;
43
+ }
44
+ }
45
+ }
46
+ function shas(output) {
47
+ return new Set(output.split('\n').filter(Boolean));
48
+ }
49
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/team/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAKhC,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAc,EAAE,IAAc;IACzD,OAAO,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACzG,CAAC;AAYD;;;GAGG;AACH,MAAM,OAAO,OAAO;IAGW,GAAG;IAFf,IAAI,GAAG,IAAI,GAAG,EAAyC,CAAC;IAEzE,YAA6B,GAAG,GAAQ,MAAM;mBAAjB,GAAG;IAAiB,CAAC;IAElD,uDAAuD;IACvD,EAAE,CAAC,MAAc;QACf,IAAI,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAClC,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,0CAA0C;IAC1C,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,MAAc;QACvC,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC7D,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;gBAC9C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;gBACtC,8DAA8D;gBAC9D,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;aACvE,CAAC,CAAC;YAEH,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACxI,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;CACF;AAED,SAAS,IAAI,CAAC,MAAc;IAC1B,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Decision, DecisionState } from './decision.js';
2
+ import type { DecisionRecorder } from './tools.js';
3
+ /** A decision as a session sees it. */
4
+ export type Shown = Decision & {
5
+ state: DecisionState;
6
+ };
7
+ /** More than this and the rest are found with `find_decisions`, so the index never crowds the context. */
8
+ export declare const INDEX_LIMIT = 30;
9
+ /** What, who, when and where, in a line. */
10
+ export declare function decisionLine(decision: Shown): string;
11
+ export declare function authorOf(decision: Decision): string;
12
+ /** The decisions that bind the work, nearest to it first, as the agent reads them. */
13
+ export declare function indexOf(decisions: Shown[]): string;
14
+ /** Told only where the user is in the project's team, in every mode. */
15
+ export declare function teamSection(recorder: DecisionRecorder): string;
16
+ /** Beside the next prompt after the user answered a question or approved a plan, which may have settled a decision. */
17
+ export declare const SETTLED = "In the last turn the user answered your question or approved your plan. If that settled a decision worth recording by the guidance on team decisions, record it with `origin: asked`; if it didn\u2019t, record nothing.";
18
+ /** Beside the next prompt once the decisions that bind the work changed since the agent was told them, as after a pull. */
19
+ export declare function indexChanged(index: string): string;
20
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/team/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,uCAAuC;AACvC,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAExD,0GAA0G;AAC1G,eAAO,MAAM,WAAW,KAAK,CAAC;AAE9B,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,QAAQ,EAAE,KAAK,UAI3C;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,UAE1C;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,UAMzC;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,QAAQ,EAAE,gBAAgB,UAkBrD;AAED,uHAAuH;AACvH,eAAO,MAAM,OAAO,6NACmM,CAAC;AAExN,2HAA2H;AAC3H,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,UAEzC"}
@@ -0,0 +1,44 @@
1
+ /** More than this and the rest are found with `find_decisions`, so the index never crowds the context. */
2
+ export const INDEX_LIMIT = 30;
3
+ /** What, who, when and where, in a line. */
4
+ export function decisionLine(decision) {
5
+ const by = decision.state === 'draft' ? 'yours, not in a commit yet' : `${authorOf(decision)}, ${decision.createdAt.slice(0, 10)}`;
6
+ return `- ${decision.id}: ${decision.title} (${by}${decision.branch ? `, on ${decision.branch}` : ''})`;
7
+ }
8
+ export function authorOf(decision) {
9
+ return decision.author?.name ?? decision.author?.email ?? 'A former teammate';
10
+ }
11
+ /** The decisions that bind the work, nearest to it first, as the agent reads them. */
12
+ export function indexOf(decisions) {
13
+ if (decisions.length === 0)
14
+ return 'None yet.';
15
+ const more = decisions.length > INDEX_LIMIT ? [`- …and ${decisions.length - INDEX_LIMIT} more; \`find_decisions\` finds them.`] : [];
16
+ return [...decisions.slice(0, INDEX_LIMIT).map(decisionLine), ...more].join('\n');
17
+ }
18
+ /** Told only where the user is in the project's team, in every mode. */
19
+ export function teamSection(recorder) {
20
+ return `# Team decisions
21
+ This project belongs to a team on Jinion, whose agents record the decisions that matter. Those that bind your work are the team's, carried by commits the user has: follow them. When one shapes your work, say so in your reply, naming it and who made it ("Ayşe decided on Oct 3 that …; I kept to it"), and call \`kept_to_decision\` with its id.
22
+
23
+ Decisions that bind this work, nearest to it first:
24
+ ${recorder.index()}
25
+
26
+ - Before you choose between real alternatives, look for decisions on it with \`find_decisions\`: by the paths you change, a symbol or a few words. One it lists as not in the user's code yet is a teammate's on another branch: never follow it as a rule.
27
+ - When the user asks for something a binding decision rules out, don't just do it: say which decision and why, and ask whether to keep it or replace it. Replacing it is recording a decision with \`record_decision\`, \`supersedes\` set to its id and \`origin: requested\`.
28
+ - In a plan, name the decisions it keeps to.
29
+
30
+ Record the decisions that matter with \`record_decision\`, without asking and without being asked. Each goes to the team, whose agents keep to it once a commit carries it, so a teammate's agent doesn't undo on purpose what was chosen on purpose. The user sees each one in the conversation and can delete it.
31
+
32
+ - Record a choice between real alternatives that a teammate would otherwise undo or redo: an architecture or a data shape, a library picked or turned down, a convention set, a behavior the user asked for that the code can't explain, a trade-off accepted on purpose.
33
+ - Don't record renames, obvious fixes, what the code already makes plain, or anything that matters to this conversation only.
34
+ - Write it to hold without this conversation: what was decided, why, and what was turned down and why it lost.
35
+ - When a decision above covers the same choice, pass its id as \`supersedes\` rather than recording a near copy.
36
+ - Never put secrets, keys, customer data or personal data in a decision.`;
37
+ }
38
+ /** Beside the next prompt after the user answered a question or approved a plan, which may have settled a decision. */
39
+ export const SETTLED = 'In the last turn the user answered your question or approved your plan. If that settled a decision worth recording by the guidance on team decisions, record it with `origin: asked`; if it didn’t, record nothing.';
40
+ /** Beside the next prompt once the decisions that bind the work changed since the agent was told them, as after a pull. */
41
+ export function indexChanged(index) {
42
+ return `The team's decisions that bind this work changed since you were told them. Now, nearest to the work first:\n${index}`;
43
+ }
44
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/team/prompt.ts"],"names":[],"mappings":"AAMA,0GAA0G;AAC1G,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE9B,4CAA4C;AAC5C,MAAM,UAAU,YAAY,CAAC,QAAe;IAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAEnI,OAAO,KAAK,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,KAAK,KAAK,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAkB;IACzC,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,mBAAmB,CAAC;AAChF,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,OAAO,CAAC,SAAkB;IACxC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE/C,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,SAAS,CAAC,MAAM,GAAG,WAAW,uCAAuC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAErI,OAAO,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpF,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,QAA0B;IACpD,OAAO;;;;EAIP,QAAQ,CAAC,KAAK,EAAE;;;;;;;;;;;;yEAYuD,CAAC;AAC1E,CAAC;AAED,uHAAuH;AACvH,MAAM,CAAC,MAAM,OAAO,GAClB,qNAAqN,CAAC;AAExN,2HAA2H;AAC3H,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,+GAA+G,KAAK,EAAE,CAAC;AAChI,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface RepositoryIdentity {
2
+ remoteUrl: string;
3
+ rootCommit: string;
4
+ }
5
+ /** The branch `folder` is on, missing when HEAD is detached, and HEAD's commit; undefined outside git or before a first commit. */
6
+ export declare function headOf(folder: string): Promise<{
7
+ branch?: string;
8
+ commit: string;
9
+ } | undefined>;
10
+ /** What tells the repository at `root` from any other: where it is pushed, and its first commit; undefined without either. */
11
+ export declare function repositoryIdentity(root: string): Promise<RepositoryIdentity | undefined>;
12
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/team/repository.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,mIAAmI;AACnI,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CAUrG;AAED,8HAA8H;AAC9H,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAgB9F"}
@@ -0,0 +1,32 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const run = promisify(execFile);
4
+ /** The branch `folder` is on, missing when HEAD is detached, and HEAD's commit; undefined outside git or before a first commit. */
5
+ export async function headOf(folder) {
6
+ const git = async (...args) => (await run('git', args, { cwd: folder, timeout: 5_000 })).stdout.trim();
7
+ try {
8
+ const [branch, commit] = await Promise.all([git('branch', '--show-current'), git('rev-parse', 'HEAD')]);
9
+ return { ...(branch && { branch }), commit };
10
+ }
11
+ catch {
12
+ return undefined;
13
+ }
14
+ }
15
+ /** What tells the repository at `root` from any other: where it is pushed, and its first commit; undefined without either. */
16
+ export async function repositoryIdentity(root) {
17
+ const git = async (...args) => (await run('git', args, { cwd: root, timeout: 5_000 })).stdout;
18
+ try {
19
+ const remotes = (await git('remote')).split('\n').filter(Boolean);
20
+ const remote = remotes.includes('origin') ? 'origin' : remotes[0];
21
+ if (!remote)
22
+ return undefined;
23
+ const remoteUrl = (await git('remote', 'get-url', remote)).trim();
24
+ // Histories merged in bring first commits of their own; the smallest is the same one in every clone.
25
+ const rootCommit = (await git('rev-list', '--max-parents=0', 'HEAD')).split('\n').filter(Boolean).sort()[0];
26
+ return rootCommit ? { remoteUrl, rootCommit } : undefined;
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ }
32
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/team/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAOhC,mIAAmI;AACnI,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAc;IACzC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAG,IAAc,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAEjH,IAAI,CAAC;QACH,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAExG,OAAO,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,8HAA8H;AAC9H,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY;IACnD,MAAM,GAAG,GAAG,KAAK,EAAE,GAAG,IAAc,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAExG,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAE9B,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClE,qGAAqG;QACrG,MAAM,UAAU,GAAG,CAAC,MAAM,GAAG,CAAC,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAE5G,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** What in `text` looks like a key or token, named; undefined when nothing does. */
2
+ export declare function secretIn(text: string): string | undefined;
3
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/team/secrets.ts"],"names":[],"mappings":"AAcA,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,sBAEpC"}
@@ -0,0 +1,18 @@
1
+ /** Keys and tokens as the services that issue them write them, each with what to call it when one turns up. */
2
+ const SECRETS = [
3
+ [/-----BEGIN [A-Z ]*PRIVATE KEY-----/, 'a private key'],
4
+ [/\bAKIA[0-9A-Z]{16}\b/, 'an AWS access key'],
5
+ [/\b(gh[pousr]_[A-Za-z0-9]{36,}|github_pat_[A-Za-z0-9_]{40,})\b/, 'a GitHub token'],
6
+ [/\bxox[abposr]-[A-Za-z0-9-]{10,}/, 'a Slack token'],
7
+ [/\b[sr]k_live_[A-Za-z0-9]{16,}/, 'a Stripe key'],
8
+ [/\bsk-(ant-)?[A-Za-z0-9_-]{20,}/, 'an API key'],
9
+ [/\bAIza[0-9A-Za-z_-]{35}\b/, 'a Google API key'],
10
+ [/\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/, 'a signed token'],
11
+ [/\b[a-z]+:\/\/[^\s:/@]+:[^\s@/]+@/i, 'a password in an address'],
12
+ [/\b(password|passwd|secret|api[_-]?key|access[_-]?token|private[_-]?key)\b["']?\s*[:=]\s*["']?[^\s"']{8,}/i, 'a secret'],
13
+ ];
14
+ /** What in `text` looks like a key or token, named; undefined when nothing does. */
15
+ export function secretIn(text) {
16
+ return SECRETS.find(([pattern]) => pattern.test(text))?.[1];
17
+ }
18
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/team/secrets.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAC/G,MAAM,OAAO,GAAuB;IAClC,CAAC,oCAAoC,EAAE,eAAe,CAAC;IACvD,CAAC,sBAAsB,EAAE,mBAAmB,CAAC;IAC7C,CAAC,+DAA+D,EAAE,gBAAgB,CAAC;IACnF,CAAC,iCAAiC,EAAE,eAAe,CAAC;IACpD,CAAC,+BAA+B,EAAE,cAAc,CAAC;IACjD,CAAC,gCAAgC,EAAE,YAAY,CAAC;IAChD,CAAC,2BAA2B,EAAE,kBAAkB,CAAC;IACjD,CAAC,oEAAoE,EAAE,gBAAgB,CAAC;IACxF,CAAC,mCAAmC,EAAE,0BAA0B,CAAC;IACjE,CAAC,2GAA2G,EAAE,UAAU,CAAC;CAC1H,CAAC;AAEF,oFAAoF;AACpF,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,82 @@
1
+ import { z } from 'zod';
2
+ import type { ToolCall } from '../agent/tools.js';
3
+ import type { ReviewPoint } from '../map/review.js';
4
+ /** What the agent says of a decision; the session fills in the rest itself. */
5
+ declare const recording: {
6
+ title: z.ZodString;
7
+ decision: z.ZodString;
8
+ reason: z.ZodString;
9
+ turnedDown: z.ZodOptional<z.ZodString>;
10
+ origin: z.ZodEnum<{
11
+ agent: "agent";
12
+ asked: "asked";
13
+ requested: "requested";
14
+ }>;
15
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
16
+ supersedes: z.ZodOptional<z.ZodString>;
17
+ };
18
+ declare const finding: {
19
+ path: z.ZodOptional<z.ZodString>;
20
+ symbol: z.ZodOptional<z.ZodString>;
21
+ words: z.ZodOptional<z.ZodString>;
22
+ };
23
+ export type RecordedDecision = z.infer<z.ZodObject<typeof recording>>;
24
+ export type DecisionQuery = z.infer<z.ZodObject<typeof finding>>;
25
+ /** What a turn changed, held against the decisions: those it goes against, and teammates' on other branches it meets. */
26
+ export interface DecisionReview {
27
+ points: ReviewPoint[];
28
+ /** Each a teammate's decision not in the user's code yet, told once a session. */
29
+ warnings: string[];
30
+ }
31
+ /** One conversation's part in its project's team decisions, as its session knows it: who, on what, where. */
32
+ export interface DecisionRecorder {
33
+ /** Whether the user is in the project's team now, which the tools and the guidance are offered on. */
34
+ ready(): boolean;
35
+ /** The decisions that bind the conversation's work, nearest to it first; told the agent as it is read. */
36
+ index(): string;
37
+ /** The index again once it changed since the agent was told it, as after a pull; undefined while it didn't. */
38
+ indexChange(): string | undefined;
39
+ record(decision: RecordedDecision): Promise<string>;
40
+ find(query: DecisionQuery): string;
41
+ /** The agent kept to a decision, which the conversation shows. */
42
+ kept(id: string): string;
43
+ /** A turn that changed `paths`, from the conversation's folder. */
44
+ review(paths: string[]): Promise<DecisionReview>;
45
+ }
46
+ /** A tool the agent records and keeps to the team's decisions with; each backend offers it its own way. */
47
+ export interface TeamTool<S extends z.ZodRawShape = z.ZodRawShape> {
48
+ description: string;
49
+ input: S;
50
+ run(input: z.infer<z.ZodObject<S>>): string | Promise<string>;
51
+ }
52
+ export declare function teamTools(recorder: DecisionRecorder): {
53
+ record_decision: TeamTool<{
54
+ title: z.ZodString;
55
+ decision: z.ZodString;
56
+ reason: z.ZodString;
57
+ turnedDown: z.ZodOptional<z.ZodString>;
58
+ origin: z.ZodEnum<{
59
+ agent: "agent";
60
+ asked: "asked";
61
+ requested: "requested";
62
+ }>;
63
+ paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
64
+ supersedes: z.ZodOptional<z.ZodString>;
65
+ }>;
66
+ find_decisions: TeamTool<{
67
+ path: z.ZodOptional<z.ZodString>;
68
+ symbol: z.ZodOptional<z.ZodString>;
69
+ words: z.ZodOptional<z.ZodString>;
70
+ }>;
71
+ kept_to_decision: TeamTool<{
72
+ id: z.ZodString;
73
+ }>;
74
+ };
75
+ export type TeamAction = keyof ReturnType<typeof teamTools>;
76
+ /** `find_decisions` as the conversation shows it, worded alike whichever backend called it. */
77
+ export declare function findDecisionsCall(input: unknown): ToolCall;
78
+ export declare const TEAM_ACTIONS: Set<string>;
79
+ /** Their calls show no row of their own: the decision's row says what was recorded or kept to. */
80
+ export declare const QUIET_TEAM_ACTIONS: Set<string>;
81
+ export {};
82
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/team/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,+EAA+E;AAC/E,QAAA,MAAM,SAAS;IACb,KAAK;IACL,QAAQ;IACR,MAAM;IACN,UAAU;IACV,MAAM;;;;;IAGN,KAAK;IACL,UAAU;CACX,CAAC;AAEF,QAAA,MAAM,OAAO;IACX,IAAI;IACJ,MAAM;IACN,KAAK;CACN,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC;AAEtE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC;AAEjE,yHAAyH;AACzH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,6GAA6G;AAC7G,MAAM,WAAW,gBAAgB;IAC/B,sGAAsG;IACtG,KAAK,IAAI,OAAO,CAAC;IACjB,0GAA0G;IAC1G,KAAK,IAAI,MAAM,CAAC;IAChB,+GAA+G;IAC/G,WAAW,IAAI,MAAM,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAAC;IACnC,kEAAkE;IAClE,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,mEAAmE;IACnE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAClD;AAED,2GAA2G;AAC3G,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,CAAC,CAAC;IACT,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/D;AAID,wBAAgB,SAAS,CAAC,QAAQ,EAAE,gBAAgB;IAEhD,eAAe;;;;;;;;;;;;;IAMf,cAAc;;;;;IAMd,gBAAgB;;;EAMnB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAE5D,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAI1D;AAED,eAAO,MAAM,YAAY,aAAoG,CAAC;AAE9H,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,aAAkF,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ import { DecisionOrigin } from './decision.js';
3
+ /** What the agent says of a decision; the session fills in the rest itself. */
4
+ const recording = {
5
+ title: z.string().max(200).describe('What was decided, in a few words.'),
6
+ decision: z.string().max(4000).describe('The decision itself, in a few sentences that hold without this conversation.'),
7
+ reason: z.string().max(4000).describe('Why, so a teammate who wasn’t here understands.'),
8
+ turnedDown: z.string().max(4000).optional().describe('The alternatives and why they lost.'),
9
+ origin: DecisionOrigin.describe('asked: the user answered your question or approved your plan. requested: the user asked for it. agent: your own call.'),
10
+ paths: z.array(z.string()).max(200).optional().describe('The files it concerns, from the repository’s root; the files this turn changed when left out.'),
11
+ supersedes: z.string().optional().describe('The id of a recorded decision this one replaces.'),
12
+ };
13
+ const finding = {
14
+ path: z.string().optional().describe('A file or a folder, from the repository’s root: the decisions on what is in it.'),
15
+ symbol: z.string().optional().describe('A function, type or component, by its name.'),
16
+ words: z.string().optional().describe('A few words of what it is about.'),
17
+ };
18
+ const define = (tool) => tool;
19
+ export function teamTools(recorder) {
20
+ return {
21
+ record_decision: define({
22
+ description: 'Records a decision that matters to the project’s team, for the workspace’s members, whose agents keep to it once a commit carries it. Record it as you make it, without asking; the user sees it and can delete it.',
23
+ input: recording,
24
+ run: (decision) => recorder.record(decision),
25
+ }),
26
+ find_decisions: define({
27
+ description: 'Finds the team’s decisions that bind this work, in full: by a path, a symbol or a few words. Look before you choose between real alternatives, and follow what it finds.',
28
+ input: finding,
29
+ run: (query) => recorder.find(query),
30
+ }),
31
+ kept_to_decision: define({
32
+ description: 'Says you kept to a binding decision this turn, by its id, which the user then sees. Call it once per decision, as you name it in your reply.',
33
+ input: { id: z.string().describe('The decision’s id, as `dec_…`.') },
34
+ run: ({ id }) => recorder.kept(id),
35
+ }),
36
+ };
37
+ }
38
+ /** `find_decisions` as the conversation shows it, worded alike whichever backend called it. */
39
+ export function findDecisionsCall(input) {
40
+ const { path, symbol, words } = (input ?? {});
41
+ return { name: 'other', input: { title: 'Look for team decisions', detail: [path, symbol, words].filter(Boolean).join(' · ') } };
42
+ }
43
+ export const TEAM_ACTIONS = new Set(['record_decision', 'find_decisions', 'kept_to_decision']);
44
+ /** Their calls show no row of their own: the decision's row says what was recorded or kept to. */
45
+ export const QUIET_TEAM_ACTIONS = new Set(['record_decision', 'kept_to_decision']);
46
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/team/tools.ts"],"names":[],"mappings":"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"}