@chenpengfei/daily-brief 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.
Files changed (49) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +21 -0
  3. package/README.md +28 -0
  4. package/config/sources.example.yaml +20 -0
  5. package/dist/src/adapters/fixture.js +70 -0
  6. package/dist/src/adapters/github-trending.js +183 -0
  7. package/dist/src/adapters/index.js +5 -0
  8. package/dist/src/adapters/rss.js +156 -0
  9. package/dist/src/adapters/types.js +1 -0
  10. package/dist/src/adapters/x.js +115 -0
  11. package/dist/src/agent/daily-brief-agent.js +350 -0
  12. package/dist/src/agent/index.js +10 -0
  13. package/dist/src/agent/model-runtime-config.js +221 -0
  14. package/dist/src/agent/model-stage-runtime.js +63 -0
  15. package/dist/src/agent/signal-narrative.js +247 -0
  16. package/dist/src/agent/signal-selection-ranking.js +276 -0
  17. package/dist/src/agent/source-grounding-audit.js +148 -0
  18. package/dist/src/agent/source-grounding-repair.js +159 -0
  19. package/dist/src/agent/source-item-understanding.js +206 -0
  20. package/dist/src/agent/stage-contracts.js +205 -0
  21. package/dist/src/agent/stage-runner.js +66 -0
  22. package/dist/src/brief/daily-brief.js +234 -0
  23. package/dist/src/brief/index.js +1 -0
  24. package/dist/src/cli.js +531 -0
  25. package/dist/src/collection/collect.js +67 -0
  26. package/dist/src/collection/index.js +1 -0
  27. package/dist/src/config/credential-store.js +169 -0
  28. package/dist/src/config/date-key.js +25 -0
  29. package/dist/src/config/index.js +5 -0
  30. package/dist/src/config/model-config.js +123 -0
  31. package/dist/src/config/paths.js +20 -0
  32. package/dist/src/config/source-registry.js +48 -0
  33. package/dist/src/discord/delivery.js +84 -0
  34. package/dist/src/discord/index.js +1 -0
  35. package/dist/src/domain/index.js +2 -0
  36. package/dist/src/domain/source-item.js +21 -0
  37. package/dist/src/domain/source.js +93 -0
  38. package/dist/src/storage/agent-run-artifact.js +44 -0
  39. package/dist/src/storage/brief-archive.js +17 -0
  40. package/dist/src/storage/index.js +3 -0
  41. package/dist/src/storage/source-item-store.js +63 -0
  42. package/dist/src/workflow/index.js +1 -0
  43. package/dist/src/workflow/status.js +95 -0
  44. package/docs/operations.md +74 -0
  45. package/docs/release-workflow.md +220 -0
  46. package/docs/user-manual.md +146 -0
  47. package/package.json +65 -0
  48. package/templates/daily-brief.md +9 -0
  49. package/templates/discord-notification.md +7 -0
