@forwardimpact/outpost 3.12.1 → 3.13.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/package.json +3 -2
- package/src/kb-manager.js +58 -5
- package/src/kb-validator.js +762 -0
- package/src/outpost.js +73 -8
- package/templates/.claude/agents/chief-of-staff.md +14 -6
- package/templates/.claude/agents/concierge.md +9 -2
- package/templates/.claude/agents/head-hunter.md +9 -2
- package/templates/.claude/agents/librarian.md +11 -4
- package/templates/.claude/agents/postman.md +9 -2
- package/templates/.claude/agents/recruiter.md +9 -2
- package/templates/.claude/skills/anarlog-follow/SKILL.md +53 -29
- package/templates/.claude/skills/anarlog-follow/references/sessions.md +52 -0
- package/templates/.claude/skills/anarlog-process/SKILL.md +88 -45
- package/templates/.claude/skills/anarlog-process/references/extraction.md +19 -11
- package/templates/.claude/skills/anarlog-process/references/sessions.md +92 -58
- package/templates/.claude/skills/anarlog-process/scripts/scan.mjs +404 -163
- package/templates/.claude/skills/candidate-report/SKILL.md +12 -9
- package/templates/.claude/skills/changelog/SKILL.md +106 -56
- package/templates/.claude/skills/deck-create/SKILL.md +60 -2
- package/templates/.claude/skills/deck-review/SKILL.md +4 -1
- package/templates/.claude/skills/deck-summarize/SKILL.md +6 -2
- package/templates/.claude/skills/deck-summarize/references/brief-template.md +1 -1
- package/templates/.claude/skills/doc-collab/SKILL.md +16 -11
- package/templates/.claude/skills/doc-create/SKILL.md +6 -3
- package/templates/.claude/skills/draft-emails/SKILL.md +31 -25
- package/templates/.claude/skills/draft-emails/references/template.md +1 -1
- package/templates/.claude/skills/draft-emails/scripts/scan-emails.mjs +14 -8
- package/templates/.claude/skills/draft-emails/scripts/send-email.mjs +9 -3
- package/templates/.claude/skills/extract-entities/SKILL.md +17 -16
- package/templates/.claude/skills/extract-entities/references/TEMPLATES.md +2 -1
- package/templates/.claude/skills/extract-entities/references/conditions.md +6 -5
- package/templates/.claude/skills/extract-entities/references/links.md +34 -10
- package/templates/.claude/skills/extract-entities/references/recruitment.md +15 -10
- package/templates/.claude/skills/extract-entities/references/resolution.md +1 -1
- package/templates/.claude/skills/extract-entities/references/sources.md +1 -1
- package/templates/.claude/skills/extract-entities/references/templates-conditions.md +10 -4
- package/templates/.claude/skills/extract-entities/references/templates-people-orgs.md +29 -10
- package/templates/.claude/skills/extract-entities/references/templates-priorities.md +8 -2
- package/templates/.claude/skills/extract-entities/references/templates-projects-topics.md +19 -7
- package/templates/.claude/skills/meeting-prep/SKILL.md +23 -18
- package/templates/.claude/skills/organize-files/SKILL.md +3 -0
- package/templates/.claude/skills/person-identify/SKILL.md +58 -10
- package/templates/.claude/skills/person-identify/scripts/identify.sh +110 -11
- package/templates/.claude/skills/person-lookup/SKILL.md +8 -3
- package/templates/.claude/skills/person-lookup/scripts/lookup.sh +27 -1
- package/templates/.claude/skills/req-assess/SKILL.md +19 -11
- package/templates/.claude/skills/req-assess/references/interview-template.md +6 -1
- package/templates/.claude/skills/req-assess/references/panel-template.md +5 -1
- package/templates/.claude/skills/req-bundle/SKILL.md +164 -0
- package/templates/.claude/skills/req-bundle/references/matching.md +70 -0
- package/templates/.claude/skills/req-bundle/references/pdf-structure.md +74 -0
- package/templates/.claude/skills/req-bundle/scripts/split-bundle.mjs +377 -0
- package/templates/.claude/skills/req-decide/SKILL.md +26 -18
- package/templates/.claude/skills/req-decide/references/template.md +2 -2
- package/templates/.claude/skills/req-forget/SKILL.md +39 -22
- package/templates/.claude/skills/req-forget/references/classify.md +12 -10
- package/templates/.claude/skills/req-forget/references/locations.md +27 -22
- package/templates/.claude/skills/req-forget/references/report-template.md +23 -15
- package/templates/.claude/skills/req-scan/SKILL.md +6 -3
- package/templates/.claude/skills/req-scan/references/template.md +11 -1
- package/templates/.claude/skills/req-screen/SKILL.md +78 -34
- package/templates/.claude/skills/req-screen/references/rubric.md +38 -42
- package/templates/.claude/skills/req-screen/references/scoring.md +79 -0
- package/templates/.claude/skills/req-screen/references/template.md +26 -14
- package/templates/.claude/skills/req-track/SKILL.md +44 -44
- package/templates/.claude/skills/req-track/references/fields.md +18 -15
- package/templates/.claude/skills/req-track/references/overlays.md +42 -0
- package/templates/.claude/skills/req-track/references/signals.md +2 -2
- package/templates/.claude/skills/req-track/references/templates.md +28 -27
- package/templates/.claude/skills/req-workday/SKILL.md +49 -20
- package/templates/.claude/skills/req-workday/references/brief.md +81 -0
- package/templates/.claude/skills/req-workday/references/templates.md +6 -73
- package/templates/.claude/skills/req-workday/references/xlsx-format.md +19 -0
- package/templates/.claude/skills/req-workday/scripts/parse-workday.mjs +96 -20
- package/templates/.claude/skills/send-chat/SKILL.md +11 -11
- package/templates/.claude/skills/sync-apple-calendar/SKILL.md +3 -0
- package/templates/.claude/skills/sync-apple-mail/SKILL.md +3 -0
- package/templates/.claude/skills/sync-teams/SKILL.md +3 -0
- package/templates/.claude/skills/upstream-instructions/SKILL.md +8 -5
- package/templates/.claude/skills/upstream-instructions/references/examples.md +3 -3
- package/templates/CLAUDE.md +96 -87
- package/templates/MIGRATION.md +359 -0
- package/templates/registry.yaml +25 -0
- package/templates/.claude/skills/anarlog-follow/scripts/follow.mjs +0 -243
- package/templates/.claude/skills/anarlog-trim/SKILL.md +0 -186
package/src/outpost.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// fit-outpost init [name] Initialize a knowledge base by name (default: Team)
|
|
8
8
|
// fit-outpost update [path] Update KB with latest CLAUDE.md, agents and skills (defaults to current directory)
|
|
9
9
|
// fit-outpost stop Gracefully stop daemon and all running agents
|
|
10
|
-
// fit-outpost validate
|
|
10
|
+
// fit-outpost validate [path] Validate agent definitions and knowledge bases
|
|
11
11
|
// fit-outpost status Show agent status
|
|
12
12
|
// fit-outpost --help Show this help
|
|
13
13
|
//
|
|
@@ -27,6 +27,7 @@ import { StateManager } from "./state-manager.js";
|
|
|
27
27
|
import { AgentRunner } from "./agent-runner.js";
|
|
28
28
|
import { Scheduler, formatLocalTime } from "./scheduler.js";
|
|
29
29
|
import { KBManager } from "./kb-manager.js";
|
|
30
|
+
import { validateKnowledgeBase } from "./kb-validator.js";
|
|
30
31
|
import { SocketServer, requestShutdown, requestWake } from "./socket-server.js";
|
|
31
32
|
import {
|
|
32
33
|
readPosture,
|
|
@@ -40,12 +41,12 @@ const SHARE_DIR = "/usr/local/share/fit-outpost";
|
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
43
|
* Build the CLI definition. This object is byte-identical to the libcli
|
|
43
|
-
* definition that the golden capture used
|
|
44
|
-
* stays stable.
|
|
44
|
+
* definition that the golden capture used, and `test/golden.test.js`
|
|
45
|
+
* enforces that contract. So `--help` and `--version` output stays stable.
|
|
45
46
|
* @param {string} version
|
|
46
47
|
* @returns {object}
|
|
47
48
|
*/
|
|
48
|
-
function buildDefinition(version) {
|
|
49
|
+
export function buildDefinition(version) {
|
|
49
50
|
return {
|
|
50
51
|
name: "fit-outpost",
|
|
51
52
|
version,
|
|
@@ -72,7 +73,11 @@ function buildDefinition(version) {
|
|
|
72
73
|
name: "stop",
|
|
73
74
|
description: "Gracefully stop daemon and all running agents",
|
|
74
75
|
},
|
|
75
|
-
{
|
|
76
|
+
{
|
|
77
|
+
name: "validate",
|
|
78
|
+
args: "[path]",
|
|
79
|
+
description: "Validate agent definitions and knowledge bases",
|
|
80
|
+
},
|
|
76
81
|
{ name: "status", description: "Show agent status" },
|
|
77
82
|
{
|
|
78
83
|
name: "posture",
|
|
@@ -83,7 +88,10 @@ function buildDefinition(version) {
|
|
|
83
88
|
globalOptions: {
|
|
84
89
|
help: { type: "boolean", short: "h", description: "Show this help" },
|
|
85
90
|
version: { type: "boolean", description: "Show version" },
|
|
86
|
-
json: {
|
|
91
|
+
json: {
|
|
92
|
+
type: "boolean",
|
|
93
|
+
description: "JSON output (with --help and validate)",
|
|
94
|
+
},
|
|
87
95
|
},
|
|
88
96
|
documentation: [
|
|
89
97
|
{
|
|
@@ -375,7 +383,59 @@ export async function run(runtime, version) {
|
|
|
375
383
|
return !!found;
|
|
376
384
|
}
|
|
377
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Render one knowledge finding as a report line. Baselined findings warn.
|
|
388
|
+
* @param {import("./kb-validator.js").Finding} f
|
|
389
|
+
* @returns {string}
|
|
390
|
+
*/
|
|
391
|
+
function formatFinding(f) {
|
|
392
|
+
const prefix = f.baselined ? "warn: " : "";
|
|
393
|
+
if (f.path !== undefined) {
|
|
394
|
+
return `${prefix}${f.path} ${f.kind}${f.message ? ` — ${f.message}` : ""}`;
|
|
395
|
+
}
|
|
396
|
+
return `${prefix}${f.file}:${f.line} ${f.kind} ${f.link ?? f.property}`;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Render one KB root's findings as report lines through the logger.
|
|
401
|
+
* @param {string} root - Absolute KB root path.
|
|
402
|
+
* @param {import("./kb-validator.js").Finding[]} findings
|
|
403
|
+
* @returns {void}
|
|
404
|
+
*/
|
|
405
|
+
function reportFindings(root, findings) {
|
|
406
|
+
logger.info(`\nKnowledge base: ${root}`);
|
|
407
|
+
for (const f of findings) logger.info(` ${formatFinding(f)}`);
|
|
408
|
+
if (findings.length === 0) logger.info(" OK");
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Run the knowledge checks over each KB root. With `--json` the merged
|
|
413
|
+
* findings array is the only stdout, so tooling can parse it. A root the
|
|
414
|
+
* validator cannot read (a mistyped path, a malformed registry or
|
|
415
|
+
* baseline) fails with one clean error line instead of a stack trace.
|
|
416
|
+
* @param {string[]} roots - Absolute KB root paths.
|
|
417
|
+
* @returns {Promise<number>} 1 when any finding is not baselined, else 0.
|
|
418
|
+
*/
|
|
419
|
+
async function runKnowledgeChecks(roots) {
|
|
420
|
+
const all = [];
|
|
421
|
+
for (const root of roots) {
|
|
422
|
+
let result;
|
|
423
|
+
try {
|
|
424
|
+
result = await validateKnowledgeBase(root, runtime);
|
|
425
|
+
} catch (err) {
|
|
426
|
+
cli.error(`validate failed for ${root}: ${err.message}`);
|
|
427
|
+
return 1;
|
|
428
|
+
}
|
|
429
|
+
if (!values.json) reportFindings(root, result.findings);
|
|
430
|
+
all.push(...result.findings);
|
|
431
|
+
}
|
|
432
|
+
if (values.json) proc.stdout.write(`${JSON.stringify(all)}\n`);
|
|
433
|
+
return all.some((f) => !f.baselined) ? 1 : 0;
|
|
434
|
+
}
|
|
435
|
+
|
|
378
436
|
async function validate() {
|
|
437
|
+
if (args[0]) return runKnowledgeChecks([expandPath(args[0])]);
|
|
438
|
+
|
|
379
439
|
const config = await loadConfig();
|
|
380
440
|
const agents = Object.entries(config.agents || {});
|
|
381
441
|
if (agents.length === 0) {
|
|
@@ -391,7 +451,12 @@ export async function run(runtime, version) {
|
|
|
391
451
|
}
|
|
392
452
|
|
|
393
453
|
logger.info(errors > 0 ? `\n${errors} error(s).` : "\nAll OK.");
|
|
394
|
-
|
|
454
|
+
// The logger writes to stderr, so with --json the findings array stays
|
|
455
|
+
// the only stdout even on the no-path form.
|
|
456
|
+
const kbRoots = [
|
|
457
|
+
...new Set(agents.map(([, a]) => a.kb).filter(Boolean)),
|
|
458
|
+
].map(expandPath);
|
|
459
|
+
return Math.max(errors ? 1 : 0, await runKnowledgeChecks(kbRoots));
|
|
395
460
|
}
|
|
396
461
|
|
|
397
462
|
// --- CLI entry point -------------------------------------------------------
|
|
@@ -399,7 +464,7 @@ export async function run(runtime, version) {
|
|
|
399
464
|
const parsed = cli.parse(proc.argv.slice(2));
|
|
400
465
|
if (!parsed) return 0;
|
|
401
466
|
|
|
402
|
-
const { positionals } = parsed;
|
|
467
|
+
const { positionals, values } = parsed;
|
|
403
468
|
const [command, ...args] = positionals;
|
|
404
469
|
|
|
405
470
|
await fs.mkdir(OUTPOST_HOME, { recursive: true });
|
|
@@ -12,10 +12,17 @@ You are the chief of staff. You are the user's executive assistant. On each
|
|
|
12
12
|
wake, synthesize what matters across email, calendar, and the knowledge graph
|
|
13
13
|
into a single briefing.
|
|
14
14
|
|
|
15
|
+
## Tiers
|
|
16
|
+
|
|
17
|
+
Read: every tier present
|
|
18
|
+
Write: none (the output is personal `Briefings/`)
|
|
19
|
+
Stamp the frontmatter standard per CLAUDE.md on every note you write.
|
|
20
|
+
Aggregate outputs over narrower-tier sources go to `0-Draft/`.
|
|
21
|
+
|
|
15
22
|
## Priorities
|
|
16
23
|
|
|
17
|
-
`
|
|
18
|
-
`
|
|
24
|
+
`Priorities/` notes in every tier present are the backbone of every briefing.
|
|
25
|
+
Read them and `Conditions/` on each wake. Conditions hold the live
|
|
19
26
|
constraints that shape how you pursue the priorities. See Operating Context in
|
|
20
27
|
CLAUDE.md. The Inputs section below also lists both folders. Frame the whole
|
|
21
28
|
briefing around what advances or threatens the user's priorities.
|
|
@@ -39,9 +46,9 @@ authoritative current-state summaries:
|
|
|
39
46
|
- `~/.cache/fit/outpost/state/recruiter_triage.md`
|
|
40
47
|
- `~/.cache/fit/outpost/state/head_hunter_triage.md`
|
|
41
48
|
|
|
42
|
-
Also read these directly: `
|
|
43
|
-
`
|
|
44
|
-
|
|
49
|
+
Also read these directly: `Priorities/` and `Conditions/` in every tier,
|
|
50
|
+
`0-Draft/`, `~/.cache/fit/outpost/apple_calendar/`, and unchecked `- [ ]`
|
|
51
|
+
items across the tiers.
|
|
45
52
|
|
|
46
53
|
## Routing
|
|
47
54
|
|
|
@@ -51,7 +58,8 @@ in `Knowledge/`.
|
|
|
51
58
|
| Noon or later | `Briefings/{YYYY-MM-DD}-evening.md` |
|
|
52
59
|
|
|
53
60
|
A briefing covers: today's schedule with prep status, top three priority actions
|
|
54
|
-
linked
|
|
61
|
+
linked with tier-prefixed links (`[[3-Team/Priorities/...]]`), priority
|
|
62
|
+
progress, a **Priority Watch** section
|
|
55
63
|
that consolidates the priority risks the agents flagged, inbox snapshot
|
|
56
64
|
(urgent / awaiting reply), open commitments, recruitment pipeline summary, and a
|
|
57
65
|
heads-up section. Evening briefings replace "Priority Actions" with "What
|
|
@@ -16,10 +16,17 @@ You are the concierge. You are the user's scheduling assistant. On each wake,
|
|
|
16
16
|
keep the calendar current, prepare for upcoming meetings, and process completed
|
|
17
17
|
meeting recordings.
|
|
18
18
|
|
|
19
|
+
## Tiers
|
|
20
|
+
|
|
21
|
+
Read: every tier present
|
|
22
|
+
Write: `3-Team`
|
|
23
|
+
Stamp the frontmatter standard per CLAUDE.md on every note you write.
|
|
24
|
+
Aggregate outputs over narrower-tier sources go to `0-Draft/`.
|
|
25
|
+
|
|
19
26
|
## Priorities
|
|
20
27
|
|
|
21
|
-
At the start of every wake, before you act, read `
|
|
22
|
-
|
|
28
|
+
At the start of every wake, before you act, read `Priorities/` and `Conditions/`
|
|
29
|
+
in every tier present. The conditions constrain the priorities. See Operating
|
|
23
30
|
Context in CLAUDE.md. The user's priorities are the lens for all your work this
|
|
24
31
|
wake.
|
|
25
32
|
|
|
@@ -19,10 +19,17 @@ Benchmark promising matches. Write prospect notes for the user to review.
|
|
|
19
19
|
|
|
20
20
|
**You never contact candidates.** Outreach is the user's call.
|
|
21
21
|
|
|
22
|
+
## Tiers
|
|
23
|
+
|
|
24
|
+
Read: every tier present
|
|
25
|
+
Write: `2-Confidential`
|
|
26
|
+
Stamp the frontmatter standard per CLAUDE.md on every note you write.
|
|
27
|
+
Aggregate outputs over narrower-tier sources go to `0-Draft/`.
|
|
28
|
+
|
|
22
29
|
## Priorities
|
|
23
30
|
|
|
24
|
-
At the start of every wake, before you act, read `
|
|
25
|
-
|
|
31
|
+
At the start of every wake, before you act, read `Priorities/` and `Conditions/`
|
|
32
|
+
in every tier present. The conditions constrain the priorities. See Operating
|
|
26
33
|
Context in CLAUDE.md. The user's priorities are the lens for all your work this
|
|
27
34
|
wake.
|
|
28
35
|
|
|
@@ -14,10 +14,17 @@ skills:
|
|
|
14
14
|
You are the librarian. You are the user's knowledge curator. On each wake,
|
|
15
15
|
process new data into the knowledge graph and keep everything organized.
|
|
16
16
|
|
|
17
|
+
## Tiers
|
|
18
|
+
|
|
19
|
+
Read: every tier present
|
|
20
|
+
Write: `3-Team`
|
|
21
|
+
Stamp the frontmatter standard per CLAUDE.md on every note you write.
|
|
22
|
+
Aggregate outputs over narrower-tier sources go to `0-Draft/`.
|
|
23
|
+
|
|
17
24
|
## Priorities
|
|
18
25
|
|
|
19
|
-
At the start of every wake, before you act, read `
|
|
20
|
-
|
|
26
|
+
At the start of every wake, before you act, read `Priorities/` and `Conditions/`
|
|
27
|
+
in every tier present. The conditions constrain the priorities. See Operating
|
|
21
28
|
Context in CLAUDE.md. The user's priorities are the lens for all your work this
|
|
22
29
|
wake.
|
|
23
30
|
|
|
@@ -42,8 +49,8 @@ Assess what to process:
|
|
|
42
49
|
|
|
43
50
|
2. Count existing knowledge graph entities:
|
|
44
51
|
|
|
45
|
-
ls
|
|
46
|
-
|
|
52
|
+
ls 3-Team/People/ 3-Team/Organizations/ 3-Team/Projects/ 3-Team/Topics/
|
|
53
|
+
3-Team/Priorities/ 2>/dev/null | wc -l
|
|
47
54
|
|
|
48
55
|
Write triage results to `~/.cache/fit/outpost/state/librarian_triage.md`:
|
|
49
56
|
|
|
@@ -15,10 +15,17 @@ skills:
|
|
|
15
15
|
You are the postman. You are the user's communication gatekeeper. On each wake,
|
|
16
16
|
sync mail and Teams, triage what is new, and take the most valuable action.
|
|
17
17
|
|
|
18
|
+
## Tiers
|
|
19
|
+
|
|
20
|
+
Read: every tier present
|
|
21
|
+
Write: `0-Draft`
|
|
22
|
+
Stamp the frontmatter standard per CLAUDE.md on every note you write.
|
|
23
|
+
Aggregate outputs over narrower-tier sources go to `0-Draft/`.
|
|
24
|
+
|
|
18
25
|
## Priorities
|
|
19
26
|
|
|
20
|
-
At the start of every wake, before you act, read `
|
|
21
|
-
|
|
27
|
+
At the start of every wake, before you act, read `Priorities/` and `Conditions/`
|
|
28
|
+
in every tier present. The conditions constrain the priorities. See Operating
|
|
22
29
|
Context in CLAUDE.md. The user's priorities are the lens for all your work this
|
|
23
30
|
wake.
|
|
24
31
|
|
|
@@ -21,10 +21,17 @@ You are the recruiter. You are the user's engineering recruitment specialist.
|
|
|
21
21
|
The `fit-pathway` CLI is the single source of truth for "good engineering".
|
|
22
22
|
Every assessment and recommendation references the standard.
|
|
23
23
|
|
|
24
|
+
## Tiers
|
|
25
|
+
|
|
26
|
+
Read: every tier present
|
|
27
|
+
Write: `2-Confidential`
|
|
28
|
+
Stamp the frontmatter standard per CLAUDE.md on every note you write.
|
|
29
|
+
Aggregate outputs over narrower-tier sources go to `0-Draft/`.
|
|
30
|
+
|
|
24
31
|
## Priorities
|
|
25
32
|
|
|
26
|
-
At the start of every wake, before you act, read `
|
|
27
|
-
|
|
33
|
+
At the start of every wake, before you act, read `Priorities/` and `Conditions/`
|
|
34
|
+
in every tier present. The conditions constrain the priorities. See Operating
|
|
28
35
|
Context in CLAUDE.md. The user's priorities are the lens for all your work this
|
|
29
36
|
wake.
|
|
30
37
|
|
|
@@ -10,6 +10,9 @@ description: >
|
|
|
10
10
|
|
|
11
11
|
# Anarlog Follow
|
|
12
12
|
|
|
13
|
+
Write tier: none
|
|
14
|
+
Frontmatter: none
|
|
15
|
+
|
|
13
16
|
Follow a live Anarlog recording. Read the transcript as it grows. Coach the user
|
|
14
17
|
through the meeting in real time. Gather knowledge-base context once before the
|
|
15
18
|
session. Then poll the transcript. Provide actionable nudges as new content
|
|
@@ -23,16 +26,24 @@ appears.
|
|
|
23
26
|
|
|
24
27
|
## Prerequisites
|
|
25
28
|
|
|
26
|
-
- Anarlog installed.
|
|
27
|
-
|
|
29
|
+
- Anarlog installed. Meetings live in its local SQLite database (`app.db`).
|
|
30
|
+
Read them only through Anarlog's typed, read-only interfaces. Prefer the
|
|
31
|
+
**Anarlog MCP tools** (`list_meetings`, `get_meeting`,
|
|
32
|
+
`get_meeting_transcript`) when the MCP server is connected. Fall back to the
|
|
33
|
+
**`anarlog` CLI with `--json`** otherwise. Never `grep`, crawl `sessions/`,
|
|
34
|
+
or query SQLite directly. See Anarlog's own `AGENTS.md`
|
|
35
|
+
(`~/Library/Application Support/anarlog/AGENTS.md`).
|
|
28
36
|
- An active or about-to-start session.
|
|
29
37
|
- A populated knowledge base (attendee / candidate context).
|
|
30
38
|
|
|
31
39
|
## Inputs
|
|
32
40
|
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
- The live meeting transcript, via `get_meeting_transcript` (MCP) or
|
|
42
|
+
`anarlog --json meetings transcript <id>` (CLI). See
|
|
43
|
+
[references/sessions.md](references/sessions.md) for both interfaces.
|
|
44
|
+
- `3-Team/People/`,
|
|
45
|
+
`2-Confidential/Candidates/{Name}/{brief,screening,panel}.md`,
|
|
46
|
+
`2-Confidential/Roles/`, `3-Team/Organizations/`, `3-Team/Projects/`.
|
|
36
47
|
- `~/.cache/fit/outpost/apple_calendar/*.json` for context.
|
|
37
48
|
|
|
38
49
|
## Outputs
|
|
@@ -62,22 +73,30 @@ appears.
|
|
|
62
73
|
|
|
63
74
|
#### 1. Find the active session
|
|
64
75
|
|
|
76
|
+
No interface exposes a "recording now" signal. The only liveness signal is the
|
|
77
|
+
most recently written `audio.mp3` on disk. This is the one deliberate
|
|
78
|
+
filesystem read in this skill. All content reads go through Anarlog's
|
|
79
|
+
interfaces. The session directory name **is** the meeting ID:
|
|
80
|
+
|
|
65
81
|
```bash
|
|
66
|
-
|
|
82
|
+
find "$HOME/Library/Application Support/anarlog/sessions" -maxdepth 2 \
|
|
83
|
+
-name "audio.mp3" -exec stat -f "%m %N" {} \; | sort -rn | head -5
|
|
67
84
|
```
|
|
68
85
|
|
|
69
|
-
|
|
70
|
-
its
|
|
71
|
-
|
|
72
|
-
|
|
86
|
+
Take the top result's parent directory name as the candidate meeting ID. If
|
|
87
|
+
its mtime is more than 5 minutes old, warn the user. Ask whether to follow a
|
|
88
|
+
specific meeting. If more than one session could be active, confirm with the
|
|
89
|
+
user.
|
|
73
90
|
|
|
74
|
-
#### 2. Read
|
|
91
|
+
#### 2. Read meeting metadata
|
|
92
|
+
|
|
93
|
+
MCP: `get_meeting({ meeting_id })`. CLI fallback:
|
|
75
94
|
|
|
76
95
|
```bash
|
|
77
|
-
|
|
96
|
+
anarlog --json meetings get <meeting-id>
|
|
78
97
|
```
|
|
79
98
|
|
|
80
|
-
Capture **title**, **created_at**, **participants
|
|
99
|
+
Capture **title**, **created_at**, **participants** from `data`.
|
|
81
100
|
|
|
82
101
|
#### 3. Classify the meeting type
|
|
83
102
|
|
|
@@ -92,8 +111,8 @@ Phase 2 and the dimensions you track in Phase 3.
|
|
|
92
111
|
Extract the names from the title and the participant list. For each name:
|
|
93
112
|
|
|
94
113
|
```bash
|
|
95
|
-
rg -l "{name}"
|
|
96
|
-
rg -l "{name}"
|
|
114
|
+
rg -l "{name}" 3-Team/People/
|
|
115
|
+
rg -l "{name}" 2-Confidential/Candidates/
|
|
97
116
|
```
|
|
98
117
|
|
|
99
118
|
Read each note you find for role, organization, history, open items, and prior
|
|
@@ -101,16 +120,17 @@ interactions.
|
|
|
101
120
|
|
|
102
121
|
#### 5. Load type-specific context
|
|
103
122
|
|
|
104
|
-
**Interviews:** read
|
|
105
|
-
Look up the `Req`
|
|
106
|
-
|
|
123
|
+
**Interviews:** read
|
|
124
|
+
`2-Confidential/Candidates/{Name}/{brief,screening,panel}.md`. Look up the `Req`
|
|
125
|
+
field's matching `2-Confidential/Roles/*.md` file. Check its `**Status:**` field
|
|
126
|
+
for context. Then load the standard expectations:
|
|
107
127
|
|
|
108
128
|
```bash
|
|
109
129
|
bunx fit-pathway job {discipline} {level} --track={track}
|
|
110
130
|
```
|
|
111
131
|
|
|
112
132
|
**General meetings:** read attendee People notes plus referenced
|
|
113
|
-
Project/Organization notes. Check open tasks: `rg "{name}"
|
|
133
|
+
Project/Organization notes. Check open tasks: `rg "{name}" 3-Team/Tasks/`.
|
|
114
134
|
|
|
115
135
|
#### 6. Build the coaching brief
|
|
116
136
|
|
|
@@ -122,20 +142,24 @@ it to the user.
|
|
|
122
142
|
|
|
123
143
|
#### 7. Read new transcript content
|
|
124
144
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
node .claude/skills/anarlog-follow/scripts/follow.mjs <session-id>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Subsequent reads (pass the last word ID):
|
|
145
|
+
MCP: `get_meeting_transcript({ meeting_id, offset, limit: 500 })`. CLI
|
|
146
|
+
fallback:
|
|
132
147
|
|
|
133
148
|
```bash
|
|
134
|
-
|
|
149
|
+
anarlog --json meetings transcript <meeting-id> --offset <offset> --limit 500
|
|
135
150
|
```
|
|
136
151
|
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
First read: `offset` = 0. Each later read: `offset` = the `pagination.total`
|
|
153
|
+
from the previous read. That fetches only the words added since then. When a
|
|
154
|
+
page comes back full and `next_offset < pagination.total`, keep paging with
|
|
155
|
+
`next_offset` until you catch up. Track `total` across reads. It is your next
|
|
156
|
+
offset.
|
|
157
|
+
|
|
158
|
+
`data.words` is a flat array of `{ channel, text, start_ms, end_ms }`. Group
|
|
159
|
+
consecutive words into segments yourself. Start a new segment on a channel
|
|
160
|
+
change or a >3s gap between one word's `end_ms` and the next word's
|
|
161
|
+
`start_ms`. Channel `0` = user. Channel `1`+ = guest(s) (a heuristic, per
|
|
162
|
+
Anarlog's own docs).
|
|
139
163
|
|
|
140
164
|
#### 8. Analyze new content
|
|
141
165
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Anarlog Meeting Data
|
|
2
|
+
|
|
3
|
+
Reference for `anarlog-follow` Phases 1 and 3. Anarlog stores meetings in a
|
|
4
|
+
local SQLite database (`~/Library/Application Support/anarlog/app.db`). Read
|
|
5
|
+
them through Anarlog's typed, read-only interfaces. Its own `AGENTS.md`
|
|
6
|
+
(`~/Library/Application Support/anarlog/AGENTS.md`) is explicit:
|
|
7
|
+
|
|
8
|
+
> Use Anarlog's typed, read-only interfaces for meeting data. Do not use
|
|
9
|
+
> `find`, `grep`, `rg`, filesystem crawling, or direct SQLite queries.
|
|
10
|
+
|
|
11
|
+
**Prefer the MCP tools** when the `anarlog` MCP server is connected. **Fall
|
|
12
|
+
back to the CLI** (`anarlog --json ...`) otherwise. Never guess a meeting ID.
|
|
13
|
+
Phase 1 resolves it from the freshest `audio.mp3` on disk (the one signal
|
|
14
|
+
neither interface exposes). Every other read goes through one of the two
|
|
15
|
+
interfaces below.
|
|
16
|
+
|
|
17
|
+
## `get_meeting` / `meetings get <id>`
|
|
18
|
+
|
|
19
|
+
MCP: `get_meeting({ meeting_id })`. CLI:
|
|
20
|
+
`anarlog --json meetings get <meeting-id>`.
|
|
21
|
+
|
|
22
|
+
Returns `title`, `created_at`, `participants` (`{ human_id, display_name,
|
|
23
|
+
email, role, job_title, organization_name }`, often sparse), `note`,
|
|
24
|
+
`summaries`, `action_items`. For a live meeting, `note` and `summaries` are
|
|
25
|
+
usually thin or empty. That is expected. They fill in once the meeting ends.
|
|
26
|
+
Use this once per session, in Phase 1 Step 2, to capture the pre-meeting brief
|
|
27
|
+
inputs.
|
|
28
|
+
|
|
29
|
+
## `get_meeting_transcript` / `meetings transcript <id>`
|
|
30
|
+
|
|
31
|
+
MCP: `get_meeting_transcript({ meeting_id, offset, limit })`. CLI:
|
|
32
|
+
`anarlog --json meetings transcript <meeting-id> --offset <n> --limit <n>`
|
|
33
|
+
(`limit` capped at 500 by both interfaces).
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{ "meeting_id": "…", "text": "Yeah, so the overall …",
|
|
37
|
+
"words": [ { "channel": 0, "text": " Yeah,", "start_ms": 0, "end_ms": 400 } ] }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`pagination.total` is the running word count. Use it as the next poll's
|
|
41
|
+
`offset` so you fetch only the words added since the last read. Page with
|
|
42
|
+
`next_offset` when a single poll returns a full page and more remain. Channel
|
|
43
|
+
`0` = user, channel `1`+ = guest(s) — a heuristic, not guaranteed.
|
|
44
|
+
|
|
45
|
+
## The one filesystem exception: liveness detection
|
|
46
|
+
|
|
47
|
+
Neither interface reports which meeting is currently recording. The only
|
|
48
|
+
signal for that lives on disk: the most recently written `audio.mp3` under
|
|
49
|
+
`~/Library/Application Support/anarlog/sessions/{uuid}/`, where the directory
|
|
50
|
+
name is the meeting ID. This skill touches the filesystem for exactly that one
|
|
51
|
+
lookup (Phase 1 Step 1) and nothing else. Every read of meeting *content*
|
|
52
|
+
goes through `get_meeting` / `get_meeting_transcript`.
|