@wirecat/drive-cli 0.1.0 → 0.3.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 (63) hide show
  1. package/README.md +8 -7
  2. package/dist/api-contract.d.ts +1 -1
  3. package/dist/api-contract.js +2 -2
  4. package/dist/api-contract.js.map +1 -1
  5. package/dist/bin/drive.js +1 -1
  6. package/dist/config.d.ts +6 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +11 -1
  9. package/dist/config.js.map +1 -1
  10. package/dist/errors.d.ts +1 -1
  11. package/dist/errors.js +2 -2
  12. package/dist/errors.js.map +1 -1
  13. package/dist/extraction.js +1 -1
  14. package/dist/generated/definitions.d.ts +1 -1
  15. package/dist/generated/manifest.d.ts +1 -1
  16. package/dist/generated/schemas.js +1 -1
  17. package/dist/google-api.js +2 -2
  18. package/dist/google-api.js.map +1 -1
  19. package/dist/google.d.ts +1 -0
  20. package/dist/google.d.ts.map +1 -1
  21. package/dist/google.js +61 -7
  22. package/dist/google.js.map +1 -1
  23. package/dist/knowledge-commands.d.ts.map +1 -1
  24. package/dist/knowledge-commands.js +162 -100
  25. package/dist/knowledge-commands.js.map +1 -1
  26. package/dist/knowledge.d.ts +13 -1
  27. package/dist/knowledge.d.ts.map +1 -1
  28. package/dist/knowledge.js +28 -1
  29. package/dist/knowledge.js.map +1 -1
  30. package/dist/login.d.ts +1 -1
  31. package/dist/login.js +1 -1
  32. package/dist/mcp.d.ts +1 -1
  33. package/dist/mcp.js +2 -2
  34. package/dist/model.d.ts +12 -11
  35. package/dist/model.d.ts.map +1 -1
  36. package/dist/model.js +1 -0
  37. package/dist/model.js.map +1 -1
  38. package/dist/policy.d.ts.map +1 -1
  39. package/dist/policy.js +6 -2
  40. package/dist/policy.js.map +1 -1
  41. package/dist/profile-lock.js +1 -1
  42. package/dist/program.d.ts +1 -1
  43. package/dist/program.d.ts.map +1 -1
  44. package/dist/program.js +112 -126
  45. package/dist/program.js.map +1 -1
  46. package/dist/registry.d.ts +37 -1
  47. package/dist/registry.d.ts.map +1 -1
  48. package/dist/registry.js +33 -2
  49. package/dist/registry.js.map +1 -1
  50. package/dist/remote-commands.d.ts.map +1 -1
  51. package/dist/remote-commands.js +88 -73
  52. package/dist/remote-commands.js.map +1 -1
  53. package/dist/schema.js +1 -1
  54. package/dist/state.d.ts.map +1 -1
  55. package/dist/state.js +11 -3
  56. package/dist/state.js.map +1 -1
  57. package/dist/store.js +1 -1
  58. package/dist/sync.d.ts.map +1 -1
  59. package/dist/sync.js +38 -16
  60. package/dist/sync.js.map +1 -1
  61. package/dist/tokens.d.ts +1 -1
  62. package/dist/tokens.js +1 -1
  63. package/package.json +8 -5
package/dist/model.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export declare const FOLDER = "application/vnd.google-apps.folder";
2
2
  export declare const DOC = "application/vnd.google-apps.document";
