@robbeverhelst/do 1.42.0 → 1.44.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 (2) hide show
  1. package/dist/do.js +404 -2
  2. package/package.json +1 -1
package/dist/do.js CHANGED
@@ -20012,6 +20012,200 @@ var areaDetailSchema = areaViewSchema.extend({
20012
20012
  routines: exports_external.array(routineViewSchema),
20013
20013
  tasks: exports_external.array(taskViewSchema)
20014
20014
  });
20015
+ // ../../packages/schema/src/contracts/modules.ts
20016
+ var MODULE_KEYS = [
20017
+ "tasks",
20018
+ "habits",
20019
+ "routines",
20020
+ "challenges",
20021
+ "projects",
20022
+ "areas",
20023
+ "notes",
20024
+ "shopping",
20025
+ "inventory",
20026
+ "meals",
20027
+ "library",
20028
+ "watchlist",
20029
+ "games",
20030
+ "cellar",
20031
+ "places",
20032
+ "music",
20033
+ "contacts",
20034
+ "automations"
20035
+ ];
20036
+ var moduleKeySchema = exports_external.enum(MODULE_KEYS);
20037
+ var FEATURE_MODULES = [
20038
+ {
20039
+ key: "today",
20040
+ label: "Today",
20041
+ description: "Your daily dashboard \u2014 always on.",
20042
+ group: "System",
20043
+ defaultEnabled: true,
20044
+ system: true
20045
+ },
20046
+ {
20047
+ key: "inbox",
20048
+ label: "Inbox",
20049
+ description: "Quick capture and triage \u2014 always on.",
20050
+ group: "System",
20051
+ defaultEnabled: true,
20052
+ system: true
20053
+ },
20054
+ {
20055
+ key: "settings",
20056
+ label: "Settings",
20057
+ description: "This screen \u2014 always on.",
20058
+ group: "System",
20059
+ defaultEnabled: true,
20060
+ system: true
20061
+ },
20062
+ {
20063
+ key: "tasks",
20064
+ label: "Tasks",
20065
+ description: "To-dos, due dates, and priorities.",
20066
+ group: "Track",
20067
+ defaultEnabled: true
20068
+ },
20069
+ {
20070
+ key: "habits",
20071
+ label: "Habits",
20072
+ description: "Daily routines and streaks.",
20073
+ group: "Track",
20074
+ defaultEnabled: true
20075
+ },
20076
+ {
20077
+ key: "routines",
20078
+ label: "Routines",
20079
+ description: "Repeatable checklists you run.",
20080
+ group: "Track",
20081
+ defaultEnabled: true
20082
+ },
20083
+ {
20084
+ key: "challenges",
20085
+ label: "Challenges",
20086
+ description: "Time-boxed goals and competitions.",
20087
+ group: "Track",
20088
+ defaultEnabled: true
20089
+ },
20090
+ {
20091
+ key: "projects",
20092
+ label: "Projects",
20093
+ description: "Multi-step work with milestones.",
20094
+ group: "Organize",
20095
+ defaultEnabled: true
20096
+ },
20097
+ {
20098
+ key: "areas",
20099
+ label: "Areas",
20100
+ description: "Ongoing life domains (PARA areas).",
20101
+ group: "Organize",
20102
+ defaultEnabled: true
20103
+ },
20104
+ {
20105
+ key: "notes",
20106
+ label: "Notes",
20107
+ description: "Quick notes and documents.",
20108
+ group: "Organize",
20109
+ defaultEnabled: true
20110
+ },
20111
+ {
20112
+ key: "shopping",
20113
+ label: "Shopping",
20114
+ description: "Lists and groceries.",
20115
+ group: "Household",
20116
+ defaultEnabled: true
20117
+ },
20118
+ {
20119
+ key: "inventory",
20120
+ label: "Inventory",
20121
+ description: "Things you own and stock.",
20122
+ group: "Household",
20123
+ defaultEnabled: true
20124
+ },
20125
+ {
20126
+ key: "meals",
20127
+ label: "Meals",
20128
+ description: "Recipes and meal plans.",
20129
+ group: "Household",
20130
+ defaultEnabled: true
20131
+ },
20132
+ {
20133
+ key: "library",
20134
+ label: "Library",
20135
+ description: "Books and things you catalog.",
20136
+ group: "Collections",
20137
+ defaultEnabled: true
20138
+ },
20139
+ {
20140
+ key: "watchlist",
20141
+ label: "Watchlist",
20142
+ description: "Films and shows to watch.",
20143
+ group: "Collections",
20144
+ defaultEnabled: true
20145
+ },
20146
+ {
20147
+ key: "games",
20148
+ label: "Games",
20149
+ description: "Games to play and backlog.",
20150
+ group: "Collections",
20151
+ defaultEnabled: true
20152
+ },
20153
+ {
20154
+ key: "cellar",
20155
+ label: "Cellar",
20156
+ description: "Wines and bottles you keep.",
20157
+ group: "Collections",
20158
+ defaultEnabled: true
20159
+ },
20160
+ {
20161
+ key: "places",
20162
+ label: "Places",
20163
+ description: "Spots to visit and remember.",
20164
+ group: "Collections",
20165
+ defaultEnabled: true
20166
+ },
20167
+ {
20168
+ key: "music",
20169
+ label: "Music",
20170
+ description: "Albums and records to hear.",
20171
+ group: "Collections",
20172
+ defaultEnabled: true
20173
+ },
20174
+ {
20175
+ key: "contacts",
20176
+ label: "Contacts",
20177
+ description: "People and relationships.",
20178
+ group: "People",
20179
+ defaultEnabled: true
20180
+ },
20181
+ {
20182
+ key: "automations",
20183
+ label: "Automations",
20184
+ description: "Trigger \u2192 condition \u2192 action rules.",
20185
+ group: "Manage",
20186
+ defaultEnabled: true
20187
+ }
20188
+ ];
20189
+ var TOGGLEABLE_MODULES = FEATURE_MODULES.filter((m) => !m.system);
20190
+ function isModuleKey(value) {
20191
+ return MODULE_KEYS.includes(value);
20192
+ }
20193
+ function normalizeEnabledModules(keys) {
20194
+ const present = new Set(keys.filter(isModuleKey));
20195
+ return MODULE_KEYS.filter((key) => present.has(key));
20196
+ }
20197
+ function effectiveEnabledModules(enabled) {
20198
+ const known = normalizeEnabledModules(enabled ?? []);
20199
+ return known.length > 0 ? known : [...MODULE_KEYS];
20200
+ }
20201
+ function setModuleEnabled(enabled, key, on) {
20202
+ const next = new Set(effectiveEnabledModules(enabled));
20203
+ if (on)
20204
+ next.add(key);
20205
+ else
20206
+ next.delete(key);
20207
+ return MODULE_KEYS.filter((candidate) => next.has(candidate));
20208
+ }
20015
20209
  // ../../packages/schema/src/contracts/settings.ts
20016
20210
  var settingsThemeSchema = exports_external.enum(settingsTheme.enumValues);
20017
20211
  var settingsDensitySchema = exports_external.enum(settingsDensity.enumValues);
@@ -20028,7 +20222,7 @@ var updateUserSettingsInputSchema = exports_external.object({
20028
20222
  theme: settingsThemeSchema.optional(),
20029
20223
  density: settingsDensitySchema.optional(),
20030
20224
  accent: settingsAccentSchema.optional(),
20031
- enabledModules: exports_external.array(exports_external.string().trim().min(1)).optional()
20225
+ enabledModules: exports_external.array(exports_external.string().trim().min(1)).transform(normalizeEnabledModules).optional()
20032
20226
  }).strict();
20033
20227
  // ../../packages/schema/src/contracts/notifications.ts
20034
20228
  var notificationTypeSchema = exports_external.enum(["task_due", "occurrence_due"]);
@@ -23306,7 +23500,7 @@ function parseCapture2(input) {
23306
23500
 
23307
23501
  // src/meta.ts
23308
23502
  var CLI_NAME = "do";
23309
- var VERSION = "1.42.0";
23503
+ var VERSION = "1.44.0";
23310
23504
  var API_PREFIX = "/api/v1";
23311
23505
  var DEFAULT_API_URL = "http://localhost:3001";
23312
23506
 
@@ -23596,6 +23790,102 @@ var ENTITIES = [
23596
23790
  canDelete: true
23597
23791
  }
23598
23792
  },
