document360-writer 0.5.73 → 0.5.75

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.
@@ -5,9 +5,10 @@ export type PendingSummary = {
5
5
  hints: number;
6
6
  requests: number;
7
7
  answers: number;
8
+ directives: number;
8
9
  };
9
- /** Deterministic local counts of queued work (hints + builder messages). Drift is network and is
10
- checked by the agent via d360_sync_status inside the prompt, not here. */
10
+ /** Deterministic local counts of queued work (hints + builder messages + owner directives). Drift is
11
+ network and is checked by the agent via d360_sync_status inside the prompt, not here. */
11
12
  export declare function pendingSummary(cwd: string): PendingSummary;
12
13
  /** A short human phrase for a pending summary, or null when nothing local is queued. */
13
14
  export declare function pendingLine(s: PendingSummary): string | null;
@@ -13,8 +13,13 @@ import type { ReplContext } from '../repl.js';
13
13
  * v6 → make the hand-off VISIBLE + state the boundary: the builder surfaces every hint drop in its
14
14
  * reply (never silently) and NEVER writes/publishes the user docs itself — that's the docs agent's
15
15
  * job. Keeps the dogfood/limitation signal honest and lets a human verify the hand-off happens.
16
+ * v7 → owner→docs directives channel: when the human types `@d360-writer <directive>` in the builder's
17
+ * session (a proactive doc ask like "document /review"), the builder APPENDS it as an `## [open]`
18
+ * block to `.d360-writer/directives.md` (create if absent) and commits — it does NOT action it
19
+ * (writing docs is the docs agent's job; it picks it up on its next /catch-up). The third comms
20
+ * channel, alongside builder hints/messages and portal feedback.
16
21
  */
17
- export declare const DEVHINTS_VERSION = 6;
22
+ export declare const DEVHINTS_VERSION = 7;
18
23
  /**
19
24
  * The committed protocol guide the SOURCE repo's coding agent follows. Self-contained because that
20
25
  * agent has none of d360-writer's context. Two parts: (1) a ONE-TIME architecture brief that onboards
@@ -1,4 +1,4 @@
1
- /** Inputs the decision needs, all already read from disk by the caller. */
1
+ /** Inputs the decision needs, all already read from disk by the caller (see lib/readyState.ts). */
2
2
  export type ReadyInputs = {
3
3
  /** Configured + signed in + scope ok + Claude present. False ⇒ the setup ladder owns the screen. */
4
4
  ready: boolean;
@@ -6,15 +6,14 @@ export type ReadyInputs = {
6
6
  hasDocs: boolean;
7
7
  /** Count of articles in the category map for the active profile. */
8
8
  tracked: number;
9
- /** `pendingLine(pendingSummary())` — e.g. "2 hints, 1 request", or null when nothing's queued. */
9
+ /** Builder queue WITHOUT directives — e.g. "2 hints, 1 request", or null when nothing's queued. */
10
10
  pendingText: string | null;
11
- /** Planned articles (plan.json) not yet written missing/empty files. >0 after an interrupted /write
12
- (e.g. a crash mid-run) or a freshly-pinned plan with bodies still to generate. Drives the "pick up
13
- where you left off" → /write lead so a half-done generation isn't buried under /audit + /pull. */
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. */
14
15
  pendingWrites: number;
15
- /** Tracked articles changed locally since their sync base (local-ahead) — ready to /publish. Computed
16
- cheaply + locally (countLocalAhead, no network). Drives the /publish lead so "ready to publish" isn't
17
- buried under /audit, and stops the briefing falsely reading "all in sync" (dogfood s-244). */
16
+ /** Tracked articles changed locally since their sync base (local-ahead) — ready to /publish (s-244). */
18
17
  localAhead: number;
19
18
  /** Commits on HEAD since the last `/audit` marker (0 when never audited or not a git repo). */
20
19
  behind: number;
@@ -23,11 +22,52 @@ export type ReadyInputs = {
23
22
  /** Active profile/connection name, for the "N articles tracked for X" line. */
24
23
  profileName: string;
25
24
  /** Whether the caller may auto-run /audit (true only at launch — never on the post-turn refresh,
26
- which would loop). When false, a would-be auto-audit degrades to offering /audit in the list. */
25
+ which would loop). When false, a would-be auto-audit degrades to recommending /audit. */
27
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
+ };
40
+ /** The one recommended action. `cmd` fills the ghost and runs on Tab→Enter; `prompt` is a free-text
41
+ ghost (e.g. cold-start "write the docs for this repo"). */
42
+ export type Lead = {
43
+ kind: 'cmd';
44
+ cmd: string;
45
+ reason: string;
46
+ } | {
47
+ kind: 'prompt';
48
+ text: string;
49
+ reason: string;
50
+ };
51
+ /** A true multi-choice — the ONLY thing rendered as a numbered list. */
52
+ export type PickerSpec = {
53
+ title: string;
54
+ options: {
55
+ cmd: string;
56
+ desc: string;
57
+ }[];
58
+ };
59
+ export type Recommendation = {
60
+ /** Conversational transcript briefing (bullets + lead sentence + prose follow-ups), or null when
61
+ there is nothing worth printing (the caller's silent post-turn restores pass this through). */
62
+ note: string | null;
63
+ tone: 'info' | 'warn';
64
+ /** Null in the calm steady state (nothing to push), or when a picker owns the moment. */
65
+ lead: Lead | null;
66
+ /** Set only for true choices (today: the doc genre). */
67
+ picker: PickerSpec | null;
28
68
  };
29
69
  export type ReadyDecision =
30
- /** Not in the ready state — the caller must leave the quick-list/ghost untouched (setup ladder owns it). */
70
+ /** Not in the ready state — the caller must leave ghost/picker untouched (setup ladder owns it). */
31
71
  {
32
72
  kind: 'idle';
33
73
  }
@@ -36,24 +76,18 @@ export type ReadyDecision =
36
76
  kind: 'autoAudit';
37
77
  note: string;
38
78
  }
39
- /** No docs yet: cold-start. `note` is the transcript line, `ghost` the tab-fill, `options`/`title` the list. */
79
+ /** The one recommendation for every other ready state. */
40
80
  | {
41
- kind: 'noDocs';
42
- note: string;
43
- ghost: string;
44
- title: string | null;
45
- options: string[];
46
- }
47
- /** Docs exist: the steady-state next-actions. `note` is the launch transcript block; `title`+`options`
48
- are the durable quick-list (also restored after every turn). */
49
- | {
50
- kind: 'actions';
51
- note: string;
52
- title: string;
53
- options: string[];
81
+ kind: 'recommend';
82
+ rec: Recommendation;
54
83
  };
84
+ /** "⇥ tab to run /devhints · or just ask me anything…" — the input-placeholder hint that carries the
85
+ lead. Null for prompt-style leads (the ghost text itself renders in the input, as before). */
86
+ export declare function ghostHintFor(lead: Lead): string | null;
87
+ /** The one-sentence recommendation — used inside the briefing AND as the REPL's "Next:" line. */
88
+ export declare function leadLine(lead: Lead): string;
55
89
  /**
56
- * Decide the next actions from already-gathered inputs. Pure — no I/O — so it's unit-tested and is the
57
- * one place option order + copy is defined. Mirrors the behavior the launch orientation had inline.
90
+ * Decide the next action from already-gathered inputs. Pure — no I/O — so it's unit-tested and is the
91
+ * one place the ladder + copy live.
58
92
  */
59
93
  export declare function decideReadyActions(i: ReadyInputs): ReadyDecision;
@@ -0,0 +1,19 @@
1
+ import type { ReadyInputs } from './nextActions.js';
2
+ /** Should the first-run nudge point the user at /scope? True when scope is unset but a
3
+ large container exists, or when a bare large-container folder is the whole scope. */
4
+ export declare function scopeLooksTooBroad(cwd: string, scope: string[] | undefined): boolean;
5
+ /** True when the repo is ESTABLISHED — past first-run: docs already written, articles tracked, or a
6
+ builder hand-off (devhints) in place. A smart agent reads this state: first-run nudges like /scope
7
+ must NEVER fire on a mature project that has been documenting for weeks (s-228). Cheap on-disk reads. */
8
+ export declare function projectIsEstablished(cwd: string, profileName?: string): boolean;
9
+ /**
10
+ * Read every signal the brain ranks (see the ladder in nextActions.ts) from disk. Returns null when
11
+ * the repo has no config (or anything is unreadable) — the caller treats that as `idle` (the setup
12
+ * ladder owns the screen). `claudeMissing` and `genreUnknown` are caller-known state (the auth
13
+ * classification and the launch genre probe live with the UI), passed through untouched.
14
+ */
15
+ export declare function gatherReadyInputs(cwd: string, profileName: string | undefined, opts: {
16
+ claudeMissing: boolean;
17
+ allowAutoAudit: boolean;
18
+ genreUnknown: boolean;
19
+ }): ReadyInputs | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "document360-writer",
3
- "version": "0.5.73",
3
+ "version": "0.5.75",
4
4
  "description": "Standalone documentation agent CLI. Reads your code, writes your docs. Specialized for Document360 publishing.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -34,7 +34,7 @@
34
34
  "@inquirer/prompts": "^8.4.3",
35
35
  "commander": "^14.0.3",
36
36
  "diff": "^8.0.4",
37
- "document360-engine": "^0.2.97",
37
+ "document360-engine": "^0.2.100",
38
38
  "ink": "^5.2.1",
39
39
  "picocolors": "^1.1.1",
40
40
  "react": "^18.3.1",