3
+ export declare const SHEET = "application/vnd.google-apps.spreadsheet";
3
4
  export interface GoogleUser {
4
5
  id?: string;
5
6
  email?: string;
@@ -15,6 +16,7 @@ export interface FileMetadata {
15
16
  url: string;
16
17
  trashed: boolean;
17
18
  canDownload: boolean;
19
+ size?: number;
18
20
  createdAt?: string;
19
21
  description?: string;
20
22
  driveId?: string;
@@ -47,7 +49,7 @@ export interface GoogleSource {
47
49
  items: Change[];
48
50
  cursor: string;
49
51
  }>;
50
- content(id: string): Promise<DocumentContent>;
52
+ content(id: string, maxChars?: number): Promise<DocumentContent>;
51
53
  }
52
54
  export interface IndexedDocument {
53
55
  metadata: FileMetadata;
@@ -60,6 +62,13 @@ export interface WorkItem {
60
62
  kind: "save" | "remove";
61
63
  file?: FileMetadata;
62
64
  }
65
+ export interface Skip {
66
+ id: string;
67
+ reason: string;
68
+ file?: FileMetadata;
69
+ textLimit?: number;
70
+ storeRefusedIn?: string;
71
+ }
63
72
  export interface SyncState {
64
73
  version: 1;
65
74
  principal: string;
@@ -67,21 +76,13 @@ export interface SyncState {
67
76
  cursor?: string;
68
77
  folders: Record<string, FileMetadata>;
69
78
  documents: Record<string, IndexedDocument>;
70
- skipped: {
71
- id: string;
72
- reason: string;
73
- file?: FileMetadata;
74
- }[];
79
+ skipped: Skip[];
75
80
  pending?: {
76
81
  cursor: string;
77
82
  scope: string;
78
83
  folders: Record<string, FileMetadata>;
79
84
  jobs: WorkItem[];
80
- skipped: {
81
- id: string;
82
- reason: string;
83
- file?: FileMetadata;
84
- }[];
85
+ skipped: Skip[];
85
86
  };
86
87
  lastSync?: string;
87
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
package/dist/model.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export const FOLDER = "application/vnd.google-apps.folder";
2
2
  export const DOC = "application/vnd.google-apps.document";
3
+ export const SHEET = "application/vnd.google-apps.spreadsheet";
3
4
  //# sourceMappingURL=model.js.map
package/dist/model.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG,oCAAoC,CAAA;AAC1D,MAAM,CAAC,MAAM,GAAG,GAAG,sCAAsC,CAAA"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG,oCAAoC,CAAA;AAC1D,MAAM,CAAC,MAAM,GAAG,GAAG,sCAAsC,CAAA;AACzD,MAAM,CAAC,MAAM,KAAK,GAAG,yCAAyC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AACD,eAAO,MAAM,cAAc,QAAS,MAAM,CAAC,UAAU,WAAW,MAAM,UAAS,WAAW;;;CASzF,CAAA;AAID,eAAO,MAAM,gBAAgB,WAAY,MAAM,aAa9C,CAAA;AACD,eAAO,MAAM,WAAW,QACjB,MAAM,CAAC,UAAU,WACb,MAAM,OACV,MAAM,WACF,OAAO,UACT,WAAW,QACZ,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,kBAkBxC,CAAA;AACD,eAAO,MAAM,kBAAkB,GAAU,CAAC,OACnC,MAAM,CAAC,UAAU,WACb,MAAM,OACV,MAAM,OACN,MAAM,OAAO,CAAC,CAAC,CAAC,UACd,WAAW,QACZ,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KACtC,OAAO,CAAC,CAAC,CAiBX,CAAA"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AACD,eAAO,MAAM,cAAc,QAAS,MAAM,CAAC,UAAU,WAAW,MAAM,UAAS,WAAW;;;CASzF,CAAA;AAID,eAAO,MAAM,gBAAgB,WAAY,MAAM,aAa9C,CAAA;AACD,eAAO,MAAM,WAAW,QACjB,MAAM,CAAC,UAAU,WACb,MAAM,OACV,MAAM,WACF,OAAO,UACT,WAAW,QACZ,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,kBAkBxC,CAAA;AACD,eAAO,MAAM,kBAAkB,GAAU,CAAC,OACnC,MAAM,CAAC,UAAU,WACb,MAAM,OACV,MAAM,OACN,MAAM,OAAO,CAAC,CAAC,CAAC,UACd,WAAW,QACZ,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KACtC,OAAO,CAAC,CAAC,CAoBX,CAAA"}
package/dist/policy.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { join } from "node:path";
2
- import { CliError } from "@wirecat/cli-core";
2
+ import { CliError } from "@wirecat/cli-base";
3
3
  import { guardedWrite, layerPermissions, levelFor, newOperationId, permissionOverrides, RecipientList, SendJournal, sendGuard, } from "@wirecat/cli-messaging/sends";
4
4
  import { operations } from "./api-contract.js";
5
5
  import { paths, readConfig } from "./config.js";
6
+ import { VERSION } from "./version.js";
6
7
  export const policySettings = (env, profile, flags = {}) => {
7
8
  const config = readConfig(env);
8
9
  const own = config.profiles[profile];
@@ -56,7 +57,10 @@ export const guardedGoogleWrite = async (env, profile, key, act, flags = {}, ask
56
57
  permissionDefaults: defaults,
57
58
  ask: async (permission) => checkPolicy(env, profile, permission, true, flags, ask),
58
59
  sendsPerHour: Number.MAX_SAFE_INTEGER,
59
- journal: new SendJournal(join(paths(env).state, "sends", `${profile}.jsonl`)),
60
+ journal: new SendJournal(join(paths(env).state, "sends", `${profile}.jsonl`), {
61
+ service: "drive",
62
+ version: VERSION,
63
+ }),
60
64
  recipients: new RecipientList(join(paths(env).state, "recipients", `${profile}.json`), "drive"),
61
65
  warn: () => { },
62
66
  });
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { CliError } from "@wirecat/cli-core";
1
+ import { CliError } from "@wirecat/cli-base";
2
2
  import lockfile from "proper-lockfile";
3
3
  import { ensureProfileDir, profileDir } from "./state.js";
4
4
  export const lockProfile = async (env, name) => {
package/dist/program.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type KeyringStore, type Streams } from "@wirecat/cli-core";
1
+ import { type KeyringStore, type Streams } from "@wirecat/cli-base";
2
2
  import { Command } from "commander";
3
3
  import { type Complete } from "./extraction.js";
4
4
  import { type GoogleApi } from "./google-api.js";
@@ -1 +1 @@
1
- {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,YAAY,EAEjB,KAAK,OAAO,EAEb,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAAE,OAAO,EAAsC,MAAM,WAAW,CAAA;AAIvE,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,iBAAiB,CAAA;AAE5D,OAAO,EAAa,KAAK,SAAS,EAAa,MAAM,iBAAiB,CAAA;AAGtE,OAAO,EAAE,KAAK,aAAa,EAAU,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAY1E,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACnD,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IACpC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,KAAK,MAAM,CAAA;CAC7C;AAWD,eAAO,MAAM,aAAa,aAAa,cAAc,KAAQ,OA+mB5D,CAAA"}
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,YAAY,EAEjB,KAAK,OAAO,EAEb,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAAE,OAAO,EAAsC,MAAM,WAAW,CAAA;AAIvE,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,iBAAiB,CAAA;AAE5D,OAAO,EAAa,KAAK,SAAS,EAAa,MAAM,iBAAiB,CAAA;AAGtE,OAAO,EAAE,KAAK,aAAa,EAAU,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAW1E,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACnD,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IACpC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,KAAK,MAAM,CAAA;CAC7C;AAWD,eAAO,MAAM,aAAa,aAAa,cAAc,KAAQ,OAooB5D,CAAA"}
package/dist/program.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { readFileSync, writeFileSync } from "node:fs";
2
- import { CliError, createDeadline, createOutputBuffer, createRenderer, processStreams, visibleControls, } from "@wirecat/cli-core";
3
- import { annotate, describeOptions, flatten, metaOf } from "@wirecat/cli-core/commands";
4
- import { formatSuggestions, suggest } from "@wirecat/cli-core/completion";
2
+ import { CliError, createDeadline, createOutputBuffer, createRenderer, processStreams, visibleControls, } from "@wirecat/cli-base";
3
+ import { annotate, describeOptions, flatten, metaOf } from "@wirecat/cli-base/commands";
4
+ import { formatSuggestions, suggest } from "@wirecat/cli-base/completion";
5
5
  import { commandWords, liftProfile, parseDuration, refuseCommandName } from "@wirecat/cli-messaging/cli";
6
6
  import { Command, Help, InvalidArgumentError, Option } from "commander";
7
- import { operationOf, validateRequest } from "./api-contract.js";
8
- import { activeProfile, application, fileId, profileName, readConfig, writeConfig } from "./config.js";
7
+ import { validateRequest } from "./api-contract.js";
8
+ import { activeProfile, application, checkTextLimit, fileId, profileName, readConfig, writeConfig } from "./config.js";
9
9
  import { googleError } from "./errors.js";
10
10
  import { memoryModel } from "./extraction.js";
11
11
  import { googleSource } from "./google.js";
@@ -15,9 +15,8 @@ import { login } from "./login.js";
15
15
  import { FOLDER } from "./model.js";
16
16
  import { checkPolicy, guardedGoogleWrite, methodPolicyKeys } from "./policy.js";
17
17
  import { lockProfile } from "./profile-lock.js";
18
- import { ACCOUNT_FREE_COMMANDS, describeDriveProgram } from "./registry.js";
18
+ import { ACCOUNT_FREE_COMMANDS, commandsDocument, describeDriveProgram, examples } from "./registry.js";
19
19
  import { installRemoteCommands } from "./remote-commands.js";
20
- import { requestSchema } from "./schema.js";
21
20
  import { readSnapshot, readState } from "./state.js";
22
21
  import { openIndex } from "./store.js";
23
22
  import { sync } from "./sync.js";
@@ -39,7 +38,7 @@ export const createProgram = (options = {}) => {
39
38
  const env = options.env ?? process.env;
40
39
  const streams = options.streams ?? processStreams;
41
40
  const program = new Command("drive")
42
- .description("Manage Google Drive and Docs, local Markdown, shared knowledge and search")
41
+ .description("manage Google Drive and Docs, local Markdown, shared knowledge and search")
43
42
  .version(VERSION)
44
43
  .usage("<profile> [options] <command>")
45
44
  .option("--profile <name>", "explicit Google account profile (alternative to the first word)")
@@ -48,7 +47,7 @@ export const createProgram = (options = {}) => {
48
47
  .option("--agent-json", "show control and direction characters visibly in machine output")
49
48
  .option("--quiet", "suppress optional diagnostics")
50
49
  .option("--timeout <duration>", "whole-command deadline, e.g. 30s", (raw) => parseDuration(raw, "--timeout"))
51
- .option("--max-output-bytes <n>", "bound buffered result output", offset, 4 * 1024 * 1024)
50
+ .option("--max-output-bytes <n>", "largest result to print, in bytes; 0 for no limit", offset, 4 * 1024 * 1024)
52
51
  .option("--read-only", "refuse local and remote mutations")
53
52
  .option("--offline", "answer only operations that use local cached data")
54
53
  .option("--dry-run", "validate command/policy and preview without acting")
@@ -129,16 +128,14 @@ export const createProgram = (options = {}) => {
129
128
  await index.close();
130
129
  }
131
130
  };
132
- const session = program.command("session").description("Google browser sign-in and local account profiles");
133
- session
134
- .command("start")
135
- .description("Approve Google access in your browser; read-only unless --write is requested")
136
- .option("--client-file <file>", "use your own Desktop OAuth application JSON instead of WireCat's app")
137
- .option("--credential-storage <storage>", "keyring or explicit private-file storage", "keyring")
138
- .option("--no-browser", "print the sign-in URL without opening a browser")
139
- .option("--write", "request remote Drive/Docs mutation permissions")
140
- .option("--activity", "also request Drive Activity history permissions")
141
- .option("--apps", "also request the installed Drive applications permission")
131
+ const session = program.command("session").description("sign in to Google and manage local profiles");
132
+ examples(session.command("start").description("sign in to Google in the browser; read-only unless you pass --write"), ["drive personal session start", "drive work session start --write --activity"])
133
+ .option("--client-file <file>", "path to your own Desktop OAuth client JSON, used instead of WireCat's")
134
+ .option("--credential-storage <storage>", "where the sign-in is kept: keyring, or file for a private file", "keyring")
135
+ .option("--no-browser", "print the sign-in URL instead of opening a browser")
136
+ .option("--write", "also ask for permission to change Drive files and Docs")
137
+ .option("--activity", "also ask for permission to read Drive Activity history")
138
+ .option("--apps", "also ask for permission to see installed Drive apps")
142
139
  .action(async (args) => {
143
140
  if (args.credentialStorage !== "keyring" && args.credentialStorage !== "file")
144
141
  throw new CliError("validation_error", "credential storage is keyring or file");
@@ -156,10 +153,9 @@ export const createProgram = (options = {}) => {
156
153
  showUrl: (url) => streams.diagnostic(`Open Google sign-in: ${url}\n`),
157
154
  }));
158
155
  });
159
- session
160
- .command("list")
161
- .description("Configured account profiles; no credentials are printed")
162
- .action(() => output({
156
+ examples(session.command("list").description("list the configured profiles; credentials are never printed"), [
157
+ "drive personal session list",
158
+ ]).action(() => output({
163
159
  scope: "all-configured-profiles",
164
160
  items: Object.entries(readConfig(env).profiles).map(([name, p]) => ({
165
161
  profile: name,
@@ -167,10 +163,9 @@ export const createProgram = (options = {}) => {
167
163
  storage: p.storage,
168
164
  })),
169
165
  }));
170
- session
171
- .command("end")
172
- .description("Remove this profile's local sign-in; cached data is retained")
173
- .action(() => {
166
+ examples(session.command("end").description("sign this profile out; imported documents stay"), [
167
+ "drive personal session end",
168
+ ]).action(() => {
174
169
  const name = selected();
175
170
  const config = readConfig(env);
176
171
  const profile = activeProfile(env, name);
@@ -179,12 +174,12 @@ export const createProgram = (options = {}) => {
179
174
  writeConfig(env, config);
180
175
  output({ profile: name, signedOut: true, cachedData: "retained" });
181
176
  });
182
- const folders = program.command("folders").description("Select Google folders for local ingestion");
183
- folders
177
+ const folders = program.command("folders").description("choose the Google Drive folders that sync imports");
178
+ const folderArgument = "folder id or Google Drive URL";
179
+ examples(folders
184
180
  .command("add")
185
- .argument("<url-or-id>")
186
- .description("Include a folder and its descendants")
187
- .action(async (input) => {
181
+ .argument("<folder>", folderArgument)
182
+ .description("import a folder and everything under it on the next sync"), ["drive personal folders add FOLDER_ID"]).action(async (input) => {
188
183
  const id = fileId(input);
189
184
  const config = readConfig(env);
190
185
  const name = selected();
@@ -198,15 +193,13 @@ export const createProgram = (options = {}) => {
198
193
  writeConfig(env, config);
199
194
  output({ id: metadata.id, name: metadata.name, added: true });
200
195
  });
201
- folders
202
- .command("list")
203
- .description("Selected folder IDs")
204
- .action(() => output({ items: activeProfile(env, selected()).roots.map((id) => ({ id })) }));
205
- folders
196
+ examples(folders.command("list").description("list the folder ids sync imports"), [
197
+ "drive personal folders list",
198
+ ]).action(() => output({ items: activeProfile(env, selected()).roots.map((id) => ({ id })) }));
199
+ examples(folders
206
200
  .command("remove")
207
- .argument("<url-or-id>")
208
- .description("Stop importing a folder; sync removes sources outside the remaining scope")
209
- .action((input) => {
201
+ .argument("<folder>", folderArgument)
202
+ .description("stop importing a folder; the next sync drops its documents"), ["drive personal folders remove FOLDER_ID"]).action((input) => {
210
203
  const id = fileId(input);
211
204
  const config = readConfig(env);
212
205
  const name = selected();
@@ -216,16 +209,14 @@ export const createProgram = (options = {}) => {
216
209
  writeConfig(env, config);
217
210
  output({ id, removed: true, next: `run drive ${name} sync to reconcile cached sources` });
218
211
  });
219
- program
220
- .command("sync")
221
- .description("Fetch selected sources and resume a durable pending batch")
222
- .option("--max <n>", "maximum source operations this run", positive, 200)
223
- .option("--rescan", "reconcile selected folders from a fresh change token")
224
- .option("--embed", "embed pending shared note chunks using an already-downloaded model")
212
+ examples(program.command("sync").description("import what changed in the chosen folders, and finish an unfinished sync"), ["drive personal sync", "drive personal sync --rescan --limit 500"])
213
+ .option("--limit <n>", "how many documents to read from Google in this run", positive, 200)
214
+ .option("--rescan", "read every chosen folder again instead of only what changed")
215
+ .option("--embed", "also index pending text for meaning search, with a model already downloaded")
225
216
  .action(async (args) => {
226
217
  const remote = activeProfile(env, selected()).roots.length ? await source() : undefined;
227
218
  const result = await withIndex(async (index) => ({
228
- ...(await sync(remote, index, env, selected(), args.max, activeSignal, args.rescan)),
219
+ ...(await sync(remote, index, env, selected(), args.limit, activeSignal, args.rescan)),
229
220
  ...(args.embed ? { embeddings: await index.embed(600) } : {}),
230
221
  }));
231
222
  output(result);
@@ -234,10 +225,9 @@ export const createProgram = (options = {}) => {
234
225
  if (result.errors.length)
235
226
  throw new CliError("provider_error", "sync completed partially; failed operations remain pending");
236
227
  });
237
- program
238
- .command("status")
239
- .description("Local sync checkpoint, cached sources and pending work")
240
- .action(() => {
228
+ examples(program.command("status").description("show the last sync, imported documents and pending work"), [
229
+ "drive personal status",
230
+ ]).action(() => {
241
231
  const name = selected();
242
232
  const profile = activeProfile(env, name);
243
233
  const state = readState(env, name, profile.principal);
@@ -252,12 +242,14 @@ export const createProgram = (options = {}) => {
252
242
  remoteChecked: false,
253
243
  });
254
244
  });
255
- const documents = program.command("documents").description("Locally imported sources and exports");
256
- documents
257
- .command("list")
258
- .description("Imported sources with original Google URLs")
259
- .option("--tag <tag>", "filter by a local shared tag")
260
- .option("--person <reference>", "filter by a linked shared person reference")
245
+ const documents = program.command("documents").description("read imported documents and Google Docs");
246
+ const documentArgument = "document id or Google Docs URL";
247
+ examples(documents.command("list").description("list imported documents with their Google URLs"), [
248
+ "drive personal documents list",
249
+ "drive personal documents list --tag budget",
250
+ ])
251
+ .option("--tag <tag>", "only documents with this tag")
252
+ .option("--person <reference>", "only documents linked to this person:<uid> reference")
261
253
  .action(async (args) => {
262
254
  const profile = activeProfile(env, selected());
263
255
  const state = readState(env, selected(), profile.principal);
@@ -289,31 +281,30 @@ export const createProgram = (options = {}) => {
289
281
  const doc = state.documents[id];
290
282
  return { id, ref: doc.reference, hash: doc.hash, snapshot: readSnapshot(env, selected(), id) };
291
283
  };
292
- documents
284
+ examples(documents
293
285
  .command("show")
294
- .argument("<url-or-id>")
295
- .description("Imported text with tab and source metadata")
296
- .action((input) => {
286
+ .argument("<document>", documentArgument)
287
+ .description("show an imported document's text, tabs and metadata"), ["drive personal documents show DOC_ID"]).action((input) => {
297
288
  const { snapshot } = imported(input);
298
289
  output({ metadata: snapshot.metadata, text: snapshot.text, tabs: snapshot.tabs });
299
290
  });
300
- documents
291
+ examples(documents
301
292
  .command("export")
302
- .argument("<url-or-id>")
303
- .requiredOption("--out <file>", "destination Markdown file")
304
- .description("Write the native Markdown snapshot; existing files are refused")
293
+ .argument("<document>", documentArgument)
294
+ .description("write an imported document to a new Markdown file"), ["drive personal documents export DOC_ID --out notes.md"])
295
+ .requiredOption("--out <file>", "path of the Markdown file to write; an existing file is refused")
305
296
  .action((input, args) => {
306
297
  const { id, snapshot } = imported(input);
307
298
  writeFileSync(args.out, snapshot.markdown, { flag: "wx", mode: 0o600 });
308
299
  output({ id, path: args.out, format: "markdown" });
309
300
  });
310
- program
301
+ examples(program
311
302
  .command("search")
312
- .argument("<query>")
313
- .description("Shared keyword and optional semantic search over imported Google sources")
314
- .option("--limit <n>", "maximum results", positive, 20)
315
- .option("--offset <n>", "results to skip", offset, 0)
316
- .option("--exact", "keyword search only, without stemming or meaning")
303
+ .argument("<query>", "words to look for")
304
+ .description("search imported documents by words, and by meaning when indexed"), ["drive personal search budget", `drive personal search "quarterly plan" --exact --limit 5`])
305
+ .option("--limit <n>", "how many results to return", positive, 20)
306
+ .option("--offset <n>", "how many results to skip", offset, 0)
307
+ .option("--exact", "match the words exactly: no word forms, no meaning")
317
308
  .action(async (query, args) => output(await withIndex((index) => index.search(activeProfile(env, selected()).principal, query, { ...args, exact: args.exact ?? false }))));
318
309
  installKnowledgeCommands(program, {
319
310
  document: imported,
@@ -374,15 +365,17 @@ export const createProgram = (options = {}) => {
374
365
  return descriptor.mutates ? guardedGoogleWrite(env, selected(), `api.${method}`, act, flags, askOnce) : act();
375
366
  },
376
367
  });
377
- const config = program
378
- .command("config")
379
- .description("Shared-style defaults/profile settings; credentials are separate");
380
- config.command("show").action(() => output(readConfig(env)));
381
- config
382
- .command("set")
383
- .argument("<key>")
384
- .argument("<json-value>")
385
- .option("--defaults", "change defaults rather than the selected profile")
368
+ const config = program.command("config").description("read and change settings; credentials are kept apart");
369
+ examples(config.command("show").description("show the defaults and every profile's settings"), [
370
+ "drive personal config show",
371
+ ]).action(() => output(readConfig(env)));
372
+ examples(config.command("set").description("set one setting of this profile, or of the defaults"), [
373
+ "drive personal config set readOnly true",
374
+ `drive personal config set permissions.files '"readonly"' --defaults`,
375
+ ])
376
+ .argument("<key>", "readOnly, maxTextChars, permissions.<key> or models.<purpose>.<field>")
377
+ .argument("<json-value>", "the new value, as JSON")
378
+ .option("--defaults", "change the defaults instead of this profile")
386
379
  .action((key, raw, args) => {
387
380
  const value = readConfig(env);
388
381
  if (args.defaults)
@@ -393,9 +386,9 @@ export const createProgram = (options = {}) => {
393
386
  if (!args.defaults)
394
387
  value.profiles[selected()] = target;
395
388
  const [head, ...parts] = key.split(".");
396
- if (!["readOnly", "permissions", "models"].includes(head ?? "") ||
389
+ if (!["readOnly", "permissions", "models", "maxTextChars"].includes(head ?? "") ||
397
390
  parts.some((part) => ["__proto__", "prototype", "constructor"].includes(part)))
398
- throw new CliError("validation_error", "config set accepts readOnly, permissions or models");
391
+ throw new CliError("validation_error", "config set accepts readOnly, permissions, models or maxTextChars");
399
392
  let parsed;
400
393
  try {
401
394
  parsed = JSON.parse(raw);
@@ -403,7 +396,9 @@ export const createProgram = (options = {}) => {
403
396
  catch {
404
397
  throw new CliError("validation_error", "setting value must be JSON");
405
398
  }
406
- if (!parts.length)
399
+ if (head === "maxTextChars" && !parts.length)
400
+ target.maxTextChars = checkTextLimit(parsed);
401
+ else if (!parts.length)
407
402
  Object.assign(target, { [key]: parsed });
408
403
  else if (head === "permissions") {
409
404
  target.permissions ??= {};
@@ -419,10 +414,10 @@ export const createProgram = (options = {}) => {
419
414
  writeConfig(env, value);
420
415
  output({ key, updated: true, scope: args.defaults ? "defaults" : selected() });
421
416
  });
422
- program
423
- .command("complete")
424
- .description("Shell completion from the shared command registry")
425
- .argument("[words...]")
417
+ examples(program.command("complete").description("print a shell completion script, or complete words"), [
418
+ "drive complete zsh",
419
+ ])
420
+ .argument("[words...]", "a shell name, or after -- the words typed so far")
426
421
  .allowUnknownOption()
427
422
  .helpOption(false)
428
423
  .action(async (words) => {
@@ -435,25 +430,17 @@ export const createProgram = (options = {}) => {
435
430
  else
436
431
  streams.data(formatSuggestions(suggest({ commands: describeDriveProgram(program), globalOptions: describeOptions(program), words })));
437
432
  });
438
- program
439
- .command("schema")
440
- .argument("<method>")
441
- .description("Generated request schema and operation contract without Google access")
442
- .action((method) => {
443
- const operation = operationOf(method);
444
- output({
445
- operation,
446
- requestSchema: requestSchema(method),
447
- });
448
- });
449
- program
433
+ examples(program
450
434
  .command("models")
451
- .description("Configure the shared model gateway; keys stay outside config")
452
- .command("configure")
453
- .option("--purpose <purpose>", "shared model purpose", "memories")
454
- .addOption(new Option("--provider <provider>").choices(["openai", "anthropic", "off"]).makeOptionMandatory())
455
- .option("--model <model>", "model identifier for the selected provider")
456
- .option("--base-url <url>", "optional HTTP/S model endpoint without URL credentials")
435
+ .description("choose the model that proposes memories; keys stay out of config")
436
+ .command("set")
437
+ .description("set the provider and model for one use"), ["drive personal models set --provider openai --model MODEL_ID", "drive personal models set --provider off"])
438
+ .option("--purpose <purpose>", "what the model is used for", "memories")
439
+ .addOption(new Option("--provider <provider>", "who runs the model, or off to use none")
440
+ .choices(["openai", "anthropic", "off"])
441
+ .makeOptionMandatory())
442
+ .option("--model <model>", "model id at the provider")
443
+ .option("--base-url <url>", "HTTP or HTTPS address of the model API, without credentials in it")
457
444
  .action((args) => {
458
445
  const config = readConfig(env);
459
446
  config.defaults ??= {};
@@ -466,8 +453,13 @@ export const createProgram = (options = {}) => {
466
453
  writeConfig(env, config);
467
454
  output({ purpose: args.purpose, configured: true });
468
455
  });
469
- const mcp = program.command("mcp").description("Expose guarded commands over MCP stdio");
470
- mcp.option("--tools", "list offered tools without starting a server").action(async (args) => {
456
+ const mcp = examples(program.command("mcp").description("serve drive's commands to an agent over MCP on stdio"), [
457
+ "drive personal mcp",
458
+ "drive personal mcp --tools",
459
+ ]);
460
+ mcp
461
+ .option("--tools", "list the tools offered instead of starting the server")
462
+ .action(async (args) => {
471
463
  const { mcpTools, serveMcp } = await import("./mcp.js");
472
464
  if (args.tools)
473
465
  output({
@@ -480,20 +472,12 @@ export const createProgram = (options = {}) => {
480
472
  else
481
473
  await serveMcp({ ...options, env, ...(activeSignal ? { signal: activeSignal } : {}) }, selected(), policyFlags());
482
474
  });
483
- program
484
- .command("commands")
485
- .argument("[path...]")
486
- .description("Discover the command tree and options as shared registry data")
487
- .action((path) => {
488
- const commands = describeDriveProgram(program);
489
- const found = path.length ? flatten(commands).filter((item) => item.path.join(" ") === path.join(" ")) : commands;
490
- if (path.length && !found.length)
491
- throw new CliError("not_found", "command path was not found");
492
- output({
493
- items: found,
494
- ...(path.length ? {} : { cli: "drive", commands, globalOptions: describeOptions(program) }),
495
- });
496
- });
475
+ examples(program.command("commands").description("print the command tree and its options as data"), [
476
+ "drive commands --json",
477
+ "drive commands files copy --json",
478
+ ])
479
+ .argument("[path...]", "only this command or group, as words")
480
+ .action((path) => output(commandsDocument(program, path)));
497
481
  for (const info of flatten(describeDriveProgram(program))) {
498
482
  let command = program;
499
483
  for (const part of info.path)
@@ -507,8 +491,8 @@ export const createProgram = (options = {}) => {
507
491
  "documents export",
508
492
  "tags add",
509
493
  "tags remove",
510
- "links add",
511
- "links remove",
494
+ "relationships add",
495
+ "relationships remove",
512
496
  "notes add",
513
497
  "notes edit",
514
498
  "notes remove",
@@ -516,8 +500,10 @@ export const createProgram = (options = {}) => {
516
500
  "memories confirm",
517
501
  "memories stale",
518
502
  "memories extract",
519
- "people link",
520
- "models configure",
503
+ "facts add",
504
+ "facts confirm",
505
+ "identities link",
506
+ "models set",
521
507
  "config set",
522
508
  ];
523
509
  const remoteWrites = [
@@ -562,7 +548,7 @@ export const createProgram = (options = {}) => {
562
548
  if (ACCOUNT_FREE_COMMANDS.has(words))
563
549
  return;
564
550
  selected();
565
- if (["commands", "complete", "schema", "config show", "config set", "session list"].includes(words))
551
+ if (["commands", "complete", "config show", "config set", "session list"].includes(words))
566
552
  return;
567
553
  const flags = policyFlags();
568
554
  const metadata = metaOf(action);