@productbrain/cli 0.1.0-beta.14233 → 0.1.0-beta.14245

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 (34) hide show
  1. package/dist/__tests__/orient-bound-scope.test.d.ts +2 -0
  2. package/dist/__tests__/orient-bound-scope.test.d.ts.map +1 -0
  3. package/dist/__tests__/orient-bound-scope.test.js +173 -0
  4. package/dist/__tests__/orient-bound-scope.test.js.map +1 -0
  5. package/dist/__tests__/orient-rules.test.js +1 -0
  6. package/dist/__tests__/orient-rules.test.js.map +1 -1
  7. package/dist/__tests__/orient.test.js +1 -0
  8. package/dist/__tests__/orient.test.js.map +1 -1
  9. package/dist/__tests__/vocabulary-leak.test.js +1 -0
  10. package/dist/__tests__/vocabulary-leak.test.js.map +1 -1
  11. package/dist/commands/history.d.ts.map +1 -1
  12. package/dist/commands/history.js +4 -2
  13. package/dist/commands/history.js.map +1 -1
  14. package/dist/commands/history.test.js +14 -0
  15. package/dist/commands/history.test.js.map +1 -1
  16. package/dist/commands/orient.d.ts.map +1 -1
  17. package/dist/commands/orient.js +6 -1
  18. package/dist/commands/orient.js.map +1 -1
  19. package/dist/formatters/entry.d.ts.map +1 -1
  20. package/dist/formatters/entry.js +4 -7
  21. package/dist/formatters/entry.js.map +1 -1
  22. package/dist/formatters/orient.d.ts +2 -0
  23. package/dist/formatters/orient.d.ts.map +1 -1
  24. package/dist/formatters/orient.js +13 -4
  25. package/dist/formatters/orient.js.map +1 -1
  26. package/dist/lib/boundScope.d.ts +94 -0
  27. package/dist/lib/boundScope.d.ts.map +1 -0
  28. package/dist/lib/boundScope.js +205 -0
  29. package/dist/lib/boundScope.js.map +1 -0
  30. package/dist/lib/historyLine.d.ts +24 -0
  31. package/dist/lib/historyLine.d.ts.map +1 -0
  32. package/dist/lib/historyLine.js +12 -0
  33. package/dist/lib/historyLine.js.map +1 -0
  34. package/package.json +1 -1
