@logbookfordevs/afk 0.5.2

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/README.md ADDED
@@ -0,0 +1,240 @@
1
+ # AFK CLI
2
+
3
+ Setup router for AI Field Kit.
4
+
5
+ Install the published CLI from npm:
6
+
7
+ ```bash
8
+ npm install -g @logbookfordevs/afk
9
+ afk setup --dry-run
10
+ ```
11
+
12
+ Use the dry run first. AFK prints the exact rules, skills, MCP, utility, and
13
+ hook setup actions before anything writes to your machine.
14
+
15
+ To work from this repository checkout:
16
+
17
+ ```bash
18
+ pnpm --dir packages/afk install
19
+ pnpm --dir packages/afk run build
20
+ node packages/afk/dist/index.js setup --dry-run
21
+ ```
22
+
23
+ From the repo root, install this checkout as a local `afk` command:
24
+
25
+ ```bash
26
+ ./scripts/install.sh --local
27
+ afk setup --dry-run
28
+ ```
29
+
30
+ `scripts/install.sh` is intended for local development installs from this
31
+ checkout. The user-facing install path is the npm package.
32
+
33
+ `afk setup` opens with a branded banner and checkbox prompts. Setup areas,
34
+ setup scope, AFK-owned rule targets, individual AFK skills, recommended external
35
+ skills, MCP recommendations, utility installs, and lifecycle hooks start
36
+ selected so you can remove only the pieces you do not want.
37
+
38
+ By default, `afk setup` prepares a global field kit for this machine. Choose
39
+ project scope when you want AFK config to live in the current repo instead:
40
+
41
+ ```bash
42
+ node packages/afk/dist/index.js setup --scope project --dry-run
43
+ node packages/afk/dist/index.js setup --local --dry-run
44
+ ```
45
+
46
+ In project scope, AFK omits the upstream `--global` flags for `skills` and
47
+ `add-mcp`, writes AFK-owned rule files under the current directory, and runs RTK
48
+ project initialization from that directory. Plannotator remains a global utility
49
+ install because its installer does not expose a project scope.
50
+
51
+ Workflow-style AFK procedures are shipped as skills. Their manifest entries set
52
+ `autoInvocation: false`, so AFK keeps them installed and available without
53
+ encouraging agents to call them implicitly.
54
+
55
+ The CLI stores editable local setup manifests under:
56
+
57
+ ```text
58
+ ~/.agents/afk/manifests/
59
+ ```
60
+
61
+ First run seeds those files from AFK defaults. After that, commands read the
62
+ local manifests, so you can add, remove, or replace skills, MCPs, utilities, or
63
+ hooks without patching the CLI.
64
+
65
+ Useful manifest setup modes:
66
+
67
+ ```bash
68
+ node packages/afk/dist/index.js setup --init-only
69
+ node packages/afk/dist/index.js setup --init-only --empty
70
+ node packages/afk/dist/index.js setup refresh
71
+ node packages/afk/dist/index.js setup refresh --local
72
+ node packages/afk/dist/index.js setup refresh --defaults-source your-org/dev-kit
73
+ node packages/afk/dist/index.js setup --defaults-source your-org/dev-kit
74
+ ```
75
+
76
+ Author your own manifests interactively:
77
+
78
+ ```bash
79
+ afk manifests configure
80
+ afk manifests configure --local
81
+ afk manifests configure --from-current
82
+ ```
83
+
84
+ `afk manifests configure` writes to `~/.agents/afk/manifests/`.
85
+ `afk manifests configure --local` writes to `./afk/manifests/`, matching the
86
+ GitHub defaults convention used by `--defaults-source`.
87
+
88
+ `--defaults-source` lets another GitHub repo become the manifest source as long
89
+ as it follows the AFK convention:
90
+
91
+ ```text
92
+ afk/manifests/
93
+ skills.json
94
+ mcps.json
95
+ presets.json
96
+ rules.json
97
+ utils.json
98
+ hooks.json
99
+ ```
100
+
101
+ For monorepos, AFK also falls back to `packages/afk/manifests/`. You can pass
102
+ `owner/repo`, a GitHub repo URL, a GitHub `tree` URL for a custom manifest
103
+ folder, or a raw GitHub manifest directory URL.
104
+
105
+ When you pass `--defaults-source`, AFK writes that source into `presets.json`.
106
+ Later, `afk setup refresh` reuses the remembered source, so you do not need to
107
+ repeat the flag. `afk setup refresh --local` refreshes `./afk/manifests` for the
108
+ current project instead of `~/.agents/afk/manifests`.
109
+
110
+ For rules, keep the source repo explicit in `rules.json`:
111
+
112
+ ```json
113
+ {
114
+ "version": 1,
115
+ "source": "github",
116
+ "url": "https://raw.githubusercontent.com/your-org/dev-kit/main/rules/AGENTS.md"
117
+ }
118
+ ```
119
+
120
+ That lets a personal defaults repo refresh the manifest and keep future
121
+ `setup rules` runs pointed at the same repo.
122
+
123
+ Hooks point at a source script plus the native command AFK should merge into
124
+ agent hook config:
125
+
126
+ ```json
127
+ {
128
+ "version": 1,
129
+ "items": [
130
+ {
131
+ "id": "company-stop-check",
132
+ "label": "Company Stop Check",
133
+ "description": "Run a local handoff guard.",
134
+ "source": "https://raw.githubusercontent.com/your-org/dev-kit/main/hooks/company-stop-check.js",
135
+ "command": "node",
136
+ "args": ["${HOOK_FILE}", "--agent", "${AGENT}"],
137
+ "events": ["stop"],
138
+ "agents": ["codex", "claude"],
139
+ "default": true
140
+ }
141
+ ]
142
+ }
143
+ ```
144
+
145
+ AFK copies the source script into the selected agent's hook folder, expands
146
+ `${HOOK_FILE}` and `${AGENT}`, and then merges the command into the agent's
147
+ native hook config.
148
+
149
+ Skills can opt out of automatic invocation:
150
+
151
+ ```json
152
+ {
153
+ "version": 1,
154
+ "defaultSource": "https://github.com/your-org/dev-kit",
155
+ "items": [
156
+ {
157
+ "id": "review-pr",
158
+ "label": "Review PR",
159
+ "source": "https://github.com/your-org/dev-kit",
160
+ "args": ["--skill", "review-pr"],
161
+ "default": true,
162
+ "autoInvocation": false
163
+ }
164
+ ]
165
+ }
166
+ ```
167
+
168
+ Selected skills are grouped into non-interactive `skills` CLI calls with
169
+ `--yes`. Global scope adds `--global`; project scope leaves that flag out so
170
+ the official CLI installs into project skill locations. AFK keeps the default
171
+ symlink behavior. When `autoInvocation` is false, AFK adds Claude Code
172
+ `disable-model-invocation: true` frontmatter and OpenAI
173
+ `allow_implicit_invocation: false` policy metadata after the official install.
174
+
175
+ Utilities are curated developer tools AFK can install by delegating to their
176
+ official install scripts. V1 includes Plannotator for plan review loops, RTK
177
+ for token-light command output, Yggtree for git worktree workflows, and
178
+ Impeccable's Codex-tailored frontend design skill. When RTK is selected, AFK
179
+ follows up with agent-specific `rtk init` commands for the selected AFK targets.
180
+ In global
181
+ scope, Codex is initialized from `~/.codex` so RTK lands in the global Codex
182
+ rules location instead of the current project, and Antigravity/Agy uses RTK's
183
+ Gemini compatibility initializer because Antigravity still consumes the global
184
+ `~/.gemini/GEMINI.md` host. In project scope, Antigravity/Agy uses
185
+ `rtk init --agent antigravity`, while other RTK init commands run from the
186
+ current project without global flags. Utility installs are best-effort: if one
187
+ third-party script fails, AFK reports the failure and continues with the rest.
188
+
189
+ During `afk setup`, each selected area runs independently. If Skills fails, AFK
190
+ still tries MCPs and Utils, then exits non-zero with a summary of failed areas.
191
+
192
+ V1 owns AFK rules sync behavior for Antigravity/Agy, Codex, Claude Code, and
193
+ OpenCode. More AFK-owned targets can be added over time. Skills and MCP
194
+ installation are delegated to the official CLIs, so their broader compatibility
195
+ belongs to those tools.
196
+
197
+ Hooks are merged into existing agent hook configs instead of replacing them.
198
+ V1 supports Codex, Claude Code, and local Cursor targets. Codex uses
199
+ `.codex/hooks.json`; Claude Code uses `.claude/settings.json`; Cursor local
200
+ uses `.cursor/hooks.json`. Cursor Cloud lifecycle hooks are intentionally out of
201
+ scope.
202
+
203
+ Rules sync fetches the latest AFK rule markdown from GitHub by default, then
204
+ injects it into a managed region inside the user-owned host file:
205
+
206
+ ```text
207
+ ~/.agents/AGENTS.md
208
+ ```
209
+
210
+ The CLI preserves content outside the `AFK:RULES` region and updates that
211
+ region in place on later runs. Agent-specific rule files still symlink to the
212
+ shared host file.
213
+
214
+ In project scope, rules are injected directly into project host files instead
215
+ of global agent files: `AGENTS.md` for Codex/OpenCode, `GEMINI.md` for
216
+ Antigravity/Agy, and `CLAUDE.md` for Claude Code.
217
+
218
+ Use a local checkout while developing rule changes:
219
+
220
+ ```bash
221
+ node packages/afk/dist/index.js setup rules --dry-run --source local
222
+ ```
223
+
224
+ Update `rules.json` when you want a stable public setup:
225
+
226
+ ```bash
227
+ node packages/afk/dist/index.js setup rules --dry-run
228
+ ```
229
+
230
+ Install only utilities:
231
+
232
+ ```bash
233
+ node packages/afk/dist/index.js setup utils --dry-run
234
+ ```
235
+
236
+ Install only hooks:
237
+
238
+ ```bash
239
+ node packages/afk/dist/index.js setup hooks --dry-run
240
+ ```
package/dist/agents.js ADDED
@@ -0,0 +1,59 @@
1
+ export const agentIds = [
2
+ "antigravity",
3
+ "claude",
4
+ "codex",
5
+ "opencode",
6
+ ];
7
+ export const universalSkillAgentLabels = [
8
+ "Amp",
9
+ "Antigravity",
10
+ "Cline",
11
+ "Codex",
12
+ "Cursor",
13
+ "Deep Agents",
14
+ "Dexto",
15
+ "Firebender",
16
+ "Gemini CLI",
17
+ "GitHub Copilot",
18
+ "Kimi Code CLI",
19
+ "OpenCode",
20
+ "Warp",
21
+ "Zed",
22
+ ];
23
+ export const skillAgentChoices = [
24
+ { id: "claude-code", label: "Claude Code", path: ".claude/skills" },
25
+ { id: "kiro-cli", label: "Kiro CLI", path: ".kiro/skills" },
26
+ { id: "kilo", label: "Kilo Code", path: ".kilocode/skills" },
27
+ { id: "pi", label: "Pi", path: ".pi/agent/skills" },
28
+ { id: "droid", label: "Droid", path: ".factory/skills" },
29
+ ];
30
+ export const skillAgentIds = skillAgentChoices.map((agent) => agent.id);
31
+ export const hookAgentIds = [
32
+ "codex",
33
+ "claude",
34
+ "cursor-local",
35
+ ];
36
+ export const addMcpAgentNames = {
37
+ antigravity: "antigravity",
38
+ claude: "claude-code",
39
+ codex: "codex",
40
+ opencode: "opencode",
41
+ };
42
+ export function isAgentId(value) {
43
+ return [...agentIds, ...hookAgentIds].includes(value);
44
+ }
45
+ export function normalizeAgentId(value) {
46
+ if (value === "agy" || value === "gemini") {
47
+ return "antigravity";
48
+ }
49
+ if (value === "cursor" || value === "cursor-ide" || value === "cursor-cli") {
50
+ return "cursor-local";
51
+ }
52
+ return isAgentId(value) ? value : null;
53
+ }
54
+ export function filterAgents(selected, supported) {
55
+ if (selected.length === 0) {
56
+ return supported;
57
+ }
58
+ return selected.filter((agent) => supported.includes(agent));
59
+ }
package/dist/brand.js ADDED
@@ -0,0 +1,60 @@
1
+ import { ansi, bold, paint, reset, routeGradient, terminalPalette } from "./terminal-theme.js";
2
+ export function renderBanner() {
3
+ const title = [
4
+ " ___ ________ __",
5
+ " / | / ____/ //_/",
6
+ " / /| | / /_ / ,< ",
7
+ " / ___ | / __/ / /| | ",
8
+ "/_/ |_|/_/ /_/ |_| ",
9
+ ];
10
+ const name = "AI FIELD KIT";
11
+ const subtitle = "setup router for agentic dev work";
12
+ const rule = "─".repeat(54);
13
+ return [
14
+ "",
15
+ gradient(rule),
16
+ ...title.map((line) => `${bold}${gradient(line)}${reset}`),
17
+ "",
18
+ `${bold}${brandText(name)}${reset}`,
19
+ muted(subtitle),
20
+ gradient(rule),
21
+ "",
22
+ ].join("\n");
23
+ }
24
+ export function renderSetupOutro(input) {
25
+ const title = input.failed ? "AFK setup needs attention" : input.dryRun ? "AFK dry run complete" : "AFK setup complete";
26
+ const body = input.failed
27
+ ? "Some areas failed, but AFK finished the full route and kept the summary above."
28
+ : input.dryRun
29
+ ? "No files changed. The preview above is the exact route AFK would take."
30
+ : "Your field kit is prepared. Restart any agents that cache config before they read the new setup.";
31
+ const rule = "─".repeat(54);
32
+ return [
33
+ "",
34
+ gradient(rule),
35
+ `${bold}${brandText(title)}${reset}`,
36
+ muted(body),
37
+ muted(`Scope: ${input.scopeLabel}`),
38
+ muted(`Areas: ${input.areas.join(", ")}`),
39
+ gradient(rule),
40
+ "",
41
+ ].join("\n");
42
+ }
43
+ export function sectionTitle(value) {
44
+ return `${paint(terminalPalette.rust, "◆")} ${bold}${value}${reset}`;
45
+ }
46
+ export function muted(value) {
47
+ return paint(terminalPalette.driftwood, value);
48
+ }
49
+ function brandText(value) {
50
+ return paint(terminalPalette.brass, value);
51
+ }
52
+ function gradient(value) {
53
+ return [...value]
54
+ .map((char, index) => {
55
+ const colorIndex = Math.min(routeGradient.length - 1, Math.floor((index / Math.max(1, value.length - 1)) * routeGradient.length));
56
+ const color = routeGradient[colorIndex] ?? routeGradient[0];
57
+ return `${ansi(color[0], color[1], color[2])}${char}`;
58
+ })
59
+ .join("") + reset;
60
+ }