23793
+ {
23794
+ name: "library",
23795
+ path: "/library",
23796
+ readScope: "collections:read",
23797
+ returns: "ShoppingList",
23798
+ canGet: true,
23799
+ listFlags: [],
23800
+ write: {
23801
+ scope: "collections:write",
23802
+ createSchema: createShoppingListInputSchema,
23803
+ createInput: "CreateShoppingListInput",
23804
+ updateSchema: updateShoppingListInputSchema,
23805
+ updateInput: "UpdateShoppingListInput",
23806
+ canDelete: true
23807
+ }
23808
+ },
23809
+ {
23810
+ name: "watchlist",
23811
+ path: "/watchlist",
23812
+ readScope: "collections:read",
23813
+ returns: "ShoppingList",
23814
+ canGet: true,
23815
+ listFlags: [],
23816
+ write: {
23817
+ scope: "collections:write",
23818
+ createSchema: createShoppingListInputSchema,
23819
+ createInput: "CreateShoppingListInput",
23820
+ updateSchema: updateShoppingListInputSchema,
23821
+ updateInput: "UpdateShoppingListInput",
23822
+ canDelete: true
23823
+ }
23824
+ },
23825
+ {
23826
+ name: "games",
23827
+ path: "/games",
23828
+ readScope: "collections:read",
23829
+ returns: "ShoppingList",
23830
+ canGet: true,
23831
+ listFlags: [],
23832
+ write: {
23833
+ scope: "collections:write",
23834
+ createSchema: createShoppingListInputSchema,
23835
+ createInput: "CreateShoppingListInput",
23836
+ updateSchema: updateShoppingListInputSchema,
23837
+ updateInput: "UpdateShoppingListInput",
23838
+ canDelete: true
23839
+ }
23840
+ },
23841
+ {
23842
+ name: "cellar",
23843
+ path: "/cellar",
23844
+ readScope: "collections:read",
23845
+ returns: "ShoppingList",
23846
+ canGet: true,
23847
+ listFlags: [],
23848
+ write: {
23849
+ scope: "collections:write",
23850
+ createSchema: createShoppingListInputSchema,
23851
+ createInput: "CreateShoppingListInput",
23852
+ updateSchema: updateShoppingListInputSchema,
23853
+ updateInput: "UpdateShoppingListInput",
23854
+ canDelete: true
23855
+ }
23856
+ },
23857
+ {
23858
+ name: "places",
23859
+ path: "/places",
23860
+ readScope: "collections:read",
23861
+ returns: "ShoppingList",
23862
+ canGet: true,
23863
+ listFlags: [],
23864
+ write: {
23865
+ scope: "collections:write",
23866
+ createSchema: createShoppingListInputSchema,
23867
+ createInput: "CreateShoppingListInput",
23868
+ updateSchema: updateShoppingListInputSchema,
23869
+ updateInput: "UpdateShoppingListInput",
23870
+ canDelete: true
23871
+ }
23872
+ },
23873
+ {
23874
+ name: "music",
23875
+ path: "/music",
23876
+ readScope: "collections:read",
23877
+ returns: "ShoppingList",
23878
+ canGet: true,
23879
+ listFlags: [],
23880
+ write: {
23881
+ scope: "collections:write",
23882
+ createSchema: createShoppingListInputSchema,
23883
+ createInput: "CreateShoppingListInput",
23884
+ updateSchema: updateShoppingListInputSchema,
23885
+ updateInput: "UpdateShoppingListInput",
23886
+ canDelete: true
23887
+ }
23888
+ },
23599
23889
  {
23600
23890
  name: "inventory-items",
23601
23891
  path: "/inventory-items",
@@ -23786,6 +24076,57 @@ var COMMAND_SPECS = [
23786
24076
  scopes: ["settings:write"],
23787
24077
  returns: "UserSettings"
23788
24078
  },
24079
+ {
24080
+ path: ["modules", "list"],
24081
+ summary: "List feature-modules and whether each is enabled for the caller.",
24082
+ args: [],
24083
+ flags: [],
24084
+ scopes: ["settings:read"],
24085
+ returns: "ModuleStatus",
24086
+ notes: "Reads enabledModules from GET /api/v1/settings; an empty set means every module is on."
24087
+ },
24088
+ {
24089
+ path: ["modules", "enable"],
24090
+ summary: "Enable a feature-module (surfaces it in nav / quick-add / \u2318K).",
24091
+ args: [{ name: "key", required: true, description: "Module key (see `do modules list`)." }],
24092
+ flags: [],
24093
+ scopes: ["settings:read", "settings:write"],
24094
+ returns: "UserSettings",
24095
+ notes: "Reads then patches settings; only the module visibility list changes."
24096
+ },
24097
+ {
24098
+ path: ["modules", "disable"],
24099
+ summary: "Disable a feature-module (hides its surfaces \u2014 nothing is deleted).",
24100
+ args: [{ name: "key", required: true, description: "Module key (see `do modules list`)." }],
24101
+ flags: [],
24102
+ scopes: ["settings:read", "settings:write"],
24103
+ returns: "UserSettings",
24104
+ notes: "Reads then patches settings; only the module visibility list changes."
24105
+ },
24106
+ {
24107
+ path: ["presets", "list"],
24108
+ summary: "List the preset gallery (key \xB7 name \xB7 entity).",
24109
+ args: [],
24110
+ flags: [
24111
+ {
24112
+ name: "entity",
24113
+ type: "string",
24114
+ description: "Filter to one gallery facet (habit|list|library|watchlist|games|cellar|places|music|routine|area|project|recipe|contact|challenge|automation)."
24115
+ }
24116
+ ],
24117
+ scopes: ["presets:read"],
24118
+ returns: "Preset",
24119
+ notes: "The catalog is code-defined; --entity filters it client-side."
24120
+ },
24121
+ {
24122
+ path: ["presets", "install"],
24123
+ summary: "Install a preset into the Space; prints the nodes it created.",
24124
+ args: [{ name: "key", required: true, description: "Preset catalog key (kebab-case)." }],
24125
+ flags: [],
24126
+ scopes: ["presets:install"],
24127
+ returns: "PresetInstallResult",
24128
+ notes: "Authors content as the caller, so it needs a key minted while logged in."
24129
+ },
23789
24130
  {
23790
24131
  path: ["invite", "create"],
23791
24132
  summary: "Create a Space invite (email/link/guest).",
@@ -24249,6 +24590,27 @@ function idOf(row) {
24249
24590
  }
24250
24591
  return;
24251
24592
  }
24593
+ function renderPresetList(data, mode) {
24594
+ if (!Array.isArray(data))
24595
+ return renderRecord(data, mode);
24596
+ if (data.length === 0)
24597
+ return paint(mode, "dim", "(no presets)");
24598
+ const lines = data.map((p) => {
24599
+ const key = paint(mode, "bold", p.key ?? "(no key)");
24600
+ const facet = p.entity ? paint(mode, "dim", ` [${p.entity}]`) : "";
24601
+ return ` ${key} ${p.name ?? ""}${facet}`;
24602
+ });
24603
+ return [`${data.length} preset(s):`, ...lines].join(`
24604
+ `);
24605
+ }
24606
+ function renderPresetInstall(data, mode) {
24607
+ const r = data;
24608
+ const header = `installed ${paint(mode, "bold", r.key ?? "(preset)")} \u2014 ${r.nodeCount ?? 0} node(s) created`;
24609
+ const facet = r.entity ? [` entity: ${r.entity}`] : [];
24610
+ const ids = (r.nodeIds ?? []).map((id) => ` ${paint(mode, "dim", id)}`);
24611
+ return [header, ...facet, ...ids].join(`
24612
+ `);
24613
+ }
24252
24614
  function renderHelp(data, mode) {
24253
24615
  const m = data;
24254
24616
  const lines = [];
@@ -24492,6 +24854,35 @@ var HANDLERS = {
24492
24854
  const body = parseInput(updateUserSettingsInputSchema, readDataFlag(flags));
24493
24855
  return { data: await requireClient().patch("/settings", body), render: renderRecord };
24494
24856
  },
24857
+ "modules list": async ({ requireClient }) => {
24858
+ const settings2 = await requireClient().get("/settings");
24859
+ const enabled = new Set(effectiveEnabledModules(settings2.enabledModules));
24860
+ const rows = FEATURE_MODULES.map((module) => ({
24861
+ key: module.key,
24862
+ label: module.label,
24863
+ group: module.group,
24864
+ enabled: module.system ? true : enabled.has(module.key),
24865
+ system: Boolean(module.system),
24866
+ default: module.defaultEnabled
24867
+ }));
24868
+ return { data: rows, render: renderList };
24869
+ },
24870
+ "modules enable": async ({ args, requireClient }) => setModuleVisibility(args, requireClient, true),
24871
+ "modules disable": async ({ args, requireClient }) => setModuleVisibility(args, requireClient, false),
24872
+ "presets list": async ({ flags, requireClient }) => {
24873
+ const entity = flagString(flags, "entity");
24874
+ if (entity !== undefined && !presetEntitySchema.safeParse(entity).success) {
24875
+ throw usageError(`--entity must be one of: ${presetEntitySchema.options.join(", ")}`);
24876
+ }
24877
+ const catalog2 = presetSchema.array().parse(await requireClient().get("/presets"));
24878
+ const presets2 = entity ? catalog2.filter((p) => p.entity === entity) : catalog2;
24879
+ return { data: presets2, render: renderPresetList };
24880
+ },
24881
+ "presets install": async ({ args, requireClient }) => {
24882
+ const key = requireArg(args, 0, "preset key");
24883
+ const result = presetInstallResultSchema.parse(await requireClient().post(`/presets/${encodeURIComponent(key)}/install`, undefined));
24884
+ return { data: result, render: renderPresetInstall };
24885
+ },
24495
24886
  "invite create": async ({ flags, requireClient }) => {
24496
24887
  const body = parseInput(createInviteInputSchema, { id: ulid3(), ...readDataFlag(flags) });
24497
24888
  return { data: await requireClient().post("/invites", body), render: renderRecord };
@@ -24666,6 +25057,17 @@ var HANDLERS = {
24666
25057
  render: () => `${CLI_NAME} ${VERSION}`
24667
25058
  })
24668
25059
  };
25060
+ async function setModuleVisibility(args, requireClient, on) {
25061
+ const key = requireArg(args, 0, "module key");
25062
+ if (!isModuleKey(key)) {
25063
+ throw usageError(`unknown module \`${key}\` \u2014 valid keys: ${MODULE_KEYS.join(", ")}`);
25064
+ }
25065
+ const client = requireClient();
25066
+ const settings2 = await client.get("/settings");
25067
+ const enabledModules = setModuleEnabled(settings2.enabledModules, key, on);
25068
+ const body = parseInput(updateUserSettingsInputSchema, { enabledModules });
25069
+ return { data: await client.patch("/settings", body), render: renderRecord };
25070
+ }
24669
25071
  function requireArg(args, index2, name) {
24670
25072
  const value = args[index2];
24671
25073
  if (value === undefined || value.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robbeverhelst/do",
3
- "version": "1.42.0",
3
+ "version": "1.44.0",
4
4
  "private": false,
5
5
  "description": "do — the agent-drivable CLI over the public /api/v1 surface",
6
6
  "type": "module",