@@ -0,0 +1,205 @@
1
+ /**
2
+ * TASK-1638 (WP-862; TEN-5003, DEC-2095): what a bound lane is working on, read again after every compaction. The lane's bind
3
+ * receipt (`.productbrain/.local/workspace-scope.json`, written by scripts/workspace-bind.ts) names its package and owned tasks;
4
+ * pb orient and the MCP orient print them after the served rules as one Bound scope block: the package with its stage and
5
+ * priority, each owned task with its done-when ticks, and the lane's open PRs. Outside a bound lane the block is absent.
6
+ * The receipt's one parser is here, so the lane scripts (scripts/lib/workspace-completion.ts) read it alike, and every word
7
+ * the block prints is in BOUND_SCOPE_WORDS (RULE-664). The MCP copy is generated from this file by
8
+ * scripts/generate-mcp-embedded-copies.mjs, since the isolated MCP build cannot import it.
9
+ */
10
+ import { execFile } from 'node:child_process';
11
+ import { readFileSync } from 'node:fs';
12
+ import { NO_PRIORITY, PRIORITY_LEVELS, priorityOf } from './priority.js';
13
+ export const WORKSPACE_SCOPE_BINDING_VERSION = 1;
14
+ export const WORKSPACE_SCOPE_RELATIVE_PATH = '.productbrain/.local/workspace-scope.json';
15
+ /** The id a lane may be bound to: a work package, or a legacy bet. The binding and the retirement receipt both read it. */
16
+ export const BOUND_PACKAGE_ID = /^(?:WP|BET)-\d+$/;
17
+ /** The refusal every workspace lifecycle rule throws, the receipt parser's included. */
18
+ export class WorkspaceCompletionError extends Error {
19
+ name = 'WorkspaceCompletionError';
20
+ }
21
+ function isRecord(value) {
22
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
23
+ }
24
+ function requiredString(value, label) {
25
+ if (typeof value !== 'string' || value.trim().length === 0)
26
+ throw new WorkspaceCompletionError(`Workspace scope binding has no valid ${label}.`);
27
+ return value;
28
+ }
29
+ /** TASK-673: owned ids are TASK-NNN, at least one, deduped in first-seen order. */
30
+ export function normalizeOwnedSliceIds(value) {
31
+ if (!Array.isArray(value) || value.length === 0)
32
+ throw new WorkspaceCompletionError('Workspace scope binding ownedSliceIds must be a non-empty list of TASK-NNN ids.');
33
+ const bad = value.findIndex((id) => typeof id !== 'string' || !/^TASK-\d+$/.test(id));
34
+ if (bad >= 0)
35
+ throw new WorkspaceCompletionError(`${String(value[bad])} is not a TASK-NNN id; a workspace owns tasks only (ownedSliceIds).`);
36
+ return [...new Set(value)];
37
+ }
38
+ export function parseWorkspaceScopeBinding(raw) {
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(raw);
42
+ }
43
+ catch {
44
+ throw new WorkspaceCompletionError('Workspace scope binding is malformed JSON.');
45
+ }
46
+ if (!isRecord(parsed))
47
+ throw new WorkspaceCompletionError('Workspace scope binding must be a JSON object.');
48
+ if (parsed['version'] !== WORKSPACE_SCOPE_BINDING_VERSION)
49
+ throw new WorkspaceCompletionError(`Unsupported workspace scope binding version: ${String(parsed['version'])}.`);
50
+ const scopeEntryId = requiredString(parsed['scopeEntryId'], 'scopeEntryId');
51
+ if (!BOUND_PACKAGE_ID.test(scopeEntryId))
52
+ throw new WorkspaceCompletionError(`Workspace scope binding entry must be a WP-NNN or legacy BET-NNN ID; got ${scopeEntryId}.`);
53
+ const boundAt = requiredString(parsed['boundAt'], 'boundAt');
54
+ if (Number.isNaN(Date.parse(boundAt)))
55
+ throw new WorkspaceCompletionError('Workspace scope binding has an invalid boundAt timestamp.');
56
+ return {
57
+ version: WORKSPACE_SCOPE_BINDING_VERSION, scopeEntryId, scopeName: requiredString(parsed['scopeName'], 'scopeName'),
58
+ chainWorkspaceId: requiredString(parsed['chainWorkspaceId'], 'chainWorkspaceId'), boundAt,
59
+ ...('ownedSliceIds' in parsed ? { ownedSliceIds: normalizeOwnedSliceIds(parsed['ownedSliceIds']) } : {}),
60
+ };
61
+ }
62
+ const BIND_AGAIN = 'npm run workspace:bind -- <WP-ID> [TASK-ID ...]';
63
+ export const BOUND_SCOPE_WORDS = {
64
+ heading: '## Bound scope',
65
+ /** RULE-17: ticks are counted against the task's whole done-when list. */
66
+ ticks: (ticked, total) => (total === 0 ? 'no done-when' : `${ticked} of ${total} done-when ticked`),
67
+ noStage: 'no stage',
68
+ notFound: 'not found in this workspace; check the id in the bind file, or bind again',
69
+ /** The credential reads another workspace than the lane was bound in (as assertParentIdentity refuses in the lane scripts). */
70
+ otherWorkspace: (ids) => `Read from another workspace than this lane's bind: ${ids.join(', ')}. Run \`pb profile use <name>\` for the lane's workspace, or bind again: ${BIND_AGAIN}`,
71
+ notRead: (entryId, reason) => `${entryId} not read: ${reason}`,
72
+ wholePackage: 'No tasks named at bind: the lane owns the whole package.',
73
+ pr: (branch, pr) => `Open PR on ${branch}: #${pr.number} at ${pr.headSha.slice(0, 9)} · ${pr.labels.join(', ') || 'no labels'}`,
74
+ noPr: (branch) => `No open PR on ${branch}.`,
75
+ prsNotRead: (reason) => `PRs not read: ${reason}.`,
76
+ ghMissing: 'gh is not installed; install gh, or read the PRs on GitHub',
77
+ /** gh's own first line; the auth step only when that line is about signing in. */
78
+ ghFailed: (detail) => `gh failed (${detail})${/auth|log ?in|token|credential/i.test(detail) ? '; gh auth status says whether it is signed in' : ''}`,
79
+ noBranch: 'this worktree is on no branch; check out the lane branch',
80
+ fileError: (message) => `The bind file could not be read. ${WORKSPACE_SCOPE_RELATIVE_PATH}: ${message} Fix it, or remove it and bind again: ${BIND_AGAIN}`,
81
+ };
82
+ /** git answers in milliseconds; gh asks GitHub, so it gets longer, and a slow answer becomes a "PRs not read" line. */
83
+ const TIMEOUT_MS = { git: 3_000, gh: 8_000 };
84
+ /** The file, git and gh reads on this machine; pb orient hands in kernelCall for the Chain read, the MCP orient kernelQuery. */
85
+ export function nodeBoundScopeIo(cwd, readEntries) {
86
+ const run = (command, args, dir) => new Promise((resolve) => {
87
+ execFile(command, args, { cwd: dir, timeout: TIMEOUT_MS[command], encoding: 'utf8', windowsHide: true }, (error, stdout, stderr) => {
88
+ if (!error)
89
+ return resolve({ ok: true, stdout });
90
+ const detail = (stderr.trim().split('\n')[0] || (error.killed ? 'no answer in time' : error.message)).trim();
91
+ resolve({ ok: false, detail, ...(error.code === 'ENOENT' ? { missing: true } : {}) });
92
+ });
93
+ });
94
+ const readText = (path) => {
95
+ try {
96
+ return readFileSync(path, 'utf8');
97
+ }
98
+ catch (error) {
99
+ if (error.code === 'ENOENT')
100
+ return null;
101
+ throw error;
102
+ }
103
+ };
104
+ return { cwd, readText, run, readEntries };
105
+ }
106
+ const messageOf = (error) => (error instanceof Error ? error.message : String(error));
107
+ function rowOf(entryId, answer, isTask, workspaceId) {
108
+ const entry = answer?.entry;
109
+ if (!isRecord(entry))
110
+ return { entryId, notRead: BOUND_SCOPE_WORDS.notFound };
111
+ if (entry['workspaceId'] !== workspaceId)
112
+ return { entryId, otherWorkspace: true }; // never print another workspace's names as this lane's
113
+ const data = isRecord(entry['data']) ? entry['data'] : {};
114
+ const items = Array.isArray(data['doneWhen']) ? data['doneWhen'] : [];
115
+ return {
116
+ entryId,
117
+ ...(typeof entry['name'] === 'string' ? { name: entry['name'] } : {}),
118
+ ...(typeof entry['workflowStatus'] === 'string' ? { workflowStatus: entry['workflowStatus'] } : {}),
119
+ ...(isTask ? { doneWhen: { ticked: items.filter((item) => isRecord(item) && item['done'] === true).length, total: items.length } } : { priority: data['priority'] }),
120
+ };
121
+ }
122
+ async function readRows(io, ids, workspaceId) {
123
+ try {
124
+ const chunks = Array.from({ length: Math.ceil(ids.length / 20) }, (_, i) => ids.slice(i * 20, (i + 1) * 20));
125
+ const answers = (await Promise.all(chunks.map((chunk) => io.readEntries(chunk)))).flat();
126
+ return ids.map((id, i) => rowOf(id, answers[i], i > 0, workspaceId));
127
+ }
128
+ catch (error) {
129
+ return ids.map((entryId) => ({ entryId, notRead: messageOf(error) }));
130
+ }
131
+ }
132
+ async function readPrs(io, root, branch) {
133
+ if (!branch)
134
+ return { prsNotRead: BOUND_SCOPE_WORDS.noBranch };
135
+ const result = await io.run('gh', ['pr', 'list', '--head', branch, '--state', 'open', '--json', 'number,headRefOid,labels'], root);
136
+ if (!result.ok)
137
+ return { prsNotRead: result.missing ? BOUND_SCOPE_WORDS.ghMissing : BOUND_SCOPE_WORDS.ghFailed(result.detail) };
138
+ try {
139
+ const parsed = JSON.parse(result.stdout);
140
+ if (!Array.isArray(parsed))
141
+ throw new Error('not a list');
142
+ return {
143
+ prs: parsed.filter(isRecord).map((pr) => ({
144
+ number: Number(pr['number']),
145
+ headSha: typeof pr['headRefOid'] === 'string' ? pr['headRefOid'] : '',
146
+ labels: (Array.isArray(pr['labels']) ? pr['labels'] : []).flatMap((label) => (isRecord(label) && typeof label['name'] === 'string' ? [label['name']] : [])),
147
+ })),
148
+ };
149
+ }
150
+ catch (error) {
151
+ return { prsNotRead: BOUND_SCOPE_WORDS.ghFailed(`its answer was not a PR list: ${messageOf(error)}`) };
152
+ }
153
+ }
154
+ /** The lane the working directory sits in: null in no git worktree or one with no bind file. Never throws; a failed read is a line. */
155
+ export async function readBoundScope(io) {
156
+ const top = await io.run('git', ['rev-parse', '--show-toplevel', '--abbrev-ref', 'HEAD'], io.cwd);
157
+ if (!top.ok)
158
+ return null;
159
+ const [root = '', head = ''] = top.stdout.trim().split('\n').map((line) => line.trim());
160
+ let binding;
161
+ try {
162
+ const raw = root ? io.readText(`${root}/${WORKSPACE_SCOPE_RELATIVE_PATH}`) : null;
163
+ if (raw === null)
164
+ return null;
165
+ binding = parseWorkspaceScopeBinding(raw);
166
+ }
167
+ catch (error) {
168
+ return { fileError: messageOf(error) };
169
+ }
170
+ const branch = head && head !== 'HEAD' ? head : null;
171
+ const [rows, prs] = await Promise.all([readRows(io, [binding.scopeEntryId, ...(binding.ownedSliceIds ?? [])], binding.chainWorkspaceId), readPrs(io, root, branch)]);
172
+ return { scopeEntryId: binding.scopeEntryId, rows, ownsWholePackage: !binding.ownedSliceIds, branch, ...prs };
173
+ }
174
+ function rowLine(row, isTask) {
175
+ if (row.notRead)
176
+ return BOUND_SCOPE_WORDS.notRead(row.entryId, row.notRead);
177
+ const token = priorityOf(row.priority);
178
+ const tail = isTask ? BOUND_SCOPE_WORDS.ticks(row.doneWhen?.ticked ?? 0, row.doneWhen?.total ?? 0) : token ? PRIORITY_LEVELS[token].word : NO_PRIORITY.word;
179
+ return `${row.entryId}${row.name ? ` — ${row.name}` : ''} · ${row.workflowStatus ?? BOUND_SCOPE_WORDS.noStage} · ${tail}`;
180
+ }
181
+ /** The block's lines, heading first, items indented as orient's other lists; no trailing blank line. */
182
+ export function boundScopeLines(view) {
183
+ const lines = [BOUND_SCOPE_WORDS.heading, ''];
184
+ const item = (line) => lines.push(` • ${line}`);
185
+ if ('fileError' in view)
186
+ item(BOUND_SCOPE_WORDS.fileError(view.fileError));
187
+ else {
188
+ view.rows.forEach((row, i) => { if (!row.otherWorkspace)
189
+ item(rowLine(row, i > 0)); });
190
+ const elsewhere = view.rows.filter((row) => row.otherWorkspace).map((row) => row.entryId);
191
+ if (elsewhere.length > 0)
192
+ item(BOUND_SCOPE_WORDS.otherWorkspace(elsewhere));
193
+ if (view.ownsWholePackage)
194
+ item(BOUND_SCOPE_WORDS.wholePackage);
195
+ if (view.prsNotRead !== undefined)
196
+ item(BOUND_SCOPE_WORDS.prsNotRead(view.prsNotRead));
197
+ else if (view.branch && view.prs?.length)
198
+ for (const pr of view.prs)
199
+ item(BOUND_SCOPE_WORDS.pr(view.branch, pr));
200
+ else if (view.branch)
201
+ item(BOUND_SCOPE_WORDS.noPr(view.branch));
202
+ }
203
+ return lines;
204
+ }
205
+ //# sourceMappingURL=boundScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundScope.js","sourceRoot":"","sources":["../../src/lib/boundScope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * TASK-1637 (DEC-2633 part 6, TEN-6258; RULE-664): the one line a history event prints as, in pb get, the MCP get and
3
+ * the MCP history action: date, event, who acted and as what role, the note (a change, override or resolve reason) and
4
+ * the kernel's legacy qualifier. A reason given is shown wherever the entry is read, so no door drops the note.
5
+ * One file, no imports: the CLI and the MCP server carry generated copies (scripts/generate-mcp-embedded-copies.mjs).
6
+ * Each door passes its own single-line sanitizer (sanitizeSingleLineField), so a newline in a name or a note never
7
+ * forges a history row; each door adds its own prefix (two spaces in the terminal, a list dash in Markdown).
8
+ */
9
+ /** A history row as the gateway serves it (convex/agentKnowledge/entries.ts getEntry, listEntryHistory). */
10
+ export type HistoryLineEvent = {
11
+ timestamp: number;
12
+ event: string;
13
+ /** TASK-694 (DEC-1983): the kernel's name for who acted. */
14
+ displayAuthor: string;
15
+ /** TASK-915 (DEC-1973): the kernel's words for the role the write was made as. */
16
+ actingAs?: string;
17
+ /** The reason written with the change (DEC-2633 part 6). */
18
+ note?: string;
19
+ /** WP-D (attestation spec §7.2): the qualifier beside a legacy 'verified' row. */
20
+ legacyQualifier?: string;
21
+ };
22
+ /** The line for one event; the date reads YYYY-MM-DD (UTC), as the rests-on lines do. */
23
+ export declare function historyLine(h: HistoryLineEvent, clean: (text: string) => string): string;
24
+ //# sourceMappingURL=historyLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historyLine.d.ts","sourceRoot":"","sources":["../../src/lib/historyLine.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,4GAA4G;AAC5G,MAAM,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAMxF"}
@@ -0,0 +1,12 @@
1
+ // GENERATED by scripts/generate-mcp-embedded-copies.mjs from kernel/entries/historyLine.ts.
2
+ // DO NOT EDIT. Run `npm run mcp:embedded-copies` to regenerate.
3
+ // Local runtime copy for the isolated connector build.
4
+ /** The line for one event; the date reads YYYY-MM-DD (UTC), as the rests-on lines do. */
5
+ export function historyLine(h, clean) {
6
+ const date = new Date(h.timestamp).toISOString().split('T')[0];
7
+ const who = h.actingAs ? `${clean(h.displayAuthor)}, ${clean(h.actingAs)}` : clean(h.displayAuthor);
8
+ const note = h.note ? ` — ${clean(h.note)}` : '';
9
+ const qualifier = h.legacyQualifier ? ` [${clean(h.legacyQualifier)}]` : '';
10
+ return `${date}: ${clean(h.event)} (${who})${note}${qualifier}`;
11
+ }
12
+ //# sourceMappingURL=historyLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historyLine.js","sourceRoot":"","sources":["../../src/lib/historyLine.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,gEAAgE;AAChE,uDAAuD;AAyBvD,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAC,CAAmB,EAAE,KAA+B;IAC/E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IACpG,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,IAAI,GAAG,SAAS,EAAE,CAAC;AACjE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@productbrain/cli",
3
- "version": "0.1.0-beta.14233",
3
+ "version": "0.1.0-beta.14245",
4
4
  "description": "Product Brain — Chain knowledge and write-back CLI",
5
5
  "type": "module",
6
6
  "bin": {