@putdotio/cli 1.2.1 → 1.2.3

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
@@ -44,7 +44,7 @@ curl -fsSL https://raw.githubusercontent.com/putdotio/putio-cli/main/install.sh
44
44
  npm install --global @putdotio/cli
45
45
  ```
46
46
 
47
- Node `24.14+`
47
+ Node `>=24.14 <25`
48
48
 
49
49
  Verify:
50
50
 
@@ -73,7 +73,7 @@ If `putio` is not installed, follow the install instructions in the repository R
73
73
  https://github.com/putdotio/putio-cli/blob/main/README.md
74
74
 
75
75
  After install, run:
76
- putio describe
76
+ putio describe --output json
77
77
  putio auth status --profile devs-fe-auto --output json
78
78
 
79
79
  If auth is missing, start login with:
@@ -96,7 +96,7 @@ Rules:
96
96
  Inspect the live contract:
97
97
 
98
98
  ```bash
99
- putio describe
99
+ putio describe --output json
100
100
  ```
101
101
 
102
102
  Link your account:
package/dist/bin.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { A as CliOutputLive, F as CliRuntime, I as CliRuntimeLive, L as translate, M as isStructuredOutputMode, N as renderJson, O as CliSdkLive, P as CliConfigLive, R as version, a as searchCommand, c as brandCommand, g as CliStateLive, i as filesCommand, j as detectOutputModeFromArgv, k as CliOutput, l as versionCommand, n as whoamiCommand, o as eventsCommand, r as transfersCommand, s as downloadLinksCommand, t as describeCli, u as makeAuthCommand } from "./metadata-B7hMX4g9.mjs";
2
+ import { A as CliSdkLive, B as translate, F as renderJson, I as writeOutput, L as CliConfigLive, M as CliOutputLive, N as detectOutputModeFromArgv, P as isStructuredOutputMode, R as CliRuntime, V as version, a as searchCommand, c as brandCommand, d as getOption, f as outputOption, i as filesCommand, j as CliOutput, l as versionCommand, n as whoamiCommand, o as eventsCommand, r as transfersCommand, s as downloadLinksCommand, t as describeCli, u as makeAuthCommand, v as CliStateLive, z as CliRuntimeLive } from "./metadata-CSXfRQuw.mjs";
3
3
  import { Cause, Console, Effect, Layer, Result } from "effect";
4
4
  import { CliError, Command } from "effect/unstable/cli";
5
5
  import { NodeRuntime, NodeServices } from "@effect/platform-node";
6
6
  //#region src/cli.ts
7
7
  const authCommand = makeAuthCommand();
8
- const describeCommand = Command.make("describe", {}, () => Console.log(renderJson(describeCli())));
8
+ const describeCommand = Command.make("describe", { output: outputOption }, ({ output }) => writeOutput(describeCli(), getOption(output), renderJson));
9
9
  const command = Command.make("putio", {}, () => Console.log(translate("cli.root.help"))).pipe(Command.withSubcommands([
10
10
  describeCommand,
11
11
  brandCommand,
@@ -107,13 +107,24 @@ const executableName = (value) => {
107
107
  const normalized = value.replaceAll("\\", "/");
108
108
  return normalized.slice(normalized.lastIndexOf("/") + 1).toLowerCase();
109
109
  };
110
+ const isNodeExecutable = (value) => {
111
+ const name = executableName(value);
112
+ return name === "node" || name === "node.exe";
113
+ };
114
+ const isPutioExecutable = (value) => {
115
+ const name = executableName(value);
116
+ return name === "putio" || name === "putio.exe" || name === "bin.mjs";
117
+ };
118
+ const stripLeadingPutioExecutables = (args) => {
119
+ let start = 0;
120
+ while (isPutioExecutable(args[start] ?? "")) start++;
121
+ return args.slice(start);
122
+ };
110
123
  const commandArgsFromArgv = (args) => {
111
124
  const [first] = args;
112
125
  if (first === void 0) return args;
113
- const firstName = executableName(first);
114
- if (firstName === "node" || firstName === "node.exe") return args.slice(2);
115
- if (firstName === "putio" || firstName === "putio.exe" || firstName === "bin.mjs") return args.slice(1);
116
- return args;
126
+ if (isNodeExecutable(first)) return stripLeadingPutioExecutables(args.slice(2));
127
+ return stripLeadingPutioExecutables(args);
117
128
  };
118
129
  function runCli(args) {
119
130
  const run = Command.runWith(command, { version });
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { C as loadPersistedState, D as useProfile, E as savePersistedState, S as listProfiles, T as resolveAuthState, _ as PutioCliConfigSchema, b as clearPersistedState, d as AuthProfileListSchema, f as AuthProfileSummarySchema, g as CliStateLive, h as CliState, m as AuthStatusSchema, p as AuthStateError, t as describeCli, v as PutioCliProfileConfigSchema, w as removeProfile, x as getAuthStatus, y as ResolvedAuthStateSchema } from "./metadata-B7hMX4g9.mjs";
1
+ import { C as getAuthStatus, D as resolveAuthState, E as removeProfile, O as savePersistedState, S as clearPersistedState, T as loadPersistedState, _ as CliState, b as PutioCliProfileConfigSchema, g as AuthStatusSchema, h as AuthStateError, k as useProfile, m as AuthProfileSummarySchema, p as AuthProfileListSchema, t as describeCli, v as CliStateLive, w as listProfiles, x as ResolvedAuthStateSchema, y as PutioCliConfigSchema } from "./metadata-CSXfRQuw.mjs";
2
2
  export { AuthProfileListSchema, AuthProfileSummarySchema, AuthStateError, AuthStatusSchema, CliState, CliStateLive, PutioCliConfigSchema, PutioCliProfileConfigSchema, ResolvedAuthStateSchema, clearPersistedState, describeCli, getAuthStatus, listProfiles, loadPersistedState, removeProfile, resolveAuthState, savePersistedState, useProfile };
@@ -13,7 +13,7 @@ import * as FileSystem from "effect/FileSystem";
13
13
  import { PlatformError, SystemError } from "effect/PlatformError";
14
14
  //#region package.json
15
15
  var name = "@putdotio/cli";
16
- var version = "1.2.1";
16
+ var version = "1.2.3";
17
17
  //#endregion
18
18
  //#region src/i18n/translate.ts
19
19
  const resources = { en: { translation: {
@@ -372,100 +372,6 @@ const createTranslator = (locale = "en") => {
372
372
  };
373
373
  const translate = createTranslator();
374
374
  //#endregion
375
- //#region src/internal/agent-dx.ts
376
- const AgentDxCategoryNameSchema = Schema.Literals([
377
- "machineReadableOutput",
378
- "rawPayloadInput",
379
- "schemaIntrospection",
380
- "contextWindowDiscipline",
381
- "inputHardening",
382
- "safetyRails",
383
- "agentKnowledgePackaging"
384
- ]);
385
- const AgentDxDimensionSchema = Schema.Struct({
386
- maxScore: Schema.Literal(3),
387
- name: AgentDxCategoryNameSchema,
388
- score: Schema.Number,
389
- summary: Schema.String
390
- });
391
- const AgentDxScorecardSchema = Schema.Struct({
392
- dimensions: Schema.Array(AgentDxDimensionSchema),
393
- maxScore: Schema.Literal(21),
394
- provenance: Schema.Literal("metadata-derived"),
395
- summary: Schema.String,
396
- totalScore: Schema.Number
397
- });
398
- const commandHasFlag = (command, flagName) => command.input.flags.some((flag) => flag.name === flagName);
399
- const cursorReadCommands = [
400
- "files list",
401
- "files search",
402
- "search",
403
- "transfers list"
404
- ];
405
- const streamingReadCommands = [...cursorReadCommands, "transfers watch"];
406
- const scoreAgentDx = (input) => {
407
- const writeCommands = input.commands.filter((command) => command.kind === "write");
408
- const readCommands = input.commands.filter((command) => command.kind === "read");
409
- const dimensions = [
410
- {
411
- maxScore: 3,
412
- name: "machineReadableOutput",
413
- score: input.output.defaultNonInteractive === "json" && input.output.supported.includes("json") && input.output.supported.includes("ndjson") ? 3 : input.output.supported.includes("json") ? 2 : 1,
414
- summary: "Structured JSON is the non-interactive default, and NDJSON is available for streaming read flows."
415
- },
416
- {
417
- maxScore: 3,
418
- name: "rawPayloadInput",
419
- score: writeCommands.length > 0 && writeCommands.every((command) => command.capabilities.rawJsonInput && command.input.json !== void 0) ? 3 : writeCommands.some((command) => command.capabilities.rawJsonInput) ? 2 : 0,
420
- summary: "Every mutating command accepts raw --json input and advertises its payload contract in describe."
421
- },
422
- {
423
- maxScore: 3,
424
- name: "schemaIntrospection",
425
- score: input.commands.every((command) => command.purpose.length > 0 && Array.isArray(command.input.flags) && (!command.capabilities.rawJsonInput || command.input.json !== void 0)) ? 3 : 2,
426
- summary: "Describe exposes command purpose, flags, defaults, choices, capabilities, and raw JSON shapes."
427
- },
428
- {
429
- maxScore: 3,
430
- name: "contextWindowDiscipline",
431
- score: readCommands.every((command) => command.capabilities.fieldSelection) && cursorReadCommands.every((commandName) => {
432
- const command = input.commands.find((candidate) => candidate.command === commandName);
433
- return command !== void 0 && command.capabilities.streaming && commandHasFlag(command, "page-all");
434
- }) && streamingReadCommands.every((commandName) => {
435
- const command = input.commands.find((candidate) => candidate.command === commandName);
436
- return command !== void 0 && command.capabilities.streaming;
437
- }) ? 3 : 2,
438
- summary: "Read commands support field filtering broadly, and cursor-backed reads plus watch flows expose streaming-friendly output."
439
- },
440
- {
441
- maxScore: 3,
442
- name: "inputHardening",
443
- score: input.commands.some((command) => command.input.flags.some((flag) => flag.name === "fields" && flag.description?.includes("rejects") === true)) && writeCommands.some((command) => command.input.json?.kind === "object" && command.input.json.rules) ? 2 : 1,
444
- summary: "The CLI rejects malformed selectors and unsafe identifier-like inputs before API calls, though there is still room to deepen the boundary model."
445
- },
446
- {
447
- maxScore: 3,
448
- name: "safetyRails",
449
- score: writeCommands.every((command) => command.capabilities.dryRun) ? 2 : 1,
450
- summary: "Mutating commands offer dry-run planning across the surface, but the CLI does not yet add stronger confirmation or policy layers beyond that."
451
- },
452
- {
453
- maxScore: 3,
454
- name: "agentKnowledgePackaging",
455
- score: input.hasConsumerSkill ? 2 : 0,
456
- summary: "The repo ships a dedicated consumer skill with progressive disclosure references, even though it is still a single skill rather than a broader skill library."
457
- }
458
- ];
459
- const totalScore = dimensions.reduce((total, dimension) => total + dimension.score, 0);
460
- return {
461
- dimensions: [...dimensions],
462
- maxScore: 21,
463
- provenance: "metadata-derived",
464
- summary: "This score is derived from described command metadata and documented agent surfaces, not from a full runtime conformance audit.",
465
- totalScore
466
- };
467
- };
468
- //#endregion
469
375
  //#region src/internal/constants.ts
470
376
  const PUTIO_CLI_APP_ID = "8993";
471
377
  //#endregion
@@ -3853,7 +3759,7 @@ const commandCatalog = decodeCommandSpecs([
3853
3759
  streaming: false
3854
3760
  },
3855
3761
  command: "describe",
3856
- input: { flags: [] },
3762
+ input: { flags: [outputFlag()] },
3857
3763
  kind: "utility",
3858
3764
  purpose: translate("cli.metadata.describe")
3859
3765
  },
@@ -3876,8 +3782,25 @@ const PersistedProfileShapeSchema = Schema.Struct({
3876
3782
  api_base_url: ConfigStringFieldSchema,
3877
3783
  auth_token: ConfigStringFieldSchema
3878
3784
  });
3785
+ const SupportedOutputModeSchema = Schema.Literals([
3786
+ "json",
3787
+ "text",
3788
+ "ndjson"
3789
+ ]);
3790
+ const AutomationContractSchema = Schema.Struct({
3791
+ consumerSkillLibrary: Schema.Boolean,
3792
+ defaultNonInteractiveOutput: Schema.Literal("json"),
3793
+ dryRunForWrites: Schema.Boolean,
3794
+ fieldSelectionForReads: Schema.Boolean,
3795
+ rawJsonInputForWrites: Schema.Boolean,
3796
+ schemaIntrospection: Schema.Boolean,
3797
+ secretRedaction: Schema.Boolean,
3798
+ streamingReadCommands: Schema.Array(NonEmptyStringSchema),
3799
+ supportedOutputModes: Schema.Array(SupportedOutputModeSchema),
3800
+ untrustedTextAnnotations: Schema.Boolean
3801
+ });
3879
3802
  const CliMetadataSchema = Schema.Struct({
3880
- agentDx: AgentDxScorecardSchema,
3803
+ automation: AutomationContractSchema,
3881
3804
  auth: Schema.Struct({
3882
3805
  apiBaseUrlEnv: NonEmptyStringSchema,
3883
3806
  envPrecedence: Schema.Array(NonEmptyStringSchema),
@@ -3905,25 +3828,28 @@ const CliMetadataSchema = Schema.Struct({
3905
3828
  version: NonEmptyStringSchema
3906
3829
  });
3907
3830
  const decodeCliMetadata = Schema.decodeUnknownSync(CliMetadataSchema);
3831
+ const makeAutomationContract = () => {
3832
+ const readCommands = commandCatalog.filter((command) => command.kind === "read");
3833
+ const writeCommands = commandCatalog.filter((command) => command.kind === "write");
3834
+ return {
3835
+ consumerSkillLibrary: true,
3836
+ defaultNonInteractiveOutput: "json",
3837
+ dryRunForWrites: writeCommands.every((command) => command.capabilities.dryRun),
3838
+ fieldSelectionForReads: readCommands.every((command) => command.capabilities.fieldSelection),
3839
+ rawJsonInputForWrites: writeCommands.every((command) => command.capabilities.rawJsonInput),
3840
+ schemaIntrospection: true,
3841
+ secretRedaction: true,
3842
+ streamingReadCommands: commandCatalog.filter((command) => command.capabilities.streaming).map((command) => command.command),
3843
+ supportedOutputModes: [
3844
+ "json",
3845
+ "text",
3846
+ "ndjson"
3847
+ ],
3848
+ untrustedTextAnnotations: true
3849
+ };
3850
+ };
3908
3851
  const describeCli = () => decodeCliMetadata({
3909
- agentDx: scoreAgentDx({
3910
- commands: commandCatalog,
3911
- hasConsumerSkill: true,
3912
- output: {
3913
- defaultInteractive: "text",
3914
- defaultNonInteractive: "json",
3915
- internalRenderers: [
3916
- "json",
3917
- "terminal",
3918
- "ndjson"
3919
- ],
3920
- supported: [
3921
- "json",
3922
- "text",
3923
- "ndjson"
3924
- ]
3925
- }
3926
- }),
3852
+ automation: makeAutomationContract(),
3927
3853
  auth: {
3928
3854
  apiBaseUrlEnv: ENV_API_BASE_URL,
3929
3855
  envPrecedence: [ENV_CLI_TOKEN],
@@ -3982,4 +3908,4 @@ const describeCli = () => decodeCliMetadata({
3982
3908
  version
3983
3909
  });
3984
3910
  //#endregion
3985
- export { CliOutputLive as A, loadPersistedState as C, useProfile as D, savePersistedState as E, CliRuntime as F, CliRuntimeLive as I, translate as L, isStructuredOutputMode as M, renderJson as N, CliSdkLive as O, CliConfigLive as P, version as R, listProfiles as S, resolveAuthState as T, PutioCliConfigSchema as _, searchCommand as a, clearPersistedState as b, brandCommand as c, AuthProfileListSchema as d, AuthProfileSummarySchema as f, CliStateLive as g, CliState as h, filesCommand as i, detectOutputModeFromArgv as j, CliOutput as k, versionCommand as l, AuthStatusSchema as m, whoamiCommand as n, eventsCommand as o, AuthStateError as p, transfersCommand as r, downloadLinksCommand as s, describeCli as t, makeAuthCommand as u, PutioCliProfileConfigSchema as v, removeProfile as w, getAuthStatus as x, ResolvedAuthStateSchema as y };
3911
+ export { CliSdkLive as A, translate as B, getAuthStatus as C, resolveAuthState as D, removeProfile as E, renderJson as F, writeOutput as I, CliConfigLive as L, CliOutputLive as M, detectOutputModeFromArgv as N, savePersistedState as O, isStructuredOutputMode as P, CliRuntime as R, clearPersistedState as S, loadPersistedState as T, version as V, CliState as _, searchCommand as a, PutioCliProfileConfigSchema as b, brandCommand as c, getOption as d, outputOption as f, AuthStatusSchema as g, AuthStateError as h, filesCommand as i, CliOutput as j, useProfile as k, versionCommand as l, AuthProfileSummarySchema as m, whoamiCommand as n, eventsCommand as o, AuthProfileListSchema as p, transfersCommand as r, downloadLinksCommand as s, describeCli as t, makeAuthCommand as u, CliStateLive as v, listProfiles as w, ResolvedAuthStateSchema as x, PutioCliConfigSchema as y, CliRuntimeLive as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putdotio/cli",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Agent-first CLI for the put.io API.",
5
5
  "homepage": "https://github.com/putdotio/putio-cli#readme",
6
6
  "bugs": {
@@ -34,7 +34,7 @@
34
34
  "check": "vp check .",
35
35
  "coverage": "vp test --coverage",
36
36
  "dev": "vp pack --watch",
37
- "prepare": "./scripts/prepare-effect.sh",
37
+ "prepare": "node ./scripts/prepare-effect.mts",
38
38
  "prepack": "vp pack",
39
39
  "smoke:pack": "node ./scripts/smoke-packed-install.mts",
40
40
  "test": "vp test",