@@ -0,0 +1,63 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { formatDateKey, resolveDailyBriefPaths } from "../config/index.js";
4
+ export function sourceItemStorePath(date, root = resolveDailyBriefPaths().sourceItemRoot, dateKey) {
5
+ const datePart = dateKey ?? formatDateKey(date);
6
+ const [year, month] = datePart.split("-");
7
+ if (!year || !month) {
8
+ throw new Error(`Invalid Source Item Store date: ${datePart}`);
9
+ }
10
+ return join(root, year, month, `${datePart}.jsonl`);
11
+ }
12
+ export async function appendSourceItems(items, date, root = resolveDailyBriefPaths().sourceItemRoot, dateKey) {
13
+ const path = sourceItemStorePath(date, root, dateKey);
14
+ const existing = await readSourceItems(date, root, dateKey);
15
+ const seenIds = new Set(existing.map((item) => item.id));
16
+ const seenHashes = new Set(existing.map((item) => item.contentHash));
17
+ const written = [];
18
+ const skipped = [];
19
+ for (const item of items) {
20
+ if (seenIds.has(item.id) || seenHashes.has(item.contentHash)) {
21
+ skipped.push(item);
22
+ continue;
23
+ }
24
+ seenIds.add(item.id);
25
+ seenHashes.add(item.contentHash);
26
+ written.push(item);
27
+ }
28
+ if (written.length > 0) {
29
+ await mkdir(dirname(path), { recursive: true });
30
+ const next = [...existing, ...written].map((item) => JSON.stringify(item)).join("\n");
31
+ await writeFile(path, `${next}\n`, "utf8");
32
+ }
33
+ return { path, written, skipped };
34
+ }
35
+ export async function readSourceItems(date, root = resolveDailyBriefPaths().sourceItemRoot, dateKey) {
36
+ const path = sourceItemStorePath(date, root, dateKey);
37
+ let contents;
38
+ try {
39
+ contents = await readFile(path, "utf8");
40
+ }
41
+ catch (error) {
42
+ if (isNodeError(error) && error.code === "ENOENT") {
43
+ return [];
44
+ }
45
+ throw error;
46
+ }
47
+ return contents
48
+ .split("\n")
49
+ .filter((line) => line.trim().length > 0)
50
+ .map((line, index) => parseSourceItemLine(line, path, index + 1));
51
+ }
52
+ function isNodeError(error) {
53
+ return error instanceof Error && "code" in error;
54
+ }
55
+ function parseSourceItemLine(line, path, lineNumber) {
56
+ try {
57
+ return JSON.parse(line);
58
+ }
59
+ catch (error) {
60
+ const cause = error instanceof Error ? `: ${error.message}` : "";
61
+ throw new Error(`${path} line ${lineNumber} contains malformed Source Item JSON${cause}`);
62
+ }
63
+ }
@@ -0,0 +1 @@
1
+ export * from "./status.js";
@@ -0,0 +1,95 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { loadSourceRegistry, resolveDailyBriefPaths } from "../config/index.js";
4
+ export function evaluateWorkflowStatus(input) {
5
+ if (input.coreFailure) {
6
+ return {
7
+ health: "core-failure",
8
+ message: input.coreFailure.message,
9
+ materialPartialFailures: [],
10
+ coreFailure: input.coreFailure
11
+ };
12
+ }
13
+ if (!input.briefGenerated) {
14
+ return {
15
+ health: "core-failure",
16
+ message: "Daily Brief generation did not produce an archiveable Brief.",
17
+ materialPartialFailures: [],
18
+ coreFailure: {
19
+ kind: "brief-generation-unavailable",
20
+ message: "Daily Brief generation did not produce an archiveable Brief."
21
+ }
22
+ };
23
+ }
24
+ const materialPartialFailures = input.collectionResults
25
+ .filter((result) => result.status === "failed")
26
+ .map((result) => `${result.sourceId}: ${result.reason ?? "Unknown failure"}`)
27
+ .filter(isMaterialPartialFailure);
28
+ if (materialPartialFailures.length > 0) {
29
+ return {
30
+ health: "partial-failure",
31
+ message: "Daily Brief generated with material Source Coverage gaps.",
32
+ materialPartialFailures
33
+ };
34
+ }
35
+ return {
36
+ health: "success",
37
+ message: "Daily Brief workflow completed successfully.",
38
+ materialPartialFailures: []
39
+ };
40
+ }
41
+ export function createCoreWorkflowFailureNotification(failure) {
42
+ return [
43
+ "Daily Brief failed",
44
+ "",
45
+ `Core Workflow Failure: ${failure.kind}`,
46
+ failure.message,
47
+ "",
48
+ "No Daily Brief was generated, because sending a false or unsupported Brief would break trust."
49
+ ].join("\n");
50
+ }
51
+ export async function getOperationalStatus(options = {}) {
52
+ const date = options.date ?? new Date();
53
+ try {
54
+ await loadSourceRegistry(options.sourceRegistryPath);
55
+ }
56
+ catch (error) {
57
+ return evaluateWorkflowStatus({
58
+ collectionResults: [],
59
+ briefGenerated: false,
60
+ coreFailure: {
61
+ kind: "unreadable-source-registry",
62
+ message: error instanceof Error ? error.message : String(error)
63
+ }
64
+ });
65
+ }
66
+ const archivePath = briefArchivePath(date, options.archiveRoot ?? resolveDailyBriefPaths().briefArchiveRoot, options.dateKey);
67
+ try {
68
+ await readFile(archivePath, "utf8");
69
+ }
70
+ catch {
71
+ return {
72
+ health: "partial-failure",
73
+ message: `No Daily Brief archived for ${options.dateKey ?? date.toISOString().slice(0, 10)} yet.`,
74
+ materialPartialFailures: []
75
+ };
76
+ }
77
+ return {
78
+ health: "success",
79
+ message: `Daily Brief archive exists for ${options.dateKey ?? date.toISOString().slice(0, 10)}.`,
80
+ materialPartialFailures: []
81
+ };
82
+ }
83
+ function isMaterialPartialFailure(message) {
84
+ const normalized = message.toLowerCase();
85
+ const nonMaterialPatterns = ["missing transcript", "transcript missing", "rate limit", "parse failure"];
86
+ return !nonMaterialPatterns.some((pattern) => normalized.includes(pattern));
87
+ }
88
+ function briefArchivePath(date, root, dateKey) {
89
+ const datePart = dateKey ?? date.toISOString().slice(0, 10);
90
+ const [year, month] = datePart.split("-");
91
+ if (!year || !month) {
92
+ throw new Error(`Invalid archive date: ${datePart}`);
93
+ }
94
+ return join(root, year, month, `${datePart}.md`);
95
+ }
@@ -0,0 +1,74 @@
1
+ # Daily Brief Operations
2
+
3
+ For end-user installation, setup, upgrade, and troubleshooting, see `docs/user-manual.md`. For maintainer release gates and publication steps, see `docs/release-workflow.md`.
4
+
5
+ Installed usage uses the `daily-brief` binary:
6
+
7
+ ```bash
8
+ daily-brief setup
9
+ daily-brief run-once --date 2026-05-28
10
+ daily-brief status
11
+ ```
12
+
13
+ Development usage from a repository checkout uses `npm run cli --`:
14
+
15
+ ```bash
16
+ npm run cli -- collect
17
+ npm run cli -- generate
18
+ npm run cli -- deliver
19
+ npm run cli -- status
20
+ npm run cli -- run-once
21
+ ```
22
+
23
+ Expected local cadence:
24
+
25
+ - 06:00 local time: run `collect`.
26
+ - 07:00 local time: run `run-once` or `generate` followed by `deliver`.
27
+
28
+ Scheduler integration is intentionally deployment-neutral. A local cron, launchd job, systemd timer, GitHub Actions workflow, or another scheduler can call the commands above; the repository does not bind the MVP to a specific host.
29
+
30
+ `run-once` executes collection, brief generation/archive, and Discord delivery in order. Source Item writes are deduplicated by Source Item id and content hash within the daily JSONL store, and Daily Brief generation merges repeated mentions into one multi-citation Signal, so rerunning the workflow for the same Collection Window does not duplicate equivalent Signals.
31
+
32
+ ## Manual run
33
+
34
+ For a one-off Manual Run against the configured Sources:
35
+
36
+ ```bash
37
+ npm run cli -- sources list
38
+ npm run cli -- run-once
39
+ npm run cli -- status
40
+ ```
41
+
42
+ `sources list` confirms which Sources are enabled, including the default `github-trending-daily` Source. `run-once` performs collection, brief generation, archive writing, and Discord Delivery once. `status` reports operational health after the run.
43
+
44
+ Discord Delivery uses `DISCORD_WEBHOOK_URL` from the shell environment or local `.env`; `.env` is loaded automatically by the Operational CLI and does not need to be sourced manually.
45
+
46
+ ## Runtime configuration
47
+
48
+ When the Operational CLI starts, it loads local `.env` values from the repository root if the file exists. Existing shell environment variables take precedence over `.env` values. The `.env` file is ignored by Git; use `.env.example` as the non-secret template.
49
+
50
+ Installed operational paths can be adjusted through environment variables:
51
+
52
+ - `DAILY_BRIEF_HOME`: user config directory. Defaults to `~/.daily-brief`.
53
+ - `DAILY_BRIEF_DATA_HOME`: generated data directory. Defaults to `~/.daily-brief/data`.
54
+ - `DAILY_BRIEF_DISCORD_TEMPLATE_PATH`: optional Discord notification template override. Defaults to the packaged Discord notification template.
55
+ - `DISCORD_WEBHOOK_URL`: Discord webhook URL. If unset, Discord Delivery is skipped with an explicit reason.
56
+
57
+ Model/provider and delivery configuration should normally be managed with:
58
+
59
+ ```bash
60
+ daily-brief model configure
61
+ daily-brief model status
62
+ daily-brief delivery configure --enabled true --webhook-url <url>
63
+ daily-brief delivery status
64
+ ```
65
+
66
+ Secrets live in `~/.daily-brief/auth.json` or environment variables, never in `sources.yaml` or committed project files. Installed CLI configuration does not accept the faux provider; faux is reserved for tests through an explicit test-only runtime gate.
67
+
68
+ `run-once` does not archive a normal Daily Brief when every enabled Source fails or when no Source Items exist for the requested date. It reports a Core Workflow Failure instead, because a false low-signal brief would hide collection failure.
69
+
70
+ ## GitHub Trending collection
71
+
72
+ `github-trending-daily` monitors the site-wide daily GitHub Trending page. The Fetch Adapter treats each listed repository as a Trending Repository Observation and keeps parsing intentionally narrow: repository link, short description, stars/forks when visible, and stars today when visible. It does not fetch README files or repository detail APIs.
73
+
74
+ The adapter relies on focused HTML parsing plus regression tests for observed GitHub page changes. A GitHub Trending parsing failure is handled as a Source-level collection failure; it should not silently fall back to stale trend-list data.
@@ -0,0 +1,220 @@
1
+ # Formal Release Workflow
2
+
3
+ Formal Releases publish both a GitHub Release and the npm package `@chenpengfei/daily-brief`. The installed command remains `daily-brief`.
4
+
5
+ The workflow has three human-triggered Release Gates:
6
+
7
+ 1. Agent Release Preparation Gate
8
+ 2. Agent Release Review Gate
9
+ 3. Human Release Gate
10
+
11
+ Publication commands are never run before the Human Release Gate.
12
+
13
+ ## Release Invariants
14
+
15
+ - The Release Version uses SemVer: npm/package uses `X.Y.Z`, while GitHub tag and release title use `vX.Y.Z`.
16
+ - Release Pull Requests normally prepare release materials only: package metadata, version, Changelog, User Manual, release workflow documentation, and evidence.
17
+ - Release Pull Requests should not include ordinary product code fixes.
18
+ - Product-code Release Blockers normally leave the release line and are handled through a separate issue or fix PR.
19
+ - A minimal Release-Blocking Fix may remain in the Release Pull Request only when it is required to prove installability or publishability for the same release, is explicitly recorded in the Release Checklist Issue and Release Pull Request, and is called out for focused Agent Release Review.
20
+ - Published tags and npm versions are immutable. Post-Release Incidents use documentation and patch releases instead of moved tags or silent rollback.
21
+
22
+ ## Gate 1: Agent Release Preparation
23
+
24
+ Trigger this gate by asking an Agent to prepare release `vX.Y.Z`.
25
+
26
+ The Agent must:
27
+
28
+ - Create or update the Release Checklist Issue.
29
+ - Create a `release/vX.Y.Z` branch and Release Pull Request.
30
+ - Update `package.json` and `package-lock.json` to the Release Version and package metadata.
31
+ - Update `CHANGELOG.md` with user-visible changes, installation or upgrade notes, and known limitations.
32
+ - Update `docs/user-manual.md` for any user-facing behavior changes.
33
+ - Update `docs/release-workflow.md` if the release process changes.
34
+ - Run `npm run release:check`.
35
+ - Run `npm run release:publish:dry-run`.
36
+ - Run the isolated Release Install Smoke Test.
37
+ - Record command evidence and any Release Blockers in the Release Checklist Issue and Release Pull Request.
38
+
39
+ The Release Check Command runs:
40
+
41
+ ```bash
42
+ npm test
43
+ npm run typecheck
44
+ npm run build
45
+ npm pack --dry-run
46
+ ```
47
+
48
+ The npm publish dry-run verifies scoped package publication metadata without publishing:
49
+
50
+ ```bash
51
+ npm run release:publish:dry-run
52
+ ```
53
+
54
+ The Release Install Smoke Test must use temporary npm and Daily Brief paths:
55
+
56
+ ```bash
57
+ npm pack
58
+ npm install --prefix /tmp/daily-brief-smoke -g ./chenpengfei-daily-brief-X.Y.Z.tgz --no-audit --no-fund
59
+ DAILY_BRIEF_HOME=/tmp/daily-brief-home \
60
+ DAILY_BRIEF_DATA_HOME=/tmp/daily-brief-data \
61
+ /tmp/daily-brief-smoke/bin/daily-brief --help
62
+ DAILY_BRIEF_HOME=/tmp/daily-brief-home \
63
+ DAILY_BRIEF_DATA_HOME=/tmp/daily-brief-data \
64
+ /tmp/daily-brief-smoke/bin/daily-brief setup
65
+ ```
66
+
67
+ Use a unique temporary directory for real runs. Do not install into the maintainer's real global npm prefix or real `~/.daily-brief` during the smoke test.
68
+
69
+ If a product-code blocker appears, stop the release preparation and classify it:
70
+
71
+ - If the blocker is not required to prove this release's installability or publishability, record the blocker, create or link the fix issue, and restart this gate after the fix is merged.
72
+ - If the blocker is a minimal Release-Blocking Fix, keep it in the Release Pull Request only after recording the reason, affected files, extra tests, smoke evidence, and review focus in the Release Checklist Issue and Release Pull Request.
73
+
74
+ Release-Blocking Fixes are exceptions, not a way to bundle unrelated behavior change into a release. The Agent Release Review Gate must review the exception explicitly.
75
+
76
+ ## Gate 2: Agent Release Review
77
+
78
+ Trigger this gate in an independent Agent context after the Release Pull Request is ready.
79
+
80
+ The reviewing Agent must use a review stance and inspect:
81
+
82
+ - Release Checklist Issue evidence.
83
+ - Release Pull Request diff.
84
+ - `package.json` and `package-lock.json`.
85
+ - `CHANGELOG.md`.
86
+ - `docs/user-manual.md`.
87
+ - `docs/release-workflow.md`.
88
+ - Release CI Workflow result.
89
+ - Local evidence for `npm run release:check`.
90
+ - Local evidence for the Release Install Smoke Test.
91
+ - Any Release-Blocking Fix exception, including affected files, scope justification, targeted tests, smoke evidence, and whether a separate fix PR would be safer before release.
92
+
93
+ The reviewing Agent should report blocking findings first, with file and line references when possible. It may recommend approval or request fixes, but it must not publish the release or approve its own preparation work.
94
+
95
+ ## Gate 3: Human Release
96
+
97
+ Only the maintainer can pass the Human Release Gate.
98
+
99
+ Before publishing, verify:
100
+
101
+ - Release Pull Request is merged.
102
+ - Local `main` matches `origin/main`.
103
+ - Release CI Workflow is green on the merged state.
104
+ - Agent Release Review Gate recommends approval or all findings are resolved.
105
+ - npm credentials and GitHub credentials are available to the maintainer.
106
+ - npm package state has been checked with `npm view @chenpengfei/daily-brief version`; first release should be unpublished, and later releases should show a version lower than the target Release Version.
107
+ - release notes have been prepared from the matching `CHANGELOG.md` entry.
108
+
109
+ Run the Human Release helper in preflight mode first:
110
+
111
+ ```bash
112
+ npm run release:human -- --version X.Y.Z
113
+ ```
114
+
115
+ After the maintainer confirms the preflight output, publish with explicit confirmation:
116
+
117
+ ```bash
118
+ npm run release:human -- --version X.Y.Z --publish --yes --issue <release-checklist-issue-number>
119
+ ```
120
+
121
+ The GitHub Release notes should be derived from the `CHANGELOG.md` entry and include:
122
+
123
+ - User-visible changes.
124
+ - Installation or upgrade notes.
125
+ - Known limitations.
126
+ - Installation command: `npm install -g @chenpengfei/daily-brief`.
127
+
128
+ After publication, verify public installation:
129
+
130
+ ```bash
131
+ npm view @chenpengfei/daily-brief version
132
+ npm install --prefix /tmp/daily-brief-public-smoke -g @chenpengfei/daily-brief@X.Y.Z --no-audit --no-fund
133
+ /tmp/daily-brief-public-smoke/bin/daily-brief --help
134
+ ```
135
+
136
+ The Human Release helper performs this public installation verification after `npm publish` and GitHub Release creation.
137
+
138
+ Record the npm version, GitHub Release URL, tag, and public install verification in the Release Checklist Issue.
139
+
140
+ ## Post-Release Incidents
141
+
142
+ If npm publish succeeds but GitHub Release creation fails, continue by fixing GitHub Release creation for the same tag and version.
143
+
144
+ If GitHub Release is public but install verification fails, record the incident in the Release Checklist Issue, update release notes when relevant, create a fix issue, and publish a patch Release Version after the fix. Do not move the tag or unpublish the npm package unless the release exposed a severe secret or credential issue.
145
+
146
+ ## Release Checklist Issue Template
147
+
148
+ ```md
149
+ # Release vX.Y.Z
150
+
151
+ ## Scope
152
+
153
+ - Release Version: X.Y.Z
154
+ - GitHub tag: vX.Y.Z
155
+ - npm package: @chenpengfei/daily-brief
156
+ - Release Pull Request:
157
+
158
+ ## Gate 1: Agent Release Preparation
159
+
160
+ - [ ] Release branch created: release/vX.Y.Z
161
+ - [ ] Release Pull Request opened
162
+ - [ ] package metadata updated
163
+ - [ ] CHANGELOG.md updated
164
+ - [ ] docs/user-manual.md updated
165
+ - [ ] docs/release-workflow.md updated if needed
166
+ - [ ] npm run release:check completed
167
+ - [ ] npm run release:publish:dry-run completed
168
+ - [ ] Release Install Smoke Test completed with temporary npm prefix and Daily Brief homes
169
+ - [ ] Release Blockers recorded or confirmed absent
170
+ - [ ] Release-Blocking Fix exceptions recorded or confirmed absent
171
+
172
+ ### Preparation Evidence
173
+
174
+ - release:check:
175
+ - publish dry-run:
176
+ - npm pack output:
177
+ - npm package state before publish:
178
+ - install smoke test:
179
+ - Release-Blocking Fix exception:
180
+ - git status:
181
+ - notes:
182
+
183
+ ## Gate 2: Agent Release Review
184
+
185
+ - [ ] Independent Agent review requested
186
+ - [ ] Release Pull Request reviewed
187
+ - [ ] Release Checklist evidence reviewed
188
+ - [ ] Release CI Workflow result reviewed
189
+ - [ ] Release-Blocking Fix exceptions reviewed or confirmed absent
190
+ - [ ] Review recommendation recorded
191
+
192
+ ### Review Findings
193
+
194
+ - Blocking:
195
+ - Non-blocking:
196
+ - Recommendation:
197
+
198
+ ## Gate 3: Human Release
199
+
200
+ - [ ] Release Pull Request merged
201
+ - [ ] main matches origin/main
202
+ - [ ] npm package state checked
203
+ - [ ] GitHub Release notes file prepared
204
+ - [ ] tag pushed: vX.Y.Z
205
+ - [ ] npm publish completed
206
+ - [ ] GitHub Release created
207
+ - [ ] public install verification completed
208
+
209
+ ### Publication Evidence
210
+
211
+ - npm version:
212
+ - npm package state before publish:
213
+ - GitHub Release URL:
214
+ - tag:
215
+ - public install:
216
+
217
+ ## Post-Release Incidents
218
+
219
+ - None known.
220
+ ```
@@ -0,0 +1,146 @@
1
+ # Daily Brief User Manual
2
+
3
+ Daily Brief is an installed command-line tool for generating a recurring Agent architecture and AI Coding brief from Sources you explicitly configure.
4
+
5
+ ## Install
6
+
7
+ Daily Brief is distributed as the npm package `@chenpengfei/daily-brief` and installs the `daily-brief` command.
8
+
9
+ ```bash
10
+ npm install -g @chenpengfei/daily-brief
11
+ daily-brief --help
12
+ ```
13
+
14
+ Daily Brief requires Node.js 22 or newer.
15
+
16
+ ## First Setup
17
+
18
+ Run setup after installing the package:
19
+
20
+ ```bash
21
+ daily-brief setup
22
+ ```
23
+
24
+ Setup creates user configuration and generated-data directories, initializes the Source Registry from the packaged example, prepares credential storage, and reports readiness. Setup does not collect Sources, call an LLM, generate a Daily Brief, or send a delivery notification.
25
+
26
+ By default, configuration files live under `~/.daily-brief/`, and generated data lives under `~/.daily-brief/data/`.
27
+
28
+ ## Configure Sources
29
+
30
+ Sources are manually controlled. The agent processes configured Sources, but it does not autonomously add or remove them.
31
+
32
+ ```bash
33
+ daily-brief sources list
34
+ daily-brief sources edit
35
+ daily-brief sources validate
36
+ daily-brief sources enable <source-id>
37
+ daily-brief sources disable <source-id>
38
+ ```
39
+
40
+ Use `sources validate` after editing the Source Registry.
41
+
42
+ ## Configure Model Access
43
+
44
+ Agent Stages require an LLM Provider Configuration before real Daily Brief generation.
45
+
46
+ ```bash
47
+ daily-brief model configure
48
+ daily-brief model status
49
+ daily-brief model login
50
+ daily-brief model logout
51
+ ```
52
+
53
+ Credentials are stored in the Model Credential Store or environment variables. Do not put secrets in `sources.yaml` or committed project files.
54
+
55
+ ## Configure Delivery
56
+
57
+ Discord Delivery is optional. Configure it when you want generated Daily Brief notifications pushed to Discord.
58
+
59
+ ```bash
60
+ daily-brief delivery configure --enabled true --webhook-url <url>
61
+ daily-brief delivery status
62
+ daily-brief delivery test
63
+ ```
64
+
65
+ If Discord Delivery is disabled or no webhook is configured, generation can still run and will report skipped delivery explicitly.
66
+
67
+ ## Run Daily Brief
68
+
69
+ For a full manual run:
70
+
71
+ ```bash
72
+ daily-brief run-once
73
+ ```
74
+
75
+ For separated operational steps:
76
+
77
+ ```bash
78
+ daily-brief collect
79
+ daily-brief generate
80
+ daily-brief deliver
81
+ daily-brief status
82
+ ```
83
+
84
+ The expected local cadence is collection at 06:00 and generation or delivery at 07:00 local time. Daily Brief does not include a built-in scheduler; use an external scheduler to invoke the CLI.
85
+
86
+ ## Inspect Status
87
+
88
+ Use status after setup, after manual runs, or when diagnosing failures:
89
+
90
+ ```bash
91
+ daily-brief status
92
+ ```
93
+
94
+ Status output is the operational surface for collection, analysis, archive, and delivery health.
95
+
96
+ ## Paths and Environment
97
+
98
+ The installed CLI uses user-home paths by default:
99
+
100
+ - `DAILY_BRIEF_HOME`: configuration directory, default `~/.daily-brief`.
101
+ - `DAILY_BRIEF_DATA_HOME`: generated data directory, default `~/.daily-brief/data`.
102
+ - `DAILY_BRIEF_DISCORD_TEMPLATE_PATH`: optional Discord notification template override.
103
+ - `DISCORD_WEBHOOK_URL`: optional Discord webhook URL.
104
+
105
+ Repository checkouts may use a local `.env`; installed usage should normally rely on user configuration and credential commands.
106
+
107
+ ## Upgrade
108
+
109
+ Upgrade the installed package through npm:
110
+
111
+ ```bash
112
+ npm install -g @chenpengfei/daily-brief@latest
113
+ daily-brief status
114
+ ```
115
+
116
+ Run `daily-brief setup` again when release notes or status output indicate that configuration needs to be refreshed. Setup preserves existing files unless an overwrite or force behavior is explicitly selected.
117
+
118
+ ## Troubleshooting
119
+
120
+ If setup has not run, run:
121
+
122
+ ```bash
123
+ daily-brief setup
124
+ ```
125
+
126
+ If Sources are not collected, run:
127
+
128
+ ```bash
129
+ daily-brief sources validate
130
+ daily-brief sources list
131
+ ```
132
+
133
+ If model access fails, run:
134
+
135
+ ```bash
136
+ daily-brief model status
137
+ ```
138
+
139
+ If Discord delivery fails or is skipped, run:
140
+
141
+ ```bash
142
+ daily-brief delivery status
143
+ daily-brief delivery test
144
+ ```
145
+
146
+ If a run cannot honestly produce a Daily Brief, the CLI reports a Core Workflow Failure rather than archiving a false normal Daily Brief.
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@chenpengfei/daily-brief",
3
+ "version": "0.1.0",
4
+ "description": "Agent-driven daily brief CLI for manually curated Agent architecture and AI Coding sources.",
5
+ "private": false,
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/chenpengfei/daily-brief#readme",
9
+ "bugs": {
10
+ "url": "https://github.com/chenpengfei/daily-brief/issues"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/chenpengfei/daily-brief.git"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "keywords": [
20
+ "agent",
21
+ "daily-brief",
22
+ "cli",
23
+ "ai-coding",
24
+ "briefing"
25
+ ],
26
+ "files": [
27
+ "dist/src",
28
+ "config/sources.example.yaml",
29
+ "templates",
30
+ "docs/operations.md",
31
+ "docs/user-manual.md",
32
+ "docs/release-workflow.md",
33
+ "README.md",
34
+ "CHANGELOG.md",
35
+ "LICENSE"
36
+ ],
37
+ "bin": {
38
+ "daily-brief": "dist/src/cli.js"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc -p tsconfig.json",
42
+ "cli": "tsx src/cli.ts",
43
+ "prepack": "npm run build",
44
+ "release:check": "npm test && npm run typecheck && npm run build && npm pack --dry-run",
45
+ "release:human": "node scripts/human-release.mjs",
46
+ "release:publish:dry-run": "npm publish --dry-run --access public",
47
+ "test": "vitest run",
48
+ "typecheck": "tsc -p tsconfig.json --noEmit"
49
+ },
50
+ "dependencies": {
51
+ "@earendil-works/pi-agent-core": "^0.76.0",
52
+ "@earendil-works/pi-ai": "^0.76.0",
53
+ "fast-xml-parser": "^5.2.2",
54
+ "yaml": "^2.8.0"
55
+ },
56
+ "devDependencies": {
57
+ "@types/node": "^22.15.24",
58
+ "tsx": "^4.19.4",
59
+ "typescript": "^5.8.3",
60
+ "vitest": "^3.1.4"
61
+ },
62
+ "engines": {
63
+ "node": ">=22"
64
+ }
65
+ }
@@ -0,0 +1,9 @@
1
+ # Daily Brief -- {{date}}
2
+
3
+ ## Executive Summary
4
+
5
+ ## Top Signals
6
+
7
+ ## Source Coverage
8
+
9
+ ## Sources
@@ -0,0 +1,7 @@
1
+ Daily Brief -- {{date}}
2
+
3
+ 今日重点:
4
+ {{summary_bullets}}
5
+
6
+ 完整简报:
7
+ {{brief_path}}