@danypops/papyrus 0.29.3 → 0.29.4

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.
@@ -150,6 +150,23 @@ async function resolveArtifactIdByName(listOperation: OperationName, baseRequest
150
150
  return matchArtifactByName(candidates, name);
151
151
  }
152
152
 
153
+ /**
154
+ * Playbook `arguments` is intentionally untyped in this tool's schema (an array on create, a
155
+ * {name: value} map on invoke) -- unlike every other JSON-shaped field here, which has a concrete
156
+ * array/record schema the calling layer can serialize correctly. A genuinely schema-less field can
157
+ * arrive pre-serialized as JSON text instead of a parsed value; parse it back in place before it
158
+ * reaches the service, the same tolerance the CLI's own --arguments-json/--*-json flags already give.
159
+ */
160
+ export function normalizeJsonEncodedField(params: Record<string, unknown>, key: string): void {
161
+ const value = params[key];
162
+ if (typeof value !== "string") return;
163
+ try {
164
+ params[key] = JSON.parse(value);
165
+ } catch {
166
+ throw new Error(`${key} must be valid JSON`);
167
+ }
168
+ }
169
+
153
170
  /** Resolves every {nameKey -> idKey} pair present and not already satisfied by an explicit id, in place. */
154
171
  async function resolveNameFields(
155
172
  params: Record<string, unknown>,
@@ -610,6 +627,7 @@ export function registerDomainTools(pi: ExtensionAPI): void {
610
627
  await resolveNameFields(params, [
611
628
  { nameKey: "name", idKey: "id", listOperation: "playbooks.list", baseRequest: { project_root: params.project_root } },
612
629
  ]);
630
+ if (action === "create" || action === "invoke") normalizeJsonEncodedField(params, "arguments");
613
631
  if (action === "create") {
614
632
  const artifact = await callService<Record<string, unknown>, Artifact>("playbooks.create", params);
615
633
  return text(`Created playbook ${artifactLine(artifact)}`, createArtifactDetails("playbooks.create", artifact));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danypops/papyrus",
3
- "version": "0.29.3",
3
+ "version": "0.29.4",
4
4
  "description": "Daemon-backed graph artifacts, evidence-bearing tasks, rules, skills, and native TUI workflows for Pi",
5
5
  "type": "module",
6
6
  "keywords": ["pi-package"],
package/src/cli.ts CHANGED
@@ -112,7 +112,7 @@ const USAGE = `Usage:
112
112
  papyrus skills instantiate <template-id> [--title <title>] [--body <body>] [--status <status>] [--labels-json <json>] [--extra-json <json>] [--json]
113
113
  papyrus skills assign-project <id> [project-root] [--json]
114
114
  papyrus skills update <id> [--title <title>] [--body <body>] [--labels-json <json>] [--json]
115
- papyrus playbooks create --title <title> [--body <body>] [--trigger <text>] [--steps-json <json>] [--tools-json <json>] [--labels-json <json>] [--extra-json <json>] [--project-root <path>] [--json]
115
+ papyrus playbooks create --title <title> [--body <body>] [--trigger <text>] [--steps-json <json>] [--tools-json <json>] [--labels-json <json>] [--extra-json <json>] [--arguments-json <json>] [--project-root <path>] [--json]
116
116
  papyrus playbooks list [--status <status>] [--text <query>] [--limit <count>] [--project-root <path>] [--json]
117
117
  papyrus playbooks show <id> [--json]
118
118
  papyrus playbooks invoke <id> [--json]
@@ -201,6 +201,14 @@ function parseJsonStringArrayFlag(value: string | undefined, flag: string): stri
201
201
  return parsed as string[];
202
202
  }
203
203
 
204
+ /** Top-level shape only -- element shape (e.g. {name, description?, required?}) is validated server-side. */
205
+ function parseJsonArrayFlag(value: string | undefined, flag: string): unknown[] {
206
+ if (value === undefined) throw new Error(`${flag} requires a value`);
207
+ const parsed = JSON.parse(value) as unknown;
208
+ if (!Array.isArray(parsed)) throw new Error(`${flag} must be a JSON array`);
209
+ return parsed;
210
+ }
211
+
204
212
  function artifactLabel(artifact: CliArtifact): string {
205
213
  return `${artifact.id} ${artifact.title}`;
206
214
  }
@@ -786,6 +794,7 @@ export async function runPlaybooksCli(args: string[], client: TaskCliClient): Pr
786
794
  let tools: string[] | undefined;
787
795
  let labels: string[] | undefined;
788
796
  let extra: Record<string, unknown> | undefined;
797
+ let playbookArguments: unknown[] | undefined;
789
798
  let status: string | undefined;
790
799
  let text: string | undefined;
791
800
  let limit: number | undefined;
@@ -800,6 +809,7 @@ export async function runPlaybooksCli(args: string[], client: TaskCliClient): Pr
800
809
  if (argument === "--tools-json") { tools = parseJsonStringArrayFlag(args[++index], "--tools-json"); continue; }
801
810
  if (argument === "--labels-json") { labels = parseJsonStringArrayFlag(args[++index], "--labels-json"); continue; }
802
811
  if (argument === "--extra-json") { extra = parseJsonObjectFlag(args[++index], "--extra-json"); continue; }
812
+ if (argument === "--arguments-json") { playbookArguments = parseJsonArrayFlag(args[++index], "--arguments-json"); continue; }
803
813
  if (argument === "--status") { status = args[++index]; if (!status) throw new Error("--status requires a value"); continue; }
804
814
  if (argument === "--text") { text = args[++index]; if (text === undefined) throw new Error("--text requires a value"); continue; }
805
815
  if (argument === "--project-root") { playbookProjectRoot = args[++index]; if (!playbookProjectRoot) throw new Error("--project-root requires a value"); continue; }
@@ -819,7 +829,7 @@ export async function runPlaybooksCli(args: string[], client: TaskCliClient): Pr
819
829
  case "create": {
820
830
  if (id) throw new Error("playbooks create accepts no positional arguments");
821
831
  if (!title) throw new Error("playbooks create requires --title");
822
- const artifact = await client.call<Record<string, unknown>, CliArtifact>("playbooks.create", { title, body, trigger, steps, tools, labels, extra, project_root: playbookProjectRoot });
832
+ const artifact = await client.call<Record<string, unknown>, CliArtifact>("playbooks.create", { title, body, trigger, steps, tools, labels, extra, arguments: playbookArguments, project_root: playbookProjectRoot });
823
833
  result = artifact;
824
834
  human = `Created playbook: ${artifactLabel(artifact)}`;
825
835
  break;