document360-writer 0.5.86 → 0.5.87

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 (77) hide show
  1. package/package.json +3 -3
  2. package/dist/cli.d.ts +0 -2
  3. package/dist/commands/allowProd.d.ts +0 -3
  4. package/dist/commands/audit.d.ts +0 -2
  5. package/dist/commands/capture-setup.d.ts +0 -12
  6. package/dist/commands/catchup.d.ts +0 -63
  7. package/dist/commands/clear.d.ts +0 -3
  8. package/dist/commands/convert.d.ts +0 -35
  9. package/dist/commands/devhints.d.ts +0 -125
  10. package/dist/commands/doctor.d.ts +0 -13
  11. package/dist/commands/document.d.ts +0 -19
  12. package/dist/commands/draft.d.ts +0 -27
  13. package/dist/commands/exit.d.ts +0 -2
  14. package/dist/commands/genre.d.ts +0 -3
  15. package/dist/commands/help.d.ts +0 -2
  16. package/dist/commands/inbox.d.ts +0 -11
  17. package/dist/commands/index.d.ts +0 -28
  18. package/dist/commands/init.d.ts +0 -9
  19. package/dist/commands/lint.d.ts +0 -8
  20. package/dist/commands/login.d.ts +0 -4
  21. package/dist/commands/logout.d.ts +0 -5
  22. package/dist/commands/logsCli.d.ts +0 -2
  23. package/dist/commands/mcp.d.ts +0 -2
  24. package/dist/commands/model.d.ts +0 -17
  25. package/dist/commands/profile.d.ts +0 -6
  26. package/dist/commands/project.d.ts +0 -3
  27. package/dist/commands/publish.d.ts +0 -57
  28. package/dist/commands/pull.d.ts +0 -45
  29. package/dist/commands/rename.d.ts +0 -5
  30. package/dist/commands/reorder.d.ts +0 -8
  31. package/dist/commands/reset.d.ts +0 -31
  32. package/dist/commands/resume.d.ts +0 -3
  33. package/dist/commands/review.d.ts +0 -9
  34. package/dist/commands/roadmap.d.ts +0 -10
  35. package/dist/commands/scope.d.ts +0 -9
  36. package/dist/commands/screenshot.d.ts +0 -44
  37. package/dist/commands/structure.d.ts +0 -6
  38. package/dist/commands/update.d.ts +0 -18
  39. package/dist/commands/workspace.d.ts +0 -3
  40. package/dist/commands/write.d.ts +0 -73
  41. package/dist/d360/authCli.d.ts +0 -13
  42. package/dist/d360/portalLink.d.ts +0 -18
  43. package/dist/d360/profileCli.d.ts +0 -3
  44. package/dist/d360/projectCli.d.ts +0 -17
  45. package/dist/d360/workspaceCli.d.ts +0 -17
  46. package/dist/lib/authPreflight.d.ts +0 -14
  47. package/dist/lib/categoryChoices.d.ts +0 -32
  48. package/dist/lib/checklist.d.ts +0 -30
  49. package/dist/lib/clipboard.d.ts +0 -1
  50. package/dist/lib/colors.d.ts +0 -10
  51. package/dist/lib/commandSuggest.d.ts +0 -7
  52. package/dist/lib/crashHandler.d.ts +0 -2
  53. package/dist/lib/diffRender.d.ts +0 -8
  54. package/dist/lib/hyperlink.d.ts +0 -5
  55. package/dist/lib/inputLayout.d.ts +0 -19
  56. package/dist/lib/mascot.d.ts +0 -5
  57. package/dist/lib/mdRender.d.ts +0 -7
  58. package/dist/lib/modelChoices.d.ts +0 -14
  59. package/dist/lib/nextActions.d.ts +0 -104
  60. package/dist/lib/paste.d.ts +0 -19
  61. package/dist/lib/pickOptions.d.ts +0 -18
  62. package/dist/lib/quickOptions.d.ts +0 -24
  63. package/dist/lib/readyState.d.ts +0 -19
  64. package/dist/lib/streaming.d.ts +0 -23
  65. package/dist/lib/syncRender.d.ts +0 -10
  66. package/dist/lib/toolFormat.d.ts +0 -30
  67. package/dist/lib/upgradeTable.d.ts +0 -5
  68. package/dist/oneShot.d.ts +0 -7
  69. package/dist/repl.d.ts +0 -18
  70. package/dist/tui/App.d.ts +0 -9
  71. package/dist/tui/HelpModal.d.ts +0 -7
  72. package/dist/tui/catalog.d.ts +0 -17
  73. package/dist/tui/helpContent.d.ts +0 -35
  74. package/dist/tui/index.d.ts +0 -3
  75. package/dist/tui/itemRender.d.ts +0 -79
  76. package/dist/tui/termTitle.d.ts +0 -28
  77. package/dist/tui/transcriptStore.d.ts +0 -5
