@voidlabs.gg/voidshift 0.4.4 → 0.4.6

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 CHANGED
@@ -86,8 +86,33 @@ vsf agents workflow add|edit|show|rename|move|rm
86
86
  vsf agents projects | project add|edit|show|rename|rm
87
87
  vsf agents homes | link DIR # where the agents are installed
88
88
  vsf agents clean # old worktrees and run logs
89
+ vsf agents validate [DIR] # check the config and agent folders
89
90
  ```
90
91
 
92
+ A workflow can also be a folder you write by hand,
93
+ `~/.config/voidshift/agents/defs/NAME/agent.json`, with its prompt files next to
94
+ it. Steps are the built-in ids above or your own:
95
+
96
+ ```json
97
+ {
98
+ "triggers": [{ "source": "cron", "schedule": "0 7 * * 1-5", "task": "Morning brief" }],
99
+ "steps": [{ "id": "brief", "prompt": "brief.md", "output": "none", "model": "haiku", "timeoutMinutes": 10 }],
100
+ "maxRounds": 1,
101
+ "project": "tether-relay",
102
+ "writeBack": { "labels": true, "state": null, "comment": true }
103
+ }
104
+ ```
105
+
106
+ A step's `output` is `plan`, `verdict`, `commits`, `publish` or `none`; a failed
107
+ `verdict` sends the work back to the nearest `plan` or `commits` step. `engine`,
108
+ `model` and `timeoutMinutes` fall back to the config, and `write` to true only
109
+ for `commits`. A `publish` step takes no prompt; the others take one `prompt`
110
+ file or `skill`, which must ask for a `RESULT:` line (`plan`, `commits`) or a
111
+ `VERDICT:` line (`verdict`). `writeBack` applies to card runs: `state` moves a
112
+ verified card there (`null` never moves it), `labels: false` only takes the
113
+ trigger label off, and `comment: false` skips the closing comment. Edit the file,
114
+ then `vsf agents validate`.
115
+
91
116
  ### memory
92
117
 
93
118
  A folder of markdown notes, one topic per note, with an `INDEX.md` holding one
@@ -102,12 +127,35 @@ vsf memory status # the vault and where recall is on
102
127
  vsf memory search WORDS # notes recall would bring up
103
128
  vsf memory try "a prompt" # exactly what recall would add to that prompt
104
129
  vsf memory check # notes missing from INDEX.md, broken links
130
+ vsf memory sync # pull and push the vault through its git remote
105
131
  vsf memory on | off # turn recall on or off
106
132
  ```
107
133
 
134
+ To share the vault between machines, make it a git repository with a remote
135
+ named `origin` (any host; a private repository). `vsf memory sync` commits new
136
+ notes, rebases onto the remote and pushes. It also runs in the background from
137
+ the recall hook when the last sync is over ten minutes old, and the agents
138
+ runner syncs before and after every run. When a note changed on both sides,
139
+ the remote's version stays and this machine's copy is saved beside it as
140
+ `note.conflict-<machine>-<time>.md`, so nothing is lost.
141
+
108
142
  Setup creates a vault at `~/memory` or uses one you already have. Codex asks you
109
143
  to trust the recall hook once: run `/hooks` in Codex.
110
144
 
145
+ ### Your profile
146
+
147
+ Every agent run carries your profile, on any machine, without touching your
148
+ Claude or Codex folder. `vsf agents profile init` creates
149
+ `~/.config/voidshift/agents/profile/`:
150
+
151
+ - `RULES.md` is added to every step's prompt (style, commit rules, tone).
152
+ - `claude-settings.json` is passed to Claude runs with `--settings`, so hooks
153
+ come along. `{{profile}}` stands for the folder, so hook scripts can live in it.
154
+
155
+ Setup also asks what the runner does to agent commits before it pushes them:
156
+ remove AI co-author lines, and add `Signed-off-by` for repos that ask for a
157
+ DCO. Only the new commits of that step are rewritten, never pushed ones.
158
+
111
159
  ## What to know
112
160
 
113
161
  - **Your own logins.** Agents run the official `claude` and `codex` CLIs you
@@ -141,8 +189,12 @@ pnpm test
141
189
  node packages/cli/src/main.ts
142
190
  ```
143
191
 
144
- Node 22.18 or newer runs the TypeScript sources directly. Releases are cut by
145
- pushing a `v*` tag; CI publishes every package at that version.
192
+ Node 22.18 or newer runs the TypeScript sources directly. Each package
193
+ releases on its own: bump its `package.json` and push `agents-v0.5.0` (or
194
+ `cli-v`, `memory-v`, `awake-v`), and CI publishes only that package. A plain
195
+ `v*` tag publishes all four at one version. Tools declare the CLI contract
196
+ they were built for; a CLI that is too old refuses to load them and says to
197
+ run `vsf update`.
146
198
 
147
199
  ## License
148
200
 
package/dist/loader.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ToolEntry } from './registry.ts';
2
- import type { Tool } from './tool.ts';
2
+ import { type Tool } from './tool.ts';
3
3
  export declare function locate(entry: ToolEntry, configDir: string): string | null;
4
4
  export declare function npm(args: string[]): boolean;
5
5
  export declare function fetchTool(entry: ToolEntry, configDir: string): boolean;
package/dist/loader.js CHANGED
@@ -10,6 +10,7 @@ import { spawnSync } from 'node:child_process';
10
10
  import { existsSync } from 'node:fs';
11
11
  import { join } from 'node:path';
12
12
  import { fileURLToPath, pathToFileURL } from 'node:url';
13
+ import { CONTRACT } from "./tool.js";
13
14
  // Inside the monorepo, tools load straight from source. Installed copies
14
15
  // live under <configDir>/tools, one npm prefix shared by every tool.
15
16
  function sourcePath(entry) {
@@ -47,5 +48,8 @@ export async function loadTool(entry, configDir) {
47
48
  if (!path)
48
49
  throw new Error(`could not download ${entry.pkg}. Check your connection and run vsf setup again.`);
49
50
  const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(path).href)));
51
+ const contract = mod.default.contract ?? 1;
52
+ if (contract > CONTRACT)
53
+ throw new Error(`${entry.name} needs a newer vsf (it uses tool contract ${contract}, this vsf knows ${CONTRACT}). Run vsf update.`);
50
54
  return mod.default;
51
55
  }
package/dist/tool.d.ts CHANGED
@@ -37,9 +37,11 @@ export interface ToolContext {
37
37
  ui: Ui;
38
38
  }
39
39
  export type ToolCommand = (args: string[], ctx: ToolContext) => Promise<number>;
40
+ export declare const CONTRACT = 1;
40
41
  export interface Tool {
41
42
  name: string;
42
43
  summary: string;
44
+ contract?: number;
43
45
  install(ctx: ToolContext): Promise<void>;
44
46
  uninstall(ctx: ToolContext): Promise<void>;
45
47
  checks(ctx: ToolContext): Promise<Check[]>;
package/dist/tool.js CHANGED
@@ -1,4 +1,6 @@
1
1
  // The contract every voidshift tool implements. The CLI owns discovery,
2
2
  // install and reporting; a tool only knows how to set itself up, take
3
3
  // itself down, say whether it is healthy, and run its own subcommands.
4
- export {};
4
+ // The version of this contract. A tool built for a newer one may call things
5
+ // this CLI does not have, so it is not loaded; tools without the field are 1.
6
+ export const CONTRACT = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidlabs.gg/voidshift",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "One CLI for the Void dev tools: keep your Mac awake, run agents in the background, shared skills and memory for Claude Code and Codex.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {