daily-focus 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/LICENSE +21 -0
- package/README.md +170 -0
- package/SETUP.md +501 -0
- package/dist/audit-4AUZVELT.js +215 -0
- package/dist/chunk-2PLWVW5T.js +987 -0
- package/dist/chunk-6VWWJZKJ.js +27 -0
- package/dist/chunk-EXGTFXNV.js +77 -0
- package/dist/chunk-G4K24I4M.js +425 -0
- package/dist/chunk-NDWZUZJE.js +179 -0
- package/dist/chunk-QKT2FAB5.js +132 -0
- package/dist/chunk-V2UN3JYL.js +140 -0
- package/dist/cli.js +203 -0
- package/dist/init-ZJCI2723.js +122 -0
- package/dist/sample-M7WNKQOV.js +7 -0
- package/dist/seed-7DIDKXT7.js +50 -0
- package/dist/server-B4FWZHS2.js +4814 -0
- package/dist/service-ILBMIZB7.js +240 -0
- package/package.json +66 -0
- package/prompts/README.md +122 -0
- package/prompts/assistant.md +62 -0
- package/prompts/morning-brief-personal.md +442 -0
- package/prompts/morning-brief-work.md +630 -0
- package/public/app.js +5058 -0
- package/public/index.html +36 -0
- package/public/style.css +2515 -0
- package/schema/items.schema.json +99 -0
- package/tools/dfcal/Info.plist +16 -0
- package/tools/dfcal/build.sh +52 -0
- package/tools/dfcal/main.swift +133 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FOCUS_TEMPLATE,
|
|
3
|
+
sourcesTemplate
|
|
4
|
+
} from "./chunk-V2UN3JYL.js";
|
|
5
|
+
import {
|
|
6
|
+
describeLink,
|
|
7
|
+
linkStore
|
|
8
|
+
} from "./chunk-QKT2FAB5.js";
|
|
9
|
+
import {
|
|
10
|
+
loadConfig
|
|
11
|
+
} from "./chunk-G4K24I4M.js";
|
|
12
|
+
import {
|
|
13
|
+
PACKAGED,
|
|
14
|
+
command
|
|
15
|
+
} from "./chunk-6VWWJZKJ.js";
|
|
16
|
+
import "./chunk-EXGTFXNV.js";
|
|
17
|
+
|
|
18
|
+
// scripts/init.ts
|
|
19
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
20
|
+
import { platform } from "node:os";
|
|
21
|
+
import { relative } from "node:path";
|
|
22
|
+
var config = loadConfig();
|
|
23
|
+
var created = 0;
|
|
24
|
+
var linked = 0;
|
|
25
|
+
var failed = 0;
|
|
26
|
+
function ok(label, detail = "") {
|
|
27
|
+
console.log(` \x1B[32m\u2713\x1B[0m ${label}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
28
|
+
}
|
|
29
|
+
function kept(label, detail = "") {
|
|
30
|
+
console.log(` \x1B[2m\xB7\x1B[0m \x1B[2m${label}${detail ? ` \u2014 ${detail}` : ""}\x1B[0m`);
|
|
31
|
+
}
|
|
32
|
+
function bad(label, detail = "") {
|
|
33
|
+
failed++;
|
|
34
|
+
console.log(` \x1B[31m\u2717\x1B[0m ${label}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
35
|
+
}
|
|
36
|
+
function section(title) {
|
|
37
|
+
console.log(`
|
|
38
|
+
\x1B[1m${title}\x1B[0m`);
|
|
39
|
+
}
|
|
40
|
+
async function writeIfAbsent(path, contents, what) {
|
|
41
|
+
try {
|
|
42
|
+
await writeFile(path, contents, { encoding: "utf8", flag: "wx" });
|
|
43
|
+
created++;
|
|
44
|
+
ok(`wrote ${what}`, relative(config.dataDir, path));
|
|
45
|
+
return true;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (error.code === "EEXIST") {
|
|
48
|
+
kept(`${what} already exists, left alone`, relative(config.dataDir, path));
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
bad(`could not write ${what}`, error instanceof Error ? error.message : String(error));
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
console.log(`
|
|
56
|
+
\x1B[1mDaily Focus \u2014 store setup\x1B[0m`);
|
|
57
|
+
console.log(`\x1B[2m${config.dataDir} (${config.profile} profile)\x1B[0m`);
|
|
58
|
+
section("Directories");
|
|
59
|
+
try {
|
|
60
|
+
await mkdir(config.dataDir, { recursive: true });
|
|
61
|
+
await mkdir(config.archiveDir, { recursive: true });
|
|
62
|
+
ok("store and archive directory ready");
|
|
63
|
+
} catch (error) {
|
|
64
|
+
bad("could not create the store", error instanceof Error ? error.message : String(error));
|
|
65
|
+
}
|
|
66
|
+
section("Files you own");
|
|
67
|
+
var wroteFocus = await writeIfAbsent(config.focusFile, FOCUS_TEMPLATE, "the standing objective");
|
|
68
|
+
var wroteSources = await writeIfAbsent(config.sourcesFile, sourcesTemplate(config.profile), "the source list the agent reads");
|
|
69
|
+
section("Files linked from the repo");
|
|
70
|
+
for (const outcome of await linkStore(config)) {
|
|
71
|
+
const shown = describeLink(config, outcome);
|
|
72
|
+
if (outcome.result === "linked") {
|
|
73
|
+
linked++;
|
|
74
|
+
ok(`linked ${outcome.name}`, shown);
|
|
75
|
+
} else if (outcome.result === "kept") kept(`${outcome.name} already linked`, shown);
|
|
76
|
+
else if (outcome.result === "own") kept(`${outcome.name} is a real file, left alone`, "delete it to track the repo again");
|
|
77
|
+
else bad(`could not link ${outcome.name}`, outcome.detail ?? "");
|
|
78
|
+
}
|
|
79
|
+
section("Files you do not own");
|
|
80
|
+
kept("items.json", "the briefing agent writes it; absent reads as no brief yet");
|
|
81
|
+
kept("actions.jsonl", "the dashboard appends to it as you action things");
|
|
82
|
+
kept("sessions.jsonl", "the dashboard appends to it as you run focus sessions");
|
|
83
|
+
kept("assistant.jsonl", "the dashboard appends to it as you ask the assistant for help");
|
|
84
|
+
if (platform() !== "darwin") {
|
|
85
|
+
section("Note");
|
|
86
|
+
kept(
|
|
87
|
+
"idle detection is macOS-only",
|
|
88
|
+
"focus sessions still work; they just fall back to the two-hour backstop instead of closing when you walk away"
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
var next = [];
|
|
92
|
+
if (wroteFocus) next.push(`Edit ${config.focusFile} \u2014 say what you are trying to achieve.`);
|
|
93
|
+
if (wroteSources) next.push(`Edit ${config.sourcesFile} \u2014 say where to look.`);
|
|
94
|
+
var start = platform() === "darwin" ? `\`${command("service")}\` to run the board in the background` : `\`${PACKAGED ? "daily-focus" : "npm start"}\` to open the board`;
|
|
95
|
+
var demo = PACKAGED ? "daily-focus --demo" : "npm run demo";
|
|
96
|
+
section(next.length > 0 ? "Next" : "Nothing to do");
|
|
97
|
+
if (next.length === 0) {
|
|
98
|
+
console.log(
|
|
99
|
+
linked > 0 ? ` The store was already set up. Linked ${linked} ${linked === 1 ? "file" : "files"} to this checkout; nothing else changed.` : " The store was already set up. Nothing was changed."
|
|
100
|
+
);
|
|
101
|
+
console.log(` ${start}, \`${command("audit")}\` to check the current brief.`);
|
|
102
|
+
} else {
|
|
103
|
+
next.forEach((step, i) => console.log(` ${i + 1}. ${step}`));
|
|
104
|
+
if (created > 0) {
|
|
105
|
+
console.log(` ${next.length + 1}. ${start}, and open it to choose the CLI that writes the brief.`);
|
|
106
|
+
console.log(
|
|
107
|
+
`
|
|
108
|
+
\x1B[2mThe two files can be written in the dashboard too: until the first brief,
|
|
109
|
+
Today walks through everything it needs. To look around before an agent
|
|
110
|
+
has run, try \`${demo}\`. It shows sample data from a throwaway store, so
|
|
111
|
+
nothing lands in this one.\x1B[0m`
|
|
112
|
+
);
|
|
113
|
+
} else {
|
|
114
|
+
console.log(
|
|
115
|
+
`
|
|
116
|
+
\x1B[2mThe prompt is a link, so editing it in the repo takes effect on the next run
|
|
117
|
+
with no install step.\x1B[0m`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
console.log();
|
|
122
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sampleBrief
|
|
3
|
+
} from "./chunk-NDWZUZJE.js";
|
|
4
|
+
import {
|
|
5
|
+
Store
|
|
6
|
+
} from "./chunk-2PLWVW5T.js";
|
|
7
|
+
import {
|
|
8
|
+
loadConfig
|
|
9
|
+
} from "./chunk-G4K24I4M.js";
|
|
10
|
+
import {
|
|
11
|
+
command
|
|
12
|
+
} from "./chunk-6VWWJZKJ.js";
|
|
13
|
+
import "./chunk-EXGTFXNV.js";
|
|
14
|
+
|
|
15
|
+
// scripts/seed.ts
|
|
16
|
+
import { writeFile } from "node:fs/promises";
|
|
17
|
+
var brief = sampleBrief();
|
|
18
|
+
var config = loadConfig();
|
|
19
|
+
var force = process.argv.slice(2).includes("--force");
|
|
20
|
+
var store = new Store(config);
|
|
21
|
+
await store.ensureDataDir();
|
|
22
|
+
var isDefaultStore = !process.env.DAILY_FOCUS_DATA?.trim();
|
|
23
|
+
console.log(`Seeding store: ${config.dataDir}${isDefaultStore ? " (the default store \u2014 DAILY_FOCUS_DATA is not set)" : ""}`);
|
|
24
|
+
try {
|
|
25
|
+
await writeFile(config.itemsFile, `${JSON.stringify(brief, null, 2)}
|
|
26
|
+
`, {
|
|
27
|
+
encoding: "utf8",
|
|
28
|
+
flag: force ? "w" : "wx"
|
|
29
|
+
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (error.code !== "EEXIST") throw error;
|
|
32
|
+
console.error(
|
|
33
|
+
[
|
|
34
|
+
"",
|
|
35
|
+
`\x1B[31m\u2717 Refusing to overwrite an existing brief:\x1B[0m`,
|
|
36
|
+
"",
|
|
37
|
+
` ${config.itemsFile}`,
|
|
38
|
+
"",
|
|
39
|
+
"If this is your real store, replacing it destroys the brief and restarts the",
|
|
40
|
+
"ageing on every item. For sample data, use a throwaway store:",
|
|
41
|
+
"",
|
|
42
|
+
` DAILY_FOCUS_DATA=$(mktemp -d) ${command("seed")}`,
|
|
43
|
+
"",
|
|
44
|
+
`To overwrite this file on purpose: ${command("seed", "--force")}`
|
|
45
|
+
].join("\n")
|
|
46
|
+
);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
console.log(`${force ? "Overwrote" : "Wrote"} ${brief.items.length} sample items to ${config.itemsFile}`);
|
|
50
|
+
console.log("Start the dashboard and open it.");
|