felenova-backlog 0.1.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 +58 -0
- package/bin/backlog.js +2 -0
- package/dist/_core/criteria.d.ts +13 -0
- package/dist/_core/criteria.js +44 -0
- package/dist/_core/criteria.js.map +1 -0
- package/dist/_core/errors.d.ts +53 -0
- package/dist/_core/errors.js +91 -0
- package/dist/_core/errors.js.map +1 -0
- package/dist/_core/index.d.ts +24 -0
- package/dist/_core/index.js +27 -0
- package/dist/_core/index.js.map +1 -0
- package/dist/_core/loop.d.ts +73 -0
- package/dist/_core/loop.js +46 -0
- package/dist/_core/loop.js.map +1 -0
- package/dist/_core/markdown/items.d.ts +35 -0
- package/dist/_core/markdown/items.js +256 -0
- package/dist/_core/markdown/items.js.map +1 -0
- package/dist/_core/markdown/matrix.d.ts +20 -0
- package/dist/_core/markdown/matrix.js +147 -0
- package/dist/_core/markdown/matrix.js.map +1 -0
- package/dist/_core/markdown/track.d.ts +71 -0
- package/dist/_core/markdown/track.js +79 -0
- package/dist/_core/markdown/track.js.map +1 -0
- package/dist/_core/matrix-status.d.ts +9 -0
- package/dist/_core/matrix-status.js +31 -0
- package/dist/_core/matrix-status.js.map +1 -0
- package/dist/_core/matrix.d.ts +46 -0
- package/dist/_core/matrix.js +0 -0
- package/dist/_core/matrix.js.map +1 -0
- package/dist/_core/permissions.d.ts +14 -0
- package/dist/_core/permissions.js +87 -0
- package/dist/_core/permissions.js.map +1 -0
- package/dist/_core/promote.d.ts +20 -0
- package/dist/_core/promote.js +47 -0
- package/dist/_core/promote.js.map +1 -0
- package/dist/_core/ready.d.ts +8 -0
- package/dist/_core/ready.js +22 -0
- package/dist/_core/ready.js.map +1 -0
- package/dist/_core/review.d.ts +49 -0
- package/dist/_core/review.js +137 -0
- package/dist/_core/review.js.map +1 -0
- package/dist/_core/schema.d.ts +636 -0
- package/dist/_core/schema.js +304 -0
- package/dist/_core/schema.js.map +1 -0
- package/dist/_core/ship.d.ts +23 -0
- package/dist/_core/ship.js +31 -0
- package/dist/_core/ship.js.map +1 -0
- package/dist/_core/spec-diff.d.ts +19 -0
- package/dist/_core/spec-diff.js +25 -0
- package/dist/_core/spec-diff.js.map +1 -0
- package/dist/_core/status.d.ts +7 -0
- package/dist/_core/status.js +25 -0
- package/dist/_core/status.js.map +1 -0
- package/dist/_core/util/deep-equal.d.ts +8 -0
- package/dist/_core/util/deep-equal.js +31 -0
- package/dist/_core/util/deep-equal.js.map +1 -0
- package/dist/api.d.ts +46 -0
- package/dist/api.js +104 -0
- package/dist/api.js.map +1 -0
- package/dist/cache.d.ts +53 -0
- package/dist/cache.js +114 -0
- package/dist/cache.js.map +1 -0
- package/dist/commands/common.d.ts +59 -0
- package/dist/commands/common.js +94 -0
- package/dist/commands/common.js.map +1 -0
- package/dist/commands/export.d.ts +20 -0
- package/dist/commands/export.js +56 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/matrix.d.ts +16 -0
- package/dist/commands/matrix.js +48 -0
- package/dist/commands/matrix.js.map +1 -0
- package/dist/commands/next.d.ts +14 -0
- package/dist/commands/next.js +30 -0
- package/dist/commands/next.js.map +1 -0
- package/dist/commands/promote.d.ts +15 -0
- package/dist/commands/promote.js +172 -0
- package/dist/commands/promote.js.map +1 -0
- package/dist/commands/report.d.ts +18 -0
- package/dist/commands/report.js +45 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/ship.d.ts +15 -0
- package/dist/commands/ship.js +231 -0
- package/dist/commands/ship.js.map +1 -0
- package/dist/commands/status.d.ts +13 -0
- package/dist/commands/status.js +141 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +17 -0
- package/dist/commands/sync.js +90 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/conductor/registry.d.ts +45 -0
- package/dist/conductor/registry.js +164 -0
- package/dist/conductor/registry.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.js +137 -0
- package/dist/config.js.map +1 -0
- package/dist/doctor.d.ts +28 -0
- package/dist/doctor.js +377 -0
- package/dist/doctor.js.map +1 -0
- package/dist/errors.d.ts +23 -0
- package/dist/errors.js +114 -0
- package/dist/errors.js.map +1 -0
- package/dist/export.d.ts +1 -0
- package/dist/export.js +9 -0
- package/dist/export.js.map +1 -0
- package/dist/import.d.ts +3 -0
- package/dist/import.js +89 -0
- package/dist/import.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +183 -0
- package/dist/index.js.map +1 -0
- package/dist/init/auth.d.ts +85 -0
- package/dist/init/auth.js +194 -0
- package/dist/init/auth.js.map +1 -0
- package/dist/init/claudemd.d.ts +16 -0
- package/dist/init/claudemd.js +62 -0
- package/dist/init/claudemd.js.map +1 -0
- package/dist/init/index.d.ts +47 -0
- package/dist/init/index.js +159 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/mcp.d.ts +18 -0
- package/dist/init/mcp.js +97 -0
- package/dist/init/mcp.js.map +1 -0
- package/dist/init/plugin.d.ts +60 -0
- package/dist/init/plugin.js +120 -0
- package/dist/init/plugin.js.map +1 -0
- package/dist/init/scaffold.d.ts +19 -0
- package/dist/init/scaffold.js +46 -0
- package/dist/init/scaffold.js.map +1 -0
- package/dist/init/templates.d.ts +48 -0
- package/dist/init/templates.js +147 -0
- package/dist/init/templates.js.map +1 -0
- package/dist/plugin/.claude-plugin/plugin.json +11 -0
- package/dist/plugin/README.md +117 -0
- package/dist/plugin/commands/next.md +28 -0
- package/dist/plugin/commands/promote.md +30 -0
- package/dist/plugin/commands/report.md +26 -0
- package/dist/plugin/commands/ship.md +30 -0
- package/dist/plugin/skills/backlog-management/SKILL.md +63 -0
- package/dist/plugin/skills/backlog-query/SKILL.md +57 -0
- package/dist/plugin/skills/feature-kickoff/SKILL.md +112 -0
- package/dist/snapshot.d.ts +24 -0
- package/dist/snapshot.js +2 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/token.d.ts +29 -0
- package/dist/token.js +99 -0
- package/dist/token.js.map +1 -0
- package/package.json +52 -0
package/dist/errors.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/** Every code with a row, in the order the table below reads. */
|
|
2
|
+
export const ERROR_CODES = [
|
|
3
|
+
'unreachable',
|
|
4
|
+
'forbidden',
|
|
5
|
+
'not_found',
|
|
6
|
+
'locked',
|
|
7
|
+
'not_locked',
|
|
8
|
+
'invalid_transition',
|
|
9
|
+
'reason_required',
|
|
10
|
+
'invalid_request',
|
|
11
|
+
'conflict',
|
|
12
|
+
'superseded',
|
|
13
|
+
'internal',
|
|
14
|
+
'no_session',
|
|
15
|
+
'token_required',
|
|
16
|
+
'token_unknown',
|
|
17
|
+
'token_revoked',
|
|
18
|
+
'token_expired',
|
|
19
|
+
'no_member',
|
|
20
|
+
'rate_limited',
|
|
21
|
+
'read_only_token',
|
|
22
|
+
'session_required',
|
|
23
|
+
];
|
|
24
|
+
const MINT = 'mint a new one in the web UI (/me → "Mint a token") and run: backlog init';
|
|
25
|
+
function service(err) {
|
|
26
|
+
return err.message.trim();
|
|
27
|
+
}
|
|
28
|
+
function withSuffix(err, fallback, suffix) {
|
|
29
|
+
const head = service(err) || fallback;
|
|
30
|
+
return `${head} — ${suffix}`;
|
|
31
|
+
}
|
|
32
|
+
function where(ctx) {
|
|
33
|
+
return ctx.url ?? 'the backlog service';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* `not_found` is the interesting row. The service answers `not_found` for a project the
|
|
37
|
+
* caller has no role on, deliberately — a project's existence is privileged
|
|
38
|
+
* (`docs/service/access-control.md`). So when the refusal is about the *configured* project
|
|
39
|
+
* rather than an item or a track inside it, the CLI says what actually happened.
|
|
40
|
+
*/
|
|
41
|
+
function isProjectNotFound(err, ctx) {
|
|
42
|
+
const message = err.message.toLowerCase();
|
|
43
|
+
if (/\bno (item|track|decision|suggestion|row|evidence|token|member)\b/.test(message)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if (ctx.project && message.includes(ctx.project.toLowerCase()))
|
|
47
|
+
return true;
|
|
48
|
+
if (/\bproject\b/.test(message))
|
|
49
|
+
return true;
|
|
50
|
+
// No message at all: with a configured project, membership is the likeliest cause and the
|
|
51
|
+
// only one the reader can act on.
|
|
52
|
+
return message === '' && Boolean(ctx.project);
|
|
53
|
+
}
|
|
54
|
+
/** The code → sentence table. Exactly one line, always. */
|
|
55
|
+
export function explain(err, ctx = {}) {
|
|
56
|
+
const project = ctx.project;
|
|
57
|
+
switch (err.code) {
|
|
58
|
+
case 'unreachable':
|
|
59
|
+
return `cannot reach ${service(err) || where(ctx)} — check the network, or run \`backlog status\` for the cached view`;
|
|
60
|
+
case 'forbidden':
|
|
61
|
+
return (service(err) ||
|
|
62
|
+
`your role${project ? ` on ${project}` : ''} does not allow this — ask the Owner or a Product role to do it, or to widen your role`);
|
|
63
|
+
case 'not_found':
|
|
64
|
+
if (isProjectNotFound(err, ctx) && project) {
|
|
65
|
+
return `you are not a member of ${project} — ask the Owner for a role on it`;
|
|
66
|
+
}
|
|
67
|
+
return service(err) || `no such ${ctx.ref ? `ref ${ctx.ref}` : 'item, track or project'}`;
|
|
68
|
+
case 'locked':
|
|
69
|
+
return withSuffix(err, 'that item is locked', 'criteria are locked; suggest a change instead (`suggest_change` over MCP, or the web UI)');
|
|
70
|
+
case 'not_locked':
|
|
71
|
+
return withSuffix(err, 'the criteria are not locked yet', 'lock the criteria first (web UI, or `lock_criteria` over MCP)');
|
|
72
|
+
case 'invalid_transition':
|
|
73
|
+
return service(err) || 'the state machine refused that move — read the current state first';
|
|
74
|
+
case 'reason_required':
|
|
75
|
+
return withSuffix(err, 'this call needs a written reason', 'pass a reason');
|
|
76
|
+
case 'invalid_request':
|
|
77
|
+
return service(err) || 'the request was malformed — check the arguments and try again';
|
|
78
|
+
case 'conflict':
|
|
79
|
+
return (service(err) ||
|
|
80
|
+
'a state precondition failed — re-read the item or track and act on what it says now');
|
|
81
|
+
case 'superseded':
|
|
82
|
+
return withSuffix(err, 'a newer revision exists', 're-read the item and file it again against the current version');
|
|
83
|
+
case 'internal':
|
|
84
|
+
return `the service failed on this request — try again; if it repeats, tell the Owner (${where(ctx)})`;
|
|
85
|
+
case 'no_session':
|
|
86
|
+
return `no credential reached the service — set BACKLOG_TOKEN or run: backlog init (your token lives at ~/.config/backlog/token)`;
|
|
87
|
+
case 'token_required':
|
|
88
|
+
return `this needs a personal access token, not a browser session — ${MINT}`;
|
|
89
|
+
case 'token_unknown':
|
|
90
|
+
return `the service does not recognise that token — ${MINT}`;
|
|
91
|
+
case 'token_revoked':
|
|
92
|
+
return `that token has been revoked — ${MINT}`;
|
|
93
|
+
case 'token_expired':
|
|
94
|
+
return `that token has expired — ${MINT}`;
|
|
95
|
+
case 'no_member':
|
|
96
|
+
return 'the service has no org membership for you — ask the Owner to add you, then run: backlog doctor';
|
|
97
|
+
case 'rate_limited':
|
|
98
|
+
return 'too many requests for this token (120 per minute) — wait a minute and run the command again';
|
|
99
|
+
case 'read_only_token':
|
|
100
|
+
return 'that token is read-only and this command writes — mint a writable PAT in the web UI (/me)';
|
|
101
|
+
case 'session_required':
|
|
102
|
+
return withSuffix(err, 'this can only be done from a browser session', 'sign in to the web UI and do it there');
|
|
103
|
+
default:
|
|
104
|
+
// An unknown code still renders as a sentence: the service's own message if it sent
|
|
105
|
+
// one, and otherwise something the reader can report.
|
|
106
|
+
return (service(err) ||
|
|
107
|
+
`the service refused this request (${err.code}) — run \`backlog doctor\`, and tell the Owner if it repeats`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** The plan's name for `explain`. */
|
|
111
|
+
export function renderError(err, ctx = {}) {
|
|
112
|
+
return explain(err, ctx);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/export.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function exportFromSnapshotFile(snapshotPath: string, outDir: string): Promise<string[]>;
|
package/dist/export.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { exportProject } from './import.js';
|
|
3
|
+
export async function exportFromSnapshotFile(snapshotPath, outDir) {
|
|
4
|
+
const snap = JSON.parse(await readFile(snapshotPath, 'utf8'));
|
|
5
|
+
if (snap.version !== 1)
|
|
6
|
+
throw new Error(`unsupported snapshot version ${String(snap.version)}`);
|
|
7
|
+
return exportProject(snap, outDir);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,YAAoB,EACpB,MAAc;IAEd,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAoB,CAAC;IACjF,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChG,OAAO,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC"}
|
package/dist/import.d.ts
ADDED
package/dist/import.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { ItemParseError, parseItem, parseMatrix, serializeItem, serializeMatrix, Track, } from './_core/index.js';
|
|
5
|
+
const DOC_NAMES = ['README.md', 'decisions-owed.md', '_schema.md'];
|
|
6
|
+
export async function importProject(root, project) {
|
|
7
|
+
const itemsDir = join(root, 'docs/backlog/items');
|
|
8
|
+
const warnings = [];
|
|
9
|
+
const problems = [];
|
|
10
|
+
const items = [];
|
|
11
|
+
for (const f of (await readdir(itemsDir)).filter((f) => f.endsWith('.md')).sort()) {
|
|
12
|
+
const rel = `docs/backlog/items/${f}`;
|
|
13
|
+
try {
|
|
14
|
+
items.push(parseItem(await readFile(join(root, rel), 'utf8'), rel));
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
if (e instanceof ItemParseError)
|
|
18
|
+
problems.push(e.message);
|
|
19
|
+
else
|
|
20
|
+
throw e;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (problems.length) {
|
|
24
|
+
throw new Error(`import aborted — ${problems.length} item(s) failed to parse:\n${problems.join('\n')}`);
|
|
25
|
+
}
|
|
26
|
+
const docs = {};
|
|
27
|
+
for (const name of DOC_NAMES) {
|
|
28
|
+
const rel = `docs/backlog/${name}`;
|
|
29
|
+
docs[name] = existsSync(join(root, rel))
|
|
30
|
+
? { path: rel, raw: await readFile(join(root, rel), 'utf8') }
|
|
31
|
+
: null;
|
|
32
|
+
}
|
|
33
|
+
const tracks = [];
|
|
34
|
+
const matrices = [];
|
|
35
|
+
const tracksDir = join(root, 'conductor/tracks');
|
|
36
|
+
if (existsSync(tracksDir)) {
|
|
37
|
+
for (const slug of (await readdir(tracksDir)).sort()) {
|
|
38
|
+
const metaRel = `conductor/tracks/${slug}/metadata.json`;
|
|
39
|
+
if (!existsSync(join(root, metaRel)))
|
|
40
|
+
continue;
|
|
41
|
+
const raw = await readFile(join(root, metaRel), 'utf8');
|
|
42
|
+
const meta = JSON.parse(raw);
|
|
43
|
+
const ids = Array.isArray(meta.backlog_ids) ? meta.backlog_ids : [];
|
|
44
|
+
const qaDoc = typeof meta.qa_doc === 'string' ? meta.qa_doc : null;
|
|
45
|
+
if (ids.length === 0 && !qaDoc)
|
|
46
|
+
continue;
|
|
47
|
+
const track = Track.parse({
|
|
48
|
+
slug: String(meta.track_id ?? slug),
|
|
49
|
+
type: String(meta.type ?? 'feature'),
|
|
50
|
+
backlog_ids: ids,
|
|
51
|
+
follow_up_backlog: Array.isArray(meta.follow_up_backlog) ? meta.follow_up_backlog : [],
|
|
52
|
+
qa_doc: qaDoc,
|
|
53
|
+
qa_enforcement: meta.qa_enforcement === 'strict' ? 'strict' : 'permissive',
|
|
54
|
+
});
|
|
55
|
+
tracks.push({ track, metadataPath: metaRel, raw });
|
|
56
|
+
if (qaDoc) {
|
|
57
|
+
if (!existsSync(join(root, qaDoc))) {
|
|
58
|
+
warnings.push(`${metaRel}: qa_doc ${qaDoc} does not exist — skipped`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const doc = parseMatrix(await readFile(join(root, qaDoc), 'utf8'), qaDoc);
|
|
62
|
+
warnings.push(...doc.warnings);
|
|
63
|
+
matrices.push({ doc, rows: doc.rows });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { version: 1, project, root, items, tracks, matrices, docs, warnings };
|
|
68
|
+
}
|
|
69
|
+
export async function exportProject(snapshot, outDir) {
|
|
70
|
+
const written = [];
|
|
71
|
+
const put = async (rel, text) => {
|
|
72
|
+
await mkdir(dirname(join(outDir, rel)), { recursive: true });
|
|
73
|
+
await writeFile(join(outDir, rel), text, 'utf8');
|
|
74
|
+
written.push(rel);
|
|
75
|
+
};
|
|
76
|
+
for (const { item, source } of snapshot.items)
|
|
77
|
+
await put(source.path, serializeItem(item, source));
|
|
78
|
+
for (const name of DOC_NAMES) {
|
|
79
|
+
const d = snapshot.docs[name];
|
|
80
|
+
if (d)
|
|
81
|
+
await put(d.path, d.raw);
|
|
82
|
+
}
|
|
83
|
+
for (const { doc, rows } of snapshot.matrices)
|
|
84
|
+
await put(doc.path, serializeMatrix(doc, rows));
|
|
85
|
+
for (const t of snapshot.tracks)
|
|
86
|
+
await put(t.metadataPath, t.raw);
|
|
87
|
+
return written;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,SAAS,EACT,WAAW,EACX,aAAa,EACb,eAAe,EACf,KAAK,GACN,MAAM,wBAAwB,CAAC;AAGhC,MAAM,SAAS,GAAG,CAAC,WAAW,EAAE,mBAAmB,EAAE,YAAY,CAAU,CAAC;AAE5E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,KAAK,GAA6B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAClF,MAAM,GAAG,GAAG,sBAAsB,CAAC,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,cAAc;gBAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;;gBACrD,MAAM,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,oBAAoB,QAAQ,CAAC,MAAM,8BAA8B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACvF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,EAA6B,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,gBAAgB,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACtC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE;YAC7D,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAgC,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IACjD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,oBAAoB,IAAI,gBAAgB,CAAC;YACzD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAAE,SAAS;YAC/C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;YACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;YACxD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,WAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;YACnE,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK;gBAAE,SAAS;YACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;gBACxB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;gBACnC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;gBACpC,WAAW,EAAE,GAAG;gBAChB,iBAAiB,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;gBACtF,MAAM,EAAE,KAAK;gBACb,cAAc,EAAE,IAAI,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY;aAC3E,CAAC,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YACnD,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;oBACnC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,YAAY,KAAK,2BAA2B,CAAC,CAAC;oBACtE,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC1E,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAyB,EAAE,MAAc;IAC3E,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,KAAK,EAAE,GAAW,EAAE,IAAY,EAAE,EAAE;QAC9C,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC;IACF,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,QAAQ,CAAC,KAAK;QAC3C,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC;YAAE,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,QAAQ,CAAC,QAAQ;QAAE,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/F,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM;QAAE,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { CORE_VERSION } from './_core/index.js';
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { runExport } from './commands/export.js';
|
|
6
|
+
import { runMatrixInit } from './commands/matrix.js';
|
|
7
|
+
import { runNext } from './commands/next.js';
|
|
8
|
+
import { runPromote } from './commands/promote.js';
|
|
9
|
+
import { runReport } from './commands/report.js';
|
|
10
|
+
import { runShip } from './commands/ship.js';
|
|
11
|
+
import { runStatus } from './commands/status.js';
|
|
12
|
+
import { runSync } from './commands/sync.js';
|
|
13
|
+
import { ConfigError } from './config.js';
|
|
14
|
+
import { runDoctorRemote } from './doctor.js';
|
|
15
|
+
import { importProject } from './import.js';
|
|
16
|
+
import { InitError, runInit } from './init/index.js';
|
|
17
|
+
import { MCP_SERVER_KEY } from './init/templates.js';
|
|
18
|
+
import { TokenError } from './token.js';
|
|
19
|
+
const program = new Command('backlog')
|
|
20
|
+
.description('Felenova backlog — execution plugin CLI')
|
|
21
|
+
.version(CORE_VERSION);
|
|
22
|
+
/** Every command is a pure function of this; `process` is read in exactly one place. */
|
|
23
|
+
function io() {
|
|
24
|
+
return { cwd: process.cwd(), home: homedir(), env: process.env };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One printer for every command: the lines on success, the single refusal sentence on stderr,
|
|
28
|
+
* and the exit code from `ok`. No command prints JSON, a status code or a stack itself.
|
|
29
|
+
*/
|
|
30
|
+
function emit(result) {
|
|
31
|
+
for (const line of result.lines) {
|
|
32
|
+
if (result.ok)
|
|
33
|
+
console.log(line);
|
|
34
|
+
else
|
|
35
|
+
console.error(line);
|
|
36
|
+
}
|
|
37
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
38
|
+
}
|
|
39
|
+
/** `--url`/`--project` are on every service-backed command (config → env → flag, Task 1). */
|
|
40
|
+
function withTarget(command) {
|
|
41
|
+
return command
|
|
42
|
+
.option('--url <url>', 'backlog service URL (defaults to BACKLOG_URL, then the config)')
|
|
43
|
+
.option('--project <slug>', 'project slug (defaults to BACKLOG_PROJECT, then the config)');
|
|
44
|
+
}
|
|
45
|
+
program
|
|
46
|
+
.command('init')
|
|
47
|
+
.description('Authenticate, write backlog.config.json and .mcp.json, scaffold the conductor')
|
|
48
|
+
.option('--url <url>', 'backlog service URL (defaults to BACKLOG_URL, then the config)')
|
|
49
|
+
.option('--project <slug>', 'project slug — must be one this token can see')
|
|
50
|
+
.option('--token <pat>', 'PAT to use (defaults to BACKLOG_TOKEN, then ~/.config/backlog/token)')
|
|
51
|
+
.option('--save-token', 'store the PAT at ~/.config/backlog/token (mode 600)')
|
|
52
|
+
.option('--no-save-token', 'never store the PAT; print the chmod one-liner instead')
|
|
53
|
+
.option('--yes', 'never prompt; consent to storing the PAT')
|
|
54
|
+
.option('--force-mcp', `replace a differing "${MCP_SERVER_KEY}" entry in an existing .mcp.json`)
|
|
55
|
+
.option('--force-plugin', 'replace a plugin skill or command file that has been edited')
|
|
56
|
+
.action(async (opts) => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await runInit({
|
|
59
|
+
cwd: process.cwd(),
|
|
60
|
+
home: homedir(),
|
|
61
|
+
env: process.env,
|
|
62
|
+
flags: opts,
|
|
63
|
+
});
|
|
64
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err instanceof InitError || err instanceof TokenError || err instanceof ConfigError) {
|
|
68
|
+
console.error(err.message);
|
|
69
|
+
process.exitCode = 1;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
program
|
|
76
|
+
.command('doctor')
|
|
77
|
+
.description('Check local setup (token, project, conductor)')
|
|
78
|
+
.option('--url <url>', 'backlog service URL (defaults to BACKLOG_URL)')
|
|
79
|
+
.option('--project <slug>', 'project slug (defaults to BACKLOG_PROJECT)')
|
|
80
|
+
.action(async (opts) => {
|
|
81
|
+
const report = await runDoctorRemote(process.env, { url: opts.url, project: opts.project });
|
|
82
|
+
for (const c of report.checks) {
|
|
83
|
+
console.log(`${c.ok ? 'ok ' : 'FAIL'} ${c.name}${c.ok || !c.hint ? '' : ` — ${c.hint}`}`);
|
|
84
|
+
}
|
|
85
|
+
process.exitCode = report.ok ? 0 : 1;
|
|
86
|
+
});
|
|
87
|
+
program
|
|
88
|
+
.command('import')
|
|
89
|
+
.description('Read a docs/backlog folder (dry-run by default; --write to save a snapshot)')
|
|
90
|
+
.argument('<root>', 'repo root containing docs/backlog and conductor/')
|
|
91
|
+
.requiredOption('--project <name>', 'project name')
|
|
92
|
+
.option('--write', 'write the snapshot (otherwise dry-run)', false)
|
|
93
|
+
.option('--out <file>', 'snapshot path', 'backlog-snapshot.json')
|
|
94
|
+
.action(async (root, opts) => {
|
|
95
|
+
const snap = await importProject(root, opts.project);
|
|
96
|
+
console.log(`${snap.items.length} items, ${snap.tracks.length} tracks, ${snap.matrices.length} matrices, ${snap.warnings.length} warnings`);
|
|
97
|
+
for (const w of snap.warnings)
|
|
98
|
+
console.log(` ⚠ ${w}`);
|
|
99
|
+
if (!opts.write) {
|
|
100
|
+
console.log('dry-run — pass --write to save the snapshot');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
await writeFile(opts.out, JSON.stringify(snap, null, 2), 'utf8');
|
|
104
|
+
console.log(`wrote ${opts.out}`);
|
|
105
|
+
});
|
|
106
|
+
withTarget(program
|
|
107
|
+
.command('status')
|
|
108
|
+
.description('What the register says about this project (cached when the service is down)')
|
|
109
|
+
.option('--json', 'print the raw payload instead of the table')).action(async (opts) => {
|
|
110
|
+
emit(await runStatus(io(), opts));
|
|
111
|
+
});
|
|
112
|
+
withTarget(program
|
|
113
|
+
.command('next')
|
|
114
|
+
.description('The items that are ready to pick up, in order')
|
|
115
|
+
.option('--limit <n>', 'show at most N items', (value) => Number.parseInt(value, 10))
|
|
116
|
+
.option('--json', 'print the raw payload instead of the list')).action(async (opts) => {
|
|
117
|
+
emit(await runNext(io(), opts));
|
|
118
|
+
});
|
|
119
|
+
withTarget(program
|
|
120
|
+
.command('report')
|
|
121
|
+
.description('Record Evaluate-Loop progress on a track')
|
|
122
|
+
.argument('<track>', 'track slug')
|
|
123
|
+
.argument('<step>', 'PLAN | EVALUATE_PLAN | EXECUTE | EVALUATE_EXECUTION | FIX | COMPLETE')
|
|
124
|
+
.argument('<status>', 'IN_PROGRESS | PASS | FAIL | COMPLETE')
|
|
125
|
+
.option('--note <text>', 'a note to record with the report')
|
|
126
|
+
.option('--json', 'print the raw payload instead of the summary')).action(async (track, step, status, opts) => {
|
|
127
|
+
emit(await runReport(io(), { ...opts, track, step, status }));
|
|
128
|
+
});
|
|
129
|
+
withTarget(program
|
|
130
|
+
.command('promote')
|
|
131
|
+
.description('Promote locked items into a conductor track and write its files')
|
|
132
|
+
.argument('<ids...>', 'item refs, e.g. PLG-001 UI-002')
|
|
133
|
+
.option('--track <slug>', 'track slug (default: the service builds one from the first item)')
|
|
134
|
+
.option('--type <type>', 'feature | infra | fix', 'feature')
|
|
135
|
+
.option('--name <text>', 'the track name for metadata.json')
|
|
136
|
+
.option('--priority <P0-P4>', 'skip the items read and use this priority')
|
|
137
|
+
.option('--plan <path>', 'the plan plan.md should point at')
|
|
138
|
+
.option('--json', 'print the raw payload instead of the summary')).action(async (ids, opts) => {
|
|
139
|
+
emit(await runPromote(io(), { ...opts, ids }));
|
|
140
|
+
});
|
|
141
|
+
withTarget(program
|
|
142
|
+
.command('sync')
|
|
143
|
+
.description("Re-render a track's spec.md from the locked criteria and clear the drift flag")
|
|
144
|
+
.argument('[track]', 'track slug (default: every active track that has drifted)')
|
|
145
|
+
.option('--json', 'print the raw payload instead of the summary')).action(async (track, opts) => {
|
|
146
|
+
emit(await runSync(io(), { ...opts, ...(track ? { track } : {}) }));
|
|
147
|
+
});
|
|
148
|
+
withTarget(program
|
|
149
|
+
.command('ship')
|
|
150
|
+
.description('Ship a track: the register, then the local shipment sweep')
|
|
151
|
+
.argument('<track>', 'track slug')
|
|
152
|
+
.option('--commit <sha>', 'the merge commit that shipped')
|
|
153
|
+
.option('--date <YYYY-MM-DD>', 'the production date')
|
|
154
|
+
.option('--auto', 'read the commit from HEAD and the date from today')
|
|
155
|
+
.option('--override-reason <text>', 'Owner-only: override the ship gate, with a reason')
|
|
156
|
+
.option('--criteria-done <ref=n,n>', 'the AC numbers that are done (repeatable)', (value, all = []) => [...all, value])
|
|
157
|
+
.option('--note <text>', 'the Recent Completions note')
|
|
158
|
+
.option('--json', 'print the raw payload instead of the summary')).action(async (track, opts) => {
|
|
159
|
+
emit(await runShip(io(), { ...opts, track }));
|
|
160
|
+
});
|
|
161
|
+
const matrix = program.command('matrix').description('The QA matrix of a track');
|
|
162
|
+
withTarget(matrix
|
|
163
|
+
.command('init')
|
|
164
|
+
.description('Scaffold one QA row per locked criterion on a track')
|
|
165
|
+
.argument('<track>', 'track slug')
|
|
166
|
+
.option('--force', 'add rows for criteria that have none (never rewrites a row)')
|
|
167
|
+
.option('--json', 'print the raw payload instead of the summary')).action(async (track, opts) => {
|
|
168
|
+
emit(await runMatrixInit(io(), { ...opts, track }));
|
|
169
|
+
});
|
|
170
|
+
program
|
|
171
|
+
.command('export')
|
|
172
|
+
.description('Write a snapshot back to markdown (byte-exact for untouched objects)')
|
|
173
|
+
.argument('[outDir]', 'directory to write docs/… and conductor/… into (default: the repo root)')
|
|
174
|
+
.argument('[legacyOutDir]', 'the shipped two-argument form: <snapshot> <outDir>')
|
|
175
|
+
.option('--snapshot <file>', 'snapshot JSON from `backlog import --write`')
|
|
176
|
+
.action(async (outDir, legacyOutDir, opts) => {
|
|
177
|
+
emit(await runExport(io(), {
|
|
178
|
+
positionals: [outDir, legacyOutDir].filter((v) => typeof v === 'string'),
|
|
179
|
+
...(opts.snapshot ? { snapshot: opts.snapshot } : {}),
|
|
180
|
+
}));
|
|
181
|
+
});
|
|
182
|
+
program.parse();
|
|
183
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The token and the project. Both are decided before `init` writes anything: a refusal
|
|
3
|
+
* here must leave the repo exactly as it was, including the token file.
|
|
4
|
+
*
|
|
5
|
+
* There is no device flow — the service mints PATs in the web UI and nothing else. So the
|
|
6
|
+
* only interactive path is a hidden paste.
|
|
7
|
+
*/
|
|
8
|
+
/** A refusal `init` renders as one line. */
|
|
9
|
+
export declare class InitError extends Error {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
export interface Io {
|
|
13
|
+
input: NodeJS.ReadableStream;
|
|
14
|
+
output: NodeJS.WritableStream;
|
|
15
|
+
interactive: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Reads one line with the echo suppressed: the PAT never reaches the terminal, and so
|
|
19
|
+
* never reaches a scrollback buffer or a screen recording.
|
|
20
|
+
*
|
|
21
|
+
* The mute is a discarding output stream rather than an override of readline's internal
|
|
22
|
+
* `_writeToOutput` — that hook does not catch the per-character echo a terminal-mode
|
|
23
|
+
* interface writes, and the token would appear one character at a time.
|
|
24
|
+
*/
|
|
25
|
+
export declare function promptHidden(prompt: string, io: Io): Promise<string>;
|
|
26
|
+
/** Reads one visible line. */
|
|
27
|
+
export declare function promptLine(prompt: string, io: Io): Promise<string>;
|
|
28
|
+
export type TokenSource = 'flag' | 'env' | 'file' | 'prompt';
|
|
29
|
+
export interface ResolvedInitToken {
|
|
30
|
+
token: string;
|
|
31
|
+
source: TokenSource;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `--token` → `$BACKLOG_TOKEN` → `~/.config/backlog/token` → an interactive paste.
|
|
35
|
+
* Never logged, never echoed, never returned inside a message.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveInitToken(opts: {
|
|
38
|
+
flagToken?: string | undefined;
|
|
39
|
+
env: NodeJS.ProcessEnv;
|
|
40
|
+
home: string;
|
|
41
|
+
url: string;
|
|
42
|
+
io: Io;
|
|
43
|
+
}): Promise<ResolvedInitToken>;
|
|
44
|
+
export interface VisibleProject {
|
|
45
|
+
slug: string;
|
|
46
|
+
name: string;
|
|
47
|
+
role: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* `GET /v1/projects` — which is also the token's validation. A 401/403 renders through
|
|
51
|
+
* `explain()`: one sentence, no status code, no JSON.
|
|
52
|
+
*/
|
|
53
|
+
export declare function fetchVisibleProjects(opts: {
|
|
54
|
+
url: string;
|
|
55
|
+
token: string;
|
|
56
|
+
fetchImpl?: typeof fetch | undefined;
|
|
57
|
+
}): Promise<VisibleProject[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Only what `GET /v1/projects` returned is offerable (SVC-008): a slug that is not in the
|
|
60
|
+
* list is a membership problem, and the CLI says so in the same words `doctor` uses.
|
|
61
|
+
*
|
|
62
|
+
* The order is `--project` → the project an existing `backlog.config.json` already names →
|
|
63
|
+
* the only visible project → a prompt. `configured` is what makes a re-run in a repo that
|
|
64
|
+
* is already set up non-interactive-safe: the repo has already answered "which project",
|
|
65
|
+
* and re-asking (or refusing because several are visible) would make `init` unusable in CI
|
|
66
|
+
* and annoying everywhere else. It is a *default*, not an override: `--project` still wins,
|
|
67
|
+
* and a configured project the token can no longer see is refused exactly like a typed one
|
|
68
|
+
* — silently falling back to a different project would point the repo's commands at the
|
|
69
|
+
* wrong register.
|
|
70
|
+
*/
|
|
71
|
+
export declare function chooseProject(opts: {
|
|
72
|
+
requested?: string | undefined;
|
|
73
|
+
configured?: string | undefined;
|
|
74
|
+
projects: VisibleProject[];
|
|
75
|
+
url: string;
|
|
76
|
+
io: Io;
|
|
77
|
+
}): Promise<VisibleProject>;
|
|
78
|
+
/** Whether to persist the PAT: the flag if given, else an interactive y/N, else no. */
|
|
79
|
+
export declare function shouldSaveToken(opts: {
|
|
80
|
+
flag?: boolean | undefined;
|
|
81
|
+
yes?: boolean | undefined;
|
|
82
|
+
source: TokenSource;
|
|
83
|
+
home: string;
|
|
84
|
+
io: Io;
|
|
85
|
+
}): Promise<boolean>;
|