@@ -1,3 +0,0 @@
1
- import type { SlashCommandResult } from './index.js';
2
- import type { ReplContext } from '../repl.js';
3
- export declare function resumeCommand(args: string[], ctx: ReplContext): Promise<SlashCommandResult>;
@@ -1,9 +0,0 @@
1
- import type { ReplContext } from '../repl.js';
2
- import type { SlashCommandResult } from './index.js';
3
- /** Build the forward-to-agent review request for a repo (shared by classic + TUI). Returns null when there's
4
- no config (caller surfaces the /init hint). */
5
- export declare function buildReview(cwd: string, args: string[]): {
6
- prompt: string;
7
- display: string;
8
- } | null;
9
- export declare function reviewCommand(args: string[], ctx: ReplContext): Promise<SlashCommandResult>;
@@ -1,10 +0,0 @@
1
- import type { ReplContext } from '../repl.js';
2
- import type { SlashCommandResult } from './index.js';
3
- /** Render the campaign as plain lines (shared by the TUI note and the classic REPL). */
4
- export declare function roadmapLines(cwd: string): string[];
5
- /** `/roadmap done <step title>` — stamp a step completed outside agent turns. */
6
- export declare function roadmapDoneByTitle(cwd: string, title: string): {
7
- ok: boolean;
8
- line: string;
9
- };
10
- export declare function roadmapCommand(args: string[], ctx: ReplContext): Promise<SlashCommandResult>;
@@ -1,9 +0,0 @@
1
- import { type ScopeCandidate } from 'document360-engine';
2
- import type { ReplContext } from '../repl.js';
3
- import type { SlashCommandResult } from './index.js';
4
- /** Persist the chosen scope folders into .d360-writer/config.json (read-modify-write so
5
- unrelated fields survive). Shared by the REPL command and the TUI picker. */
6
- export declare function setAuthoritativeSourceFiles(cwd: string, paths: string[]): void;
7
- /** One display row: "src/Services/Document360.API · 142 files · .NET · user-facing surface". */
8
- export declare function scopeRowLabel(c: ScopeCandidate): string;
9
- export declare function scopeCommand(args: string[], ctx?: ReplContext): Promise<SlashCommandResult>;
@@ -1,44 +0,0 @@
1
- import { type Partition } from 'document360-engine';
2
- import type { ReplContext } from '../repl.js';
3
- import type { SlashCommandResult } from './index.js';
4
- export type ScreenshotArgs = {
5
- mode: 'single';
6
- id: string;
7
- } | {
8
- mode: 'all';
9
- setup: boolean;
10
- } | {
11
- mode: 'scope';
12
- scope: string;
13
- setup: boolean;
14
- } | {
15
- mode: 'list';
16
- scope?: string;
17
- };
18
- /** `--list [path]` → list; `<id>` → single; no arg / `--all` → all; a folder/.md path → scoped bulk.
19
- A bulk run also refreshes the capture-setup checklist when done; `--no-setup` opts out (anywhere
20
- in the args). Single-id runs never chain the checklist (you're iterating on one shot). */
21
- export declare function parseScreenshotArgs(args: string[]): ScreenshotArgs;
22
- export type ScreenshotState = 'placeholder' | 'spec' | 'captured';
23
- export type ScreenshotRow = {
24
- id: string;
25
- file: string;
26
- state: ScreenshotState;
27
- };
28
- /** Each placeholder + where it is in the pipeline. State is DERIVED from the filesystem:
29
- a spec file → 'spec'; a captured PNG → 'captured'; otherwise just the 'placeholder'. */
30
- export declare function listScreenshots(cwd: string, scope?: string): ScreenshotRow[];
31
- /** Render the list grouped by article, with a per-shot status marker + a legend. */
32
- export declare function renderScreenshotList(rows: ScreenshotRow[], scope?: string): string[];
33
- /** Prompt for ONE parallel partition: author the spec for each placeholder id in it. The rules
34
- (read source for routes/selectors, scope, prerequisite guards) live in the emit-screenshot-spec
35
- skill — keep this terse so it just points the agent at the work. */
36
- export declare function buildScreenshotBatchPrompt(partition: Partition): string;
37
- /**
38
- * `/screenshot` — list or author document360-capture specs from SCREENSHOT placeholders.
39
- * - `/screenshot --list [path]` → status of every placeholder (no agent; read-only).
40
- * - `/screenshot <id>` → author one (forwarded to the agent as a single turn).
41
- * - no arg / `--all` / a path → BULK. The TUI runs these in parallel (App.tsx); the classic
42
- * REPL forwards a single bulk turn.
43
- */
44
- export declare function screenshotCommand(args: string[], ctx?: ReplContext): Promise<SlashCommandResult>;
@@ -1,6 +0,0 @@
1
- import type { ReplContext } from '../repl.js';
2
- import type { SlashCommandResult } from './index.js';
3
- /** The ordered category → article tree as display lines (categories flush-left, articles indented).
4
- Empty when there's no config/map. Shared by the classic command + the TUI case. */
5
- export declare function structureLines(cwd: string, profileName?: string): string[];
6
- export declare function structureCommand(_args: string[], ctx: ReplContext): Promise<SlashCommandResult>;
@@ -1,18 +0,0 @@
1
- import type { SlashCommandResult } from './index.js';
2
- export declare const SELF_UPDATE_PKG = "document360-writer";
3
- export declare const SELF_UPDATE_HINT = "npm i -g document360-writer@latest";
4
- /** Run the global install. Best-effort: resolves {ok,output}, never throws.
5
- - shell:true (as a STRING command, not an args array) resolves `npm`/`npm.cmd` cross-platform without
6
- tripping Node's DEP0190 (dogfood s-197); the only interpolated value is a fixed package name.
7
- - Survive the app exiting mid-install (`npm i -g` rewrites the global shims; a missing shim → "command
8
- not recognized", s-201). On POSIX that needs `detached` + `unref` so the child outlives the parent.
9
- On WINDOWS we must NOT detach: `detached` there forces a NEW console window (a frozen-looking
10
- Windows-Terminal tab — dogfood s-211/212), and windowsHide doesn't suppress it. Windows doesn't kill
11
- child processes when the parent exits anyway, so the install completes regardless. windowsHide keeps
12
- the hidden shell from flashing. */
13
- export declare function runSelfUpdate(): Promise<{
14
- ok: boolean;
15
- output: string;
16
- }>;
17
- /** Classic-REPL `/update`: install, then tell the user to relaunch. */
18
- export declare function updateCommand(): Promise<SlashCommandResult>;
@@ -1,3 +0,0 @@
1
- import type { SlashCommandResult } from './index.js';
2
- import type { ReplContext } from '../repl.js';
3
- export declare function workspaceCommand(_args: string[], ctx: ReplContext): Promise<SlashCommandResult>;
@@ -1,73 +0,0 @@
1
- import { type CostEstimate, type DocsPlanEntry, type Partition, type PartitionResult, type TargetFile } from 'document360-engine';
2
- import type { ReplContext } from '../repl.js';
3
- import type { SlashCommandResult } from './index.js';
4
- /** Partitions running at once. Each is a heavy Claude Code subprocess; on a dev laptop 5 at once
5
- starved memory and aborted a worker hard (SNAG-0223 → SNAG-0222 cascade), so the default is a
6
- safer 3. Override per-run with `--concurrency N` (capped at MAX_WRITE_CONCURRENCY). */
7
- export declare const WRITE_CONCURRENCY = 3;
8
- export declare const MAX_WRITE_CONCURRENCY = 8;
9
- /** Clamp a requested concurrency to [1, MAX]; non-numeric/absent → the default. */
10
- export declare function resolveConcurrency(requested?: number): number;
11
- /** Parse /write args. The default ACTION is to write — `/write` starts immediately. `--preview` asks
12
- for the plan + cost estimate only (no spend). `--scope <cat>` (or `--scope=…`) narrows, `--concurrency
13
- <n>` tunes parallelism, a bare `<path>` writes one article. `--rewrite` (alias `--force`) regenerates
14
- ALREADY-written articles in scope too (the normal scope/all run skips written ones) — the iterate loop
15
- after a plan/playbook change. `--run`/`--all`/`--yes` are accepted as legacy no-ops. */
16
- export declare function parseWriteArgs(args: string[]): {
17
- scope?: string;
18
- path?: string;
19
- preview: boolean;
20
- concurrency?: number;
21
- rewrite: boolean;
22
- };
23
- /** Drop a leading `<docsDir>/` so a path given repo-relative matches the docsDir-relative plan keys. */
24
- export declare function toPlanRelative(p: string, docsDir: string): string;
25
- /** Keep only plan paths under `scope` (a category prefix or an exact .md path). No scope → all. */
26
- export declare function applyScope(paths: string[], scope?: string): string[];
27
- /** Of the given docsDir-relative paths, the ones not yet written (file missing or empty). FS. */
28
- export declare function pendingArticles(cwd: string, docsDir: string, paths: string[]): string[];
29
- /** Size each target by the SUM of its plan SOURCE bytes (the article file doesn't exist yet). The
30
- 1-byte floor keeps every planned article in the estimate so its per-article overhead counts. */
31
- export declare function sizeWriteTargets(cwd: string, entries: DocsPlanEntry[], paths: string[]): TargetFile[];
32
- /** The agent prompt for one partition: author each listed article from the plan. Each is
33
- independent; purpose + sources are looked up from the pinned plan, grounded in source.
34
- `rewrite` ⇒ the targets already exist (a `--rewrite`/single-path re-author): tell the agent to rebuild
35
- from plan + sources + the active doc-type playbook, NOT to preserve or lightly-edit the old file — else
36
- it anchors on the prior (possibly junior) output and reproduces it (dogfood P-A A5). */
37
- export declare function buildWritePrompt(partition: Partition, docsDir: string, opts?: {
38
- rewrite?: boolean;
39
- }): string;
40
- /** Preview lines for `/write --preview`: the partition plan + the cost band, before any spend. */
41
- export declare function previewLines(partitions: Partition[], estimate: CostEstimate, concurrency: number): string[];
42
- /**
43
- * Final summary, a bookend to the opening "Writing N articles across M partitions…" line. Usage
44
- * shows dollars in API mode but OUTPUT TOKENS on a Claude subscription (per-token cost is
45
- * meaningless there). `partitions` maps each result back to its article count (results carry only
46
- * an index).
47
- */
48
- export declare function summaryLines(results: PartitionResult[], partitions: Partition[], usage: 'api' | 'subscription'): string[];
49
- /** After a write run, grade JUST the authored articles with the doc-checker (deterministic, no tokens) so
50
- every write is self-checked, not only on a manual /lint. Returns a one-line summary when issues are
51
- found (pointing at /lint), or null when clean. `targets` are docsDir-relative; `docsDir` is repo-relative. */
52
- export declare function autoLintLine(cwd: string, docsDir: string, targets: string[]): string | null;
53
- /** Resolve the docsDir-relative article paths a /write invocation targets, from the pinned plan.
54
- Returns the target list + context for messaging. Single path → that article (forced, even if it
55
- exists); scope/all → not-yet-written articles only. FS-touching (existence checks). */
56
- export declare function selectWriteTargets(cwd: string, entries: DocsPlanEntry[], args: {
57
- scope?: string;
58
- path?: string;
59
- rewrite?: boolean;
60
- }): {
61
- docsDir: string;
62
- targets: string[];
63
- planCount: number;
64
- reason?: string;
65
- rewriting?: boolean;
66
- };
67
- /**
68
- * Classic-REPL `/write` — parity with the TUI handler (App.tsx): `/write [--scope x]` writes the
69
- * planned articles across parallel agents immediately; `/write --preview` shows the plan + cost first
70
- * (no spend). A single `<path>` writes that article immediately. Mid-run abort is TUI-only (Esc);
71
- * Ctrl+C exits the REPL here.
72
- */
73
- export declare function writeCommand(args: string[], ctx: ReplContext): Promise<SlashCommandResult>;
@@ -1,13 +0,0 @@
1
- import { type StoredTokens } from 'document360-engine';
2
- export declare function identityLine(tokens: StoredTokens): string;
3
- export declare function runLogin(opts: {
4
- profile?: string;
5
- manual?: boolean;
6
- }): Promise<void>;
7
- export declare function maybePersistProject(tokens: StoredTokens, profileName: string, note: (line: string) => void): Promise<void>;
8
- export declare function runWhoami(opts: {
9
- profile?: string;
10
- }): Promise<void>;
11
- export declare function runLogout(opts: {
12
- profile?: string;
13
- }): Promise<void>;
@@ -1,18 +0,0 @@
1
- /**
2
- * Deep links into the Document360 author portal, surfaced after the agent creates or
3
- * updates an article so the real rendered outcome is one click away.
4
- *
5
- * NOTE: the editor path shape (`/{projectId}/document/v1/{lang}/{articleId}`) is a
6
- * best-effort guess pending verification against the berlin portal during dogfood —
7
- * if it 404s, fix it HERE (single source) or override the base via the profile's
8
- * `connection.portalUrl` / `D360_PORTAL_URL`.
9
- */
10
- /** Portal editor URL for a draft article. */
11
- export declare function articleEditorUrl(portalUrl: string, projectId: string, articleId: string, languageCode?: string): string;
12
- /**
13
- * Pull the article id out of a write-tool exchange: update/fork/publish carry it in
14
- * the input; create returns it in the result (bulk-create → array with one item).
15
- */
16
- export declare function extractArticleId(input: Record<string, unknown>, output: string): string | null;
17
- /** Public KB URL from a tool result, if the API returned one (live after publish). */
18
- export declare function extractPublicUrl(output: string): string | null;
@@ -1,3 +0,0 @@
1
- export declare function runProfileList(cwd: string): void;
2
- export declare function runProfileUse(cwd: string, name: string): void;
3
- export declare function runProfileShow(cwd: string, name?: string): void;
@@ -1,17 +0,0 @@
1
- import { type D360Project } from 'document360-engine';
2
- /** Fetch every project the active profile's identity can access. Throws on auth/API errors. */
3
- export declare function fetchProjects(cwd: string, profileName?: string): Promise<{
4
- projects: D360Project[];
5
- profile: string;
6
- environment: string;
7
- current?: string;
8
- }>;
9
- /** Match a project by exact name, name-prefix, or id-prefix (for `/project <name>`). */
10
- export declare function matchProject(projects: D360Project[], query: string): D360Project | undefined;
11
- /** Switching project invalidates any selected workspace — clear it so /workspace re-picks. Caches the
12
- project NAME for display (banner, workspace picker) so we never show a bare GUID. */
13
- export declare function setProject(cwd: string, profileName: string, projectId: string, projectName?: string): void;
14
- /** Non-interactive set-by-name (scriptable): `d360-writer project use <name>`. */
15
- export declare function runProjectUse(cwd: string, query: string, profileName?: string): Promise<number>;
16
- /** CLI / login path: list projects and prompt (interactive TTY). Persists the choice. */
17
- export declare function runProjectPicker(cwd: string, profileName?: string): Promise<void>;
@@ -1,17 +0,0 @@
1
- import { type D360Workspace } from 'document360-engine';
2
- /** Fetch workspaces for the active profile's project. Throws on auth/API errors. */
3
- export declare function fetchWorkspaces(cwd: string, profileName?: string): Promise<{
4
- workspaces: D360Workspace[];
5
- projectId: string;
6
- projectName?: string;
7
- profile: string;
8
- environment: string;
9
- current?: string;
10
- }>;
11
- /** Match a workspace by exact name, name-prefix, or id-prefix (for `/workspace <name>`). */
12
- export declare function matchWorkspace(workspaces: D360Workspace[], query: string): D360Workspace | undefined;
13
- export declare function setWorkspace(cwd: string, profileName: string, projectId: string, workspaceId: string, workspaceName?: string): void;
14
- /** Non-interactive set-by-name (scriptable): `d360-writer workspace use <name>`. */
15
- export declare function runWorkspaceUse(cwd: string, query: string, profileName?: string): Promise<number>;
16
- /** CLI / login path: list workspaces and prompt (interactive TTY). Persists the choice. */
17
- export declare function runWorkspacePicker(cwd: string, profileName?: string): Promise<void>;
@@ -1,14 +0,0 @@
1
- export type PreflightVerdict = {
2
- ok: true;
3
- } | {
4
- ok: false;
5
- reason: string;
6
- };
7
- /**
8
- * Verify the signed-in Document360 session can actually act on the active profile's project. Catches the
9
- * three states that otherwise fail mid-run: not signed in, an unrefreshable expired session, and a
10
- * project mismatch (the token is scoped to a different project than the profile pins — the exact
11
- * "token is scoped to a specific project" 403). Returns `{ ok: true }` when nothing is provably wrong
12
- * (it can't predict every server-side scope, so the engine's 403 re-message remains the safety net).
13
- */
14
- export declare function checkD360Preflight(cwd: string, profileName?: string): PreflightVerdict;
@@ -1,32 +0,0 @@
1
- /** One pickable category: `token` is the docsDir-relative prefix `--scope` wants (e.g. "04-scenario-manager"),
2
- `label` its human name, `count` its article count. */
3
- export type CategoryChoice = {
4
- token: string;
5
- label: string;
6
- count: number;
7
- };
8
- /**
9
- * The ordered list of categories to offer for `--scope`, in reading order. Deterministic, no network.
10
- * `token` is the category path made docsDir-relative — exactly what `/write --scope`, `/check`, `/review`,
11
- * `/reorder` accept. Empty (no config / no map / unresolved profile) → []. Root-level entries (no token)
12
- * are dropped — you can't scope to "everything" via the picker.
13
- */
14
- export declare function categoryChoices(cwd: string, profileName?: string): CategoryChoice[];
15
- /** Classic-REPL fallback (no picker overlay): the lines to print when `--scope` was given without a value,
16
- so the user can copy an exact `--scope <token>`. Mirrors the TUI picker's list. */
17
- export declare function scopeHintLines(cwd: string, profileName?: string): string[];
18
- /** True when a bare invocation would act on the WHOLE knowledge base and should offer a choice first
19
- (like bare /publish): /review or /reorder with no positional scope, or /write --rewrite with no
20
- scope/path. `--all` is the explicit everything escape (what the TUI picker's first row dispatches),
21
- so it — and any positional — skips the gate. Report-only whole-KB commands (/check, /audit) are
22
- exempt by design. */
23
- export declare function bareWholeKbInvocation(name: string, args: string[]): boolean;
24
- /** Classic-REPL fallback for a bare whole-KB invocation: print the choices (everything vs per category)
25
- with the exact commands to copy. Empty when there's nothing meaningful to choose (0–1 categories). */
26
- export declare function wholeKbHintLines(cwd: string, name: string, args: string[], profileName?: string): string[];
27
- /** True when the args ASK for a scope (`--scope`) but omit its value (next token missing or another flag) —
28
- the signal to open the category picker (TUI) or print the token list (classic). */
29
- export declare function scopeFlagWithoutValue(args: string[]): boolean;
30
- /** Rebuild an arg list with `--scope <token>` — filling an empty `--scope`, replacing an existing value, or
31
- prepending the flag if absent. Preserves every other flag (e.g. `--rewrite`). */
32
- export declare function withScopeValue(args: string[], token: string): string[];
@@ -1,30 +0,0 @@
1
- export type ChecklistStatus = 'pending' | 'active' | 'done' | 'failed';
2
- /** `itemsDone` is live per-item progress WITHIN an active partition (e.g. articles written so far of
3
- `items`); undefined for flows that don't report per-item progress (the row then shows the total only). */
4
- export type ChecklistRow = {
5
- label: string;
6
- items: number;
7
- status: ChecklistStatus;
8
- itemsDone?: number;
9
- };
10
- /** Build the initial (all-pending) checklist rows from a partition plan. */
11
- export declare function checklistRows(partitions: {
12
- label: string;
13
- paths: string[];
14
- }[]): ChecklistRow[];
15
- /** Return rows with the named partition set to `status` (immutable; for setConvertProgress updaters). */
16
- export declare function withRowStatus(rows: ChecklistRow[], label: string, status: ChecklistStatus): ChecklistRow[];
17
- /** Return rows with the named partition's `itemsDone` bumped by one (capped at `items`). Drives the
18
- live "1/3 articles" sub-progress as each file lands — so a long write turn shows steady movement
19
- instead of a frozen-looking 0/N. Immutable (for setConvertProgress updaters). */
20
- export declare function withRowItemDone(rows: ChecklistRow[], label: string): ChecklistRow[];
21
- /** If this tool event wrote one of a partition's target articles, return that target path; else null.
22
- The tool's `file_path` is absolute/cwd-relative while partition paths are docsDir-relative, so we match
23
- by path-tail (with a `/` boundary so "…/11-x.md" can't match target "1-x.md"). Pure + testable; the
24
- caller dedupes (an Edit after a Write to the same file must tick the article only once). */
25
- export declare function writtenArticle(toolName: string, input: Record<string, unknown>, paths: string[]): string | null;
26
- /** Strip a leading docs-dir path segment so a category row reads "01-getting-started", not
27
- "user-docs/01-…". Only matches a path-like token (no spaces) so "chunk 1/3" is left intact. */
28
- export declare function rowLabel(label: string): string;
29
- export declare const CHECKLIST_MAX_ROWS = 16;
30
- export declare const ROW_MARK: Record<ChecklistStatus, string>;
@@ -1 +0,0 @@
1
- export declare function copyToClipboard(text: string): Promise<boolean>;
@@ -1,10 +0,0 @@
1
- /** Document360 brand purple — single source of truth for the app's primary color. */
2
- export declare const BRAND_HEX = "#7f56d9";
3
- export declare const banner: (s: string) => string;
4
- export declare const dim: (s: string) => string;
5
- export declare const error: (s: string) => string;
6
- export declare const warn: (s: string) => string;
7
- export declare const ok: (s: string) => string;
8
- export declare const accent: (s: string) => string;
9
- export declare const muted: (s: string) => string;
10
- export declare const bold: (s: string) => string;
@@ -1,7 +0,0 @@
1
- /**
2
- * Quick-run options: when an agent turn ends by suggesting slash commands (e.g. the
3
- * gap-analysis trust gate offering `/pull <path>` vs `/publish <path>`), the TUI
4
- * lets the user press 1-N to fill the command instead of retyping it. Only standalone
5
- * command lines count — a command mentioned mid-sentence is prose, not an option.
6
- */
7
- export declare function extractCommandSuggestions(text: string, knownNames: string[], max?: number): string[];
@@ -1,2 +0,0 @@
1
- /** Install once at startup. `label` names the running command in the log (e.g. 'd360-writer'). */
2
- export declare function installCrashHandlers(label: string): void;
@@ -1,8 +0,0 @@
1
- export type DiffView = {
2
- added: number;
3
- removed: number;
4
- lines: string[];
5
- hidden: number;
6
- };
7
- /** Render old→new content as a Claude Code-style diff. Returns null when identical. */
8
- export declare function renderArticleDiff(oldContent: string, newContent: string, width: number): DiffView | null;
@@ -1,5 +0,0 @@
1
- /** Conservative allowlist of terminals known to handle OSC 8 (à la supports-hyperlinks). */
2
- export declare function supportsHyperlinks(env?: NodeJS.ProcessEnv): boolean;
3
- export declare function hyperlink(url: string, text?: string, env?: NodeJS.ProcessEnv): string;
4
- /** Wrap every URL in a string as its own OSC 8 hyperlink (text shown unchanged). */
5
- export declare function linkifyUrls(s: string, env?: NodeJS.ProcessEnv): string;
@@ -1,19 +0,0 @@
1
- /**
2
- * Input-editor layout math (SNAG-0057): the input box renders multi-line text as
3
- * hard-wrapped visual lines with the caret positioned IN the text (it used to be
4
- * a sibling element stranded after the wrapped block). Pure functions — the same
5
- * layout drives rendering and arrow/home/end caret movement, so they can't drift.
6
- */
7
- export type VisualLine = {
8
- start: number;
9
- end: number;
10
- };
11
- /** Split on real newlines, then hard-wrap each segment at `width` columns. */
12
- export declare function layoutInput(text: string, width: number): VisualLine[];
13
- /** Visual line containing the caret. At a wrap boundary (pos == end == next.start)
14
- the caret belongs to the NEXT line (column 0) — standard editor behavior. */
15
- export declare function caretLineIndex(lines: VisualLine[], pos: number): number;
16
- /** Move the caret one visual line up/down, preserving the column (clamped). */
17
- export declare function moveCaretVertically(lines: VisualLine[], pos: number, delta: 1 | -1): number;
18
- /** Home/End within the caret's visual line. */
19
- export declare function caretLineEdge(lines: VisualLine[], pos: number, edge: 'start' | 'end'): number;
@@ -1,5 +0,0 @@
1
- /**
2
- * Render the mascot as ANSI lines (one per two pixel rows), or [] when colors are
3
- * off (NO_COLOR / non-TTY) — a colorless silhouette loses the face, so skip it.
4
- */
5
- export declare function mascotLines(): string[];
@@ -1,7 +0,0 @@
1
- /** Render inline **bold**, *italic*, `code` as ANSI-styled spans. */
2
- export declare function inlineMd(text: string): string;
3
- /**
4
- * Render finalized markdown to an ANSI string. Blocks are joined with one blank line
5
- * (uniform spacing — source blocks are blank-line separated, so render them so).
6
- */
7
- export declare function renderMarkdown(md: string, width: number): string;
@@ -1,14 +0,0 @@
1
- /** The /model picker's curated list (mirrors Claude Code's /model dialog).
2
- Class aliases ('opus'/'sonnet'/'haiku') stay evergreen — the runtime resolves
3
- them to the latest model in class; Fable needs its exact id. */
4
- import type { ResolvedModel } from 'document360-engine';
5
- export type ModelChoice = {
6
- /** Value written to the personal config; null = clear the override (runtime default). */
7
- value: string | null;
8
- label: string;
9
- desc: string;
10
- };
11
- export declare const MODEL_CHOICES: ModelChoice[];
12
- /** Index of the choice matching the resolved model (for the ✓ marker / initial cursor).
13
- Personal/team/env overrides match by value or label; unset → Auto (the docs-right default). */
14
- export declare function currentChoiceIndex(resolved: ResolvedModel): number;
@@ -1,104 +0,0 @@
1
- /** Inputs the decision needs, all already read from disk by the caller (see lib/readyState.ts). */
2
- export type ReadyInputs = {
3
- /** Configured + signed in + scope ok + Claude present. False ⇒ the setup ladder owns the screen. */
4
- ready: boolean;
5
- /** Any tracked docs exist locally (a non-empty docsDir). */
6
- hasDocs: boolean;
7
- /** Count of articles in the category map for the active profile. */
8
- tracked: number;
9
- /** Builder queue WITHOUT directives — e.g. "2 hints, 1 request", or null when nothing's queued. */
10
- pendingText: string | null;
11
- /** OPEN owner directives (.d360-writer/directives.md) — the owner's proactive doc asks. Ranked with
12
- the builder queue (both are queued intent → /catch-up) but surfaced as their own bullet. */
13
- directives: number;
14
- /** Planned articles (plan.json) not yet written — missing/empty files. >0 after an interrupted /write. */
15
- pendingWrites: number;
16
- /** Tracked articles changed locally since their sync base (local-ahead) — ready to /publish (s-244). */
17
- localAhead: number;
18
- /** Commits on HEAD since the last `/audit` marker (0 when never audited or not a git repo). */
19
- behind: number;
20
- /** The user's `/audit --auto on` setting. */
21
- autoAudit: boolean;
22
- /** Active profile/connection name, for the "N articles tracked for X" line. */
23
- profileName: string;
24
- /** Whether the caller may auto-run /audit (true only at launch — never on the post-turn refresh,
25
- which would loop). When false, a would-be auto-audit degrades to recommending /audit. */
26
- allowAutoAudit: boolean;
27
- /** devhintsStaleness(cwd).status — is the builder's dev↔docs protocol behind this package's? */
28
- devhints: 'current' | 'stale' | 'unset';
29
- /** The protocol version the builder last completed (for "you're on v6" copy). */
30
- devhintsCompletedVersion?: number;
31
- /** This package's protocol version (DEVHINTS_VERSION — passed in so the brain stays pure). */
32
- devhintsToVersion?: number;
33
- /** builderHasStarted(cwd) — an architecture brief exists. The brain leads /devhints ONLY when the
34
- builder has started; the never-started case keeps the caller's full hand-off flow (copy prompt +
35
- wait heartbeat) untouched. */
36
- builderStarted: boolean;
37
- /** The doc genre (appType) couldn't be auto-classified — the /genre picker is the fix. */
38
- genreUnknown: boolean;
39
- /** The docs roadmap (roadmapProgress(cwd)) — the durable CAMPAIGN in .d360-writer/roadmap.md.
40
- Null when the file is absent or has no steps. `next` is the first open step; null when all done
41
- (the "campaign complete" calm state). */
42
- roadmap: {
43
- done: number;
44
- total: number;
45
- next: {
46
- title: string;
47
- run?: string;
48
- } | null;
49
- } | null;
50
- };
51
- /** The one recommended action. `cmd` fills the ghost and runs on Tab→Enter; `prompt` is a free-text
52
- ghost (e.g. cold-start "write the docs for this repo"). */
53
- export type Lead = {
54
- kind: 'cmd';
55
- cmd: string;
56
- reason: string;
57
- } | {
58
- kind: 'prompt';
59
- text: string;
60
- reason: string;
61
- };
62
- /** A true multi-choice — the ONLY thing rendered as a numbered list. */
63
- export type PickerSpec = {
64
- title: string;
65
- options: {
66
- cmd: string;
67
- desc: string;
68
- }[];
69
- };
70
- export type Recommendation = {
71
- /** Conversational transcript briefing (bullets + lead sentence + prose follow-ups), or null when
72
- there is nothing worth printing (the caller's silent post-turn restores pass this through). */
73
- note: string | null;
74
- tone: 'info' | 'warn';
75
- /** Null in the calm steady state (nothing to push), or when a picker owns the moment. */
76
- lead: Lead | null;
77
- /** Set only for true choices (today: the doc genre). */
78
- picker: PickerSpec | null;
79
- };
80
- export type ReadyDecision =
81
- /** Not in the ready state — the caller must leave ghost/picker untouched (setup ladder owns it). */
82
- {
83
- kind: 'idle';
84
- }
85
- /** Launch only: code moved + auto-audit on ⇒ run /audit now. `note` is the ambient line to show. */
86
- | {
87
- kind: 'autoAudit';
88
- note: string;
89
- }
90
- /** The one recommendation for every other ready state. */
91
- | {
92
- kind: 'recommend';
93
- rec: Recommendation;
94
- };
95
- /** "⇥ tab to run /devhints · or just ask me anything…" — the input-placeholder hint that carries the
96
- lead. Null for prompt-style leads (the ghost text itself renders in the input, as before). */
97
- export declare function ghostHintFor(lead: Lead): string | null;
98
- /** The one-sentence recommendation — used inside the briefing AND as the REPL's "Next:" line. */
99
- export declare function leadLine(lead: Lead): string;
100
- /**
101
- * Decide the next action from already-gathered inputs. Pure — no I/O — so it's unit-tested and is the
102
- * one place the ladder + copy live.
103
- */
104
- export declare function decideReadyActions(i: ReadyInputs): ReadyDecision;
@@ -1,19 +0,0 @@
1
- /**
2
- * Claude Code-style paste collapsing for the TUI input box. Large or multiline
3
- * pastes are held aside and represented inline by a marker like
4
- * `[Pasted text #1 +12 lines]`; markers expand back to the full text at submit.
5
- * Pure logic — the TUI owns the marker→text map (session lifetime, so history
6
- * recall of a collapsed prompt still expands).
7
- */
8
- export declare function normalizePaste(raw: string): string;
9
- /** Collapse multiline pastes (the input box is one line) and long single-line ones. */
10
- export declare function shouldCollapse(text: string): boolean;
11
- export declare function makeMarker(id: number, text: string): string;
12
- /** Replace every intact marker that has a stored paste; unknown markers pass through. */
13
- export declare function expandPastes(text: string, pastes: ReadonlyMap<string, string>): string;
14
- /**
15
- * Backspace treats a marker as atomic (Claude Code behavior): if the input ends
16
- * with one, remove it whole; otherwise remove the last character. Returns null
17
- * when the input does not end with a marker.
18
- */
19
- export declare function stripTrailingMarker(input: string): string | null;
@@ -1,18 +0,0 @@
1
- export declare const PICK_CUE: RegExp;
2
- export type PickState = {
3
- num: number;
4
- closed: boolean;
5
- cueSeen: boolean;
6
- };
7
- /**
8
- * Renumber the option bullets that FOLLOW a "reply with the number" cue line to `1.` `2.` `3.` so they're
9
- * actually pickable. Walks line by line, flipping `cueSeen` only when it passes the cue line itself — so
10
- * bullets that appear BEFORE the cue (e.g. an earlier "things to flag" list) are never touched, and only
11
- * the FIRST contiguous block AFTER the cue is numbered (dogfood: the cue trailed an unrelated bullet list
12
- * in an /audit, and the old "cue anywhere → first block" logic renumbered the wrong one and missed the
13
- * real options). Conservative: top-level `-`/`*`/`•` only; indented continuation lines (wrapped
14
- * descriptions) don't close the block — only a non-indented, non-bullet line does. `state` persists across
15
- * streamed chunks (the cue line and the options can arrive in different chunks). No-op once the block is
16
- * closed, or if the agent already numbered the options.
17
- */
18
- export declare function renumberPickOptions(chunk: string, state: PickState): string;
@@ -1,24 +0,0 @@
1
- /** A quick-run option is either a bare command line (description derived from the catalog) OR a
2
- command plus a CONTEXTUAL description that travels with it — so a CTA can say exactly what each
3
- key does in this moment (e.g. "/check" = "re-scan", vs the catalog blurb). The description riding
4
- on the option means it can never go stale or mismatch the command (no parallel side-map to sync). */
5
- export type QuickOption = string | {
6
- cmd: string;
7
- desc: string;
8
- };
9
- /** The command line of a quick option, whichever form it takes. */
10
- export declare function optCmd(o: QuickOption): string;
11
- /** The contextual description of a quick option, or undefined for a bare command (→ catalog fallback). */
12
- export declare function optDesc(o: QuickOption): string | undefined;
13
- /** The argument portion of a command line ("/publish --all" → "--all", "/audit" → ""). */
14
- export declare function argOf(cmd: string): string;
15
- /**
16
- * Given the currently-offered quick options and the slash command the user just ran, return the
17
- * options that should remain:
18
- * - If the command IS one of the offered suggestions (same command, or an alternative over the same
19
- * argument), the user is following the offered flow → keep the siblings, dropping the executed one
20
- * and its argument-alternatives (SNAG-0049: running "/pull X" must not wipe a pending "/audit").
21
- * - Otherwise the user went off-script (e.g. "/reset" while "/publish --all" was offered) → clear all,
22
- * so a now-irrelevant suggestion can't linger into the new context (SNAG-0127).
23
- */
24
- export declare function nextQuickOptions(prev: QuickOption[], executed: string): QuickOption[];