appostle-installer 0.0.19 → 0.0.21

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/dist/appostle.js CHANGED
@@ -1922,6 +1922,10 @@ function toAgentPayload(agent, options) {
1922
1922
  title: options?.title ?? null,
1923
1923
  labels: agent.labels,
1924
1924
  internal: agent.internal,
1925
+ // Forward archivedAt on the live broadcast so paired clients (e.g. mobile)
1926
+ // see the archive land — without this, only the device that ran the
1927
+ // archive mutation knows about it.
1928
+ archivedAt: agent.archivedAt ?? null,
1925
1929
  // Surface ownership so the client can render an owner badge / detect
1926
1930
  // "shared with me" agents. `sharedWithUserIds` deliberately stays off
1927
1931
  // the snapshot — only owners read the full ACL, via the dedicated
@@ -3494,6 +3498,7 @@ var GoogleFontsDownloadResponseSchema = z10.object({
3494
3498
  });
3495
3499
 
3496
3500
  // ../server/src/shared/messages.ts
3501
+ var InitialAgentSnapshotPageLimit = 200;
3497
3502
  var MutableDaemonConfigSchema = z11.object({
3498
3503
  mcp: z11.object({
3499
3504
  injectIntoAgents: z11.boolean()
@@ -5986,6 +5991,17 @@ var FetchAgentsResponseMessageSchema = z11.object({
5986
5991
  })
5987
5992
  })
5988
5993
  });
5994
+ var InitialAgentSnapshotMessageSchema = z11.object({
5995
+ type: z11.literal("initial_agent_snapshot"),
5996
+ payload: z11.object({
5997
+ entries: z11.array(
5998
+ z11.object({
5999
+ agent: AgentSnapshotPayloadSchema,
6000
+ project: ProjectPlacementPayloadSchema
6001
+ })
6002
+ )
6003
+ })
6004
+ });
5989
6005
  var FetchWorkspacesResponseMessageSchema = z11.object({
5990
6006
  type: z11.literal("fetch_workspaces_response"),
5991
6007
  payload: z11.object({
@@ -7027,6 +7043,7 @@ var SessionOutboundMessageSchema = z11.discriminatedUnion("type", [
7027
7043
  AgentStreamMessageSchema,
7028
7044
  AgentStatusMessageSchema,
7029
7045
  FetchAgentsResponseMessageSchema,
7046
+ InitialAgentSnapshotMessageSchema,
7030
7047
  FetchWorkspacesResponseMessageSchema,
7031
7048
  OpenProjectResponseMessageSchema,
7032
7049
  StartWorkspaceScriptResponseMessageSchema,
@@ -19464,11 +19481,53 @@ var ClaudeAgentSession = class {
19464
19481
  // sub-agents stop announcing them as suspected prompt injections. See
19465
19482
  // getSystemReminderGuidance for the full rationale.
19466
19483
  getSystemReminderGuidance(),
19467
- "Default response shape: open with a short, scannable plain-English read. 2\u20134 short sentences, one idea each, no comma-chained clauses or em-dash pile-ups. When the read covers 3+ discrete points, use bullets instead of prose. Then the technical detail in dense form (paths, line refs, code) without narration. Don't explain what well-named code already explains. Skip the shape for trivial questions.",
19468
- "For multi-step work with independent chunks, spawn Task subagents instead of doing every tool call yourself. Run them in parallel when chunks don't depend on each other. Keeps your main context lean.",
19484
+ //
19485
+ //
19486
+ //
19487
+ //
19488
+ // ╔══════════════════════════════════════════════════════════════════╗
19489
+ // ║ CUSTOM INSTRUCTIONS — add new system prompt lines below here ║
19490
+ // ║ Each line is a quoted string: "your instruction here", ║
19491
+ // ╚══════════════════════════════════════════════════════════════════╝
19492
+ //
19493
+ //
19494
+ //
19495
+ //
19496
+ "Default response shape: open with a short, scannable plain-English read. 2\u20134 short sentences, one idea each, no comma-chained clauses or em-dash pile-ups. When the read covers 3+ discrete points, use bullets instead of prose. Then the technical detail in dense form (paths, line refs, code) without narration. Don\u2019t explain what well-named code already explains. Skip the shape for trivial questions.",
19497
+ //
19469
19498
  "When the user sends `>learn`, re-explain your previous message in plain English only \u2014 1 short paragraph that helps them build the mental model. No code, no file references, no technical repeat.",
19499
+ //
19500
+ //
19501
+ //
19502
+ //
19503
+ // ╔══════════════════════════════════════════════════════════════════╗
19504
+ // ║ END CUSTOM INSTRUCTIONS — don't edit below this line ║
19505
+ // ╚══════════════════════════════════════════════════════════════════╝
19506
+ //
19507
+ //
19508
+ //
19509
+ //
19470
19510
  this.config.systemPrompt?.trim()
19471
19511
  ].filter((entry) => typeof entry === "string" && entry.length > 0).join("\n\n");
19512
+ const appostleAgents = {
19513
+ researcher: {
19514
+ description: "Use this agent when you need to explore unfamiliar code, trace data flow across modules, search broadly across the codebase, or read more than 2 files you haven't seen yet. Delegate investigation work here to keep the main conversation context lean.",
19515
+ prompt: "You are a codebase researcher. Your job is to investigate, trace, and report findings \u2014 never edit files. Read code, grep for patterns, follow imports, and build a clear picture. Report back a concise summary of what you found: key files, relevant code paths, and your conclusion. Keep your report under 300 words unless the investigation is complex.",
19516
+ model: "sonnet"
19517
+ },
19518
+ refactorer: {
19519
+ description: "Use this agent for refactors that touch more than 2 files \u2014 renames, migrations, pattern replacements, moving code between modules. Delegate multi-file changes here to isolate the blast radius.",
19520
+ prompt: "You are a refactoring specialist. Make the requested changes across all affected files. Be thorough \u2014 update imports, references, types, and tests. Run typecheck after changes if available. Report what you changed and any issues found."
19521
+ },
19522
+ reviewer: {
19523
+ description: "Use this agent to review code for bugs, security issues, performance problems, or style violations. Use it before committing large changes or when the user asks for a review.",
19524
+ prompt: "You are a code reviewer. Analyze the code for correctness, security vulnerabilities (OWASP top 10), performance issues, and adherence to the project's coding standards. Be specific \u2014 cite file paths and line numbers. Flag severity: critical, warning, or nitpick. Keep the review focused and actionable."
19525
+ },
19526
+ debugger: {
19527
+ description: "Use this agent to investigate bugs \u2014 read logs, trace error paths, check database state, reproduce issues. Delegate debugging here when the root cause isn't obvious from a quick look.",
19528
+ prompt: "You are a debugger. Your job is to find the root cause, not patch symptoms. Check real data first \u2014 logs, network requests, database state. Trace the full lifecycle of the bug. Present your findings: root cause, evidence, and a proposed minimal fix. Do not edit files unless explicitly asked."
19529
+ }
19530
+ };
19472
19531
  const claudeBinary = await findExecutable("claude");
19473
19532
  this.logger.debug(
19474
19533
  {
@@ -19486,7 +19545,7 @@ var ClaudeAgentSession = class {
19486
19545
  // bypass launch capability available so later setPermissionMode("bypassPermissions")
19487
19546
  // calls do not fail after a model/thinking/rewind-driven restart.
19488
19547
  allowDangerouslySkipPermissions: true,
19489
- agents: this.defaults?.agents,
19548
+ agents: { ...appostleAgents, ...this.defaults?.agents },
19490
19549
  canUseTool: this.handlePermissionRequest,
19491
19550
  ...claudeBinary ? { pathToClaudeCodeExecutable: claudeBinary } : {},
19492
19551
  // Use Claude Code preset system prompt and load CLAUDE.md files
@@ -35482,71 +35541,28 @@ function buildStructuralContext(allBrands) {
35482
35541
  return lines.length > 0 ? lines.join("\n") : "(No structural context established yet.)";
35483
35542
  }
35484
35543
  var TARGET_QUESTIONS = 7;
35485
- var EMBEDDED_QA_FALLBACK = `## Compositional Philosophy
35486
- - What's the single-sentence design philosophy that should govern every layout decision?
35487
- - What's the ratio of whitespace to content density you're after?
35488
-
35489
- ## Hero Behavior
35490
- - How should the hero section behave? Full viewport takeover, contained module, asymmetric split?
35491
- - Should the hero have scroll-triggered behavior or stay static?
35492
-
35493
- ## Section Variation & Flow
35494
- - How many distinct section types should the page cycle through?
35495
- - Should any sections break out of the main container (full-bleed moments)?
35496
-
35497
- ## Density & Spacing
35498
- - How tight should content be packed within sections?
35499
- - How much vertical breathing room between major sections?
35500
-
35501
- ## Grid System
35502
- - What grid philosophy \u2014 strict 12-column, asymmetric, modular, or freeform?
35503
-
35504
- ## Containers & Cards
35505
- - What's your card philosophy \u2014 flat, elevated, outlined, or glassmorphic?
35506
-
35507
- ## Image Treatment
35508
- - What role do images play \u2014 hero-level, supporting, or minimal?
35509
-
35510
- ## CTA Strategy
35511
- - How many CTAs per page and what's the hierarchy?
35512
-
35513
- ## Mobile Behavior
35514
- - How should the desktop layout transform on mobile?
35515
-
35516
- ## Prohibitions & Bans
35517
- - What design patterns are absolutely forbidden?
35518
- - Any CSS properties or techniques that are banned?`;
35519
- async function loadQaQuestions(logger) {
35520
- const filePath = await findFileUpward(QA_FILENAME);
35521
- if (filePath) {
35522
- try {
35523
- const content = await fs12.readFile(filePath, "utf8");
35524
- logger.debug({ filePath }, "layout-generator: loaded Q&A questions from disk");
35525
- return content;
35526
- } catch (err) {
35527
- logger.warn(
35528
- { err, filePath },
35529
- "layout-generator: failed to read Q&A file; using embedded fallback"
35530
- );
35531
- }
35544
+ async function loadSpecFile(filename, logger) {
35545
+ const filePath = await findFileUpward(filename);
35546
+ if (!filePath) {
35547
+ throw new Error(
35548
+ `layout-generator: ${filename} not found by walking up from ${fileURLToPath2(import.meta.url)}. This file is the canonical spec and must exist at the appostle repo root.`
35549
+ );
35550
+ }
35551
+ try {
35552
+ const content = await fs12.readFile(filePath, "utf8");
35553
+ logger.debug({ filePath }, `layout-generator: loaded ${filename} from disk`);
35554
+ return content;
35555
+ } catch (err) {
35556
+ throw new Error(
35557
+ `layout-generator: failed to read ${filename} at ${filePath}: ${err.message}`
35558
+ );
35532
35559
  }
35533
- return EMBEDDED_QA_FALLBACK;
35560
+ }
35561
+ async function loadQaQuestions(logger) {
35562
+ return loadSpecFile(QA_FILENAME, logger);
35534
35563
  }
35535
35564
  async function loadLayoutPrompt(logger) {
35536
- const filePath = await findFileUpward(PROMPT_FILENAME);
35537
- if (filePath) {
35538
- try {
35539
- const content = await fs12.readFile(filePath, "utf8");
35540
- logger.debug({ filePath }, "layout-generator: loaded layout prompt from disk");
35541
- return content;
35542
- } catch (err) {
35543
- logger.warn(
35544
- { err, filePath },
35545
- "layout-generator: failed to read layout-prompt file; using embedded fallback"
35546
- );
35547
- }
35548
- }
35549
- return EMBEDDED_LAYOUT_PROMPT_FALLBACK;
35565
+ return loadSpecFile(PROMPT_FILENAME, logger);
35550
35566
  }
35551
35567
  function interpolateTemplate(template, vars) {
35552
35568
  let out = template;
@@ -35555,66 +35571,6 @@ function interpolateTemplate(template, vars) {
35555
35571
  }
35556
35572
  return out;
35557
35573
  }
35558
- var EMBEDDED_LAYOUT_PROMPT_FALLBACK = `You are an elite art director refining the layout and composition rules for a brand. This is ONLY about layout \u2014 structure, zones, grid, density, rhythm, containers, image placement, CTAs. Typography, colors, motion, animations, shadows are handled by separate brand files \u2014 do not duplicate them here.
35559
-
35560
- These rules must work across media \u2014 web pages, print, PDF, presentations. Use proportional language (fractions, ratios, percentages) as the primary system. CSS values are welcome as concrete examples but should not be the only expression of a rule.
35561
-
35562
- Your job: update the design role document based on the user's refinement prompt. This document will be injected wholesale into an AI builder's context. If your rules are vague, the output will be generic. If your rules are specific and opinionated, the output will be distinctive.
35563
-
35564
- The document must be a complete markdown document covering:
35565
- - Enemy (a specific design this must NOT resemble, with 2-3 specific layout patterns that make it wrong \u2014 and for each, the exact counter-pattern this brand uses instead)
35566
- - Signature Anomaly (the one structural layout choice that makes this unmistakably distinctive)
35567
- - Compositional Philosophy (one structural law + the structural spine mechanism that enforces it across every zone)
35568
- - Intensity Dials (Density 1-10, Grid Variance 1-10 \u2014 with concrete implications for THIS brand)
35569
- - Opening Zone / Hero Behavior (surface coverage, bleed, content placement, containment)
35570
- - Zone Inventory (ordered list of all major zones: name, layout job, dense/airy, full-bleed/contained \u2014 this is the master reference for the rhythm)
35571
- - Zone Variation & Flow (how zones differ, transition strategy, full-bleed vs contained \u2014 references the Zone Inventory)
35572
- - Density Philosophy (spacing values; the oscillation rhythm derived from the Zone Inventory \u2014 name which zones are dense, which are airy, in sequence)
35573
- - Vertical Rhythm (three values: zone padding, element gap within zones, and the one zone that breaks the rhythm and why)
35574
- - Grid System (exact column structure, asymmetry, proportions)
35575
- - Content Width Strategy (max-width of the primary content area, which zones break it and why)
35576
- - Container & Card Rules (borders, corners, nesting, exact border-radius)
35577
- - Dividers & Graphic Structure (structural vs decorative, background strategy)
35578
- - Image Treatment \u2014 Layout Only (placement, grid relationship, overlap behavior)
35579
- - CTA Strategy (position in layout referencing Zone Inventory, container strategy, frequency)
35580
- - Responsive Behavior (how the layout adapts across sizes \u2014 web: breakpoints and stacking; print: scale and margin strategy)
35581
- - Bans (at least 20 specific layout prohibitions)
35582
-
35583
- ## Critical rules
35584
-
35585
- 1. This is a REFINEMENT. The user already has a role document (shown below). Their prompt refines, evolves, or redirects \u2014 it does NOT start from scratch unless they explicitly say so.
35586
-
35587
- 2. SPECIFICITY IS MANDATORY. Every rule must be actionable at the structural level. Generic adjectives ("clean", "minimal", "modern", "elegant") are BANNED from the output.
35588
-
35589
- 3. THE DOCUMENT MUST BE OPINIONATED, NOT HEDGED. Every sentence must prescribe or ban \u2014 never suggest. Use "Always", "Never", "Must", "Banned", "Required".
35590
-
35591
- 4. STAY IN YOUR LANE. Do NOT include rules about typography, colors, motion/animation, or shadows \u2014 those belong in their own brand files.
35592
-
35593
- 5. THE BANS ARE THE MOST IMPORTANT SECTION. At least 20 bans. The 7 universal AI-layout cliches MUST each appear as an explicit named ban: centered headline over full-width image; three equal-width feature cards in a row; alternating left-right image/text rows with identical padding; uniform zone height and padding; every block wrapped in a card with shadow + radius; CTA with gradient fill; full-width "Why Choose Us" icon grid. Plus 3-5 brand-specific AI tells.
35594
-
35595
- 6. THE ENEMY IS MANDATORY. Name a specific real design and 2-3 exact layout patterns from it. Vague enemies fail.
35596
-
35597
- 7. THE SIGNATURE ANOMALY IS MANDATORY. One specific structural choice. Apply the removal test: if removing this single decision would make the layout indistinguishable from a generic design \u2014 it qualifies. Must appear as a constraint in at least 2 other sections.
35598
-
35599
- 8. USE THE STRUCTURAL CONTEXT. The {{structuralContext}} contains sibling brand files. Do not duplicate their rules \u2014 derive layout implications from them.
35600
-
35601
- ## Current role document
35602
-
35603
- {{currentValues}}
35604
-
35605
- ## Structural context (sibling brand files)
35606
-
35607
- {{structuralContext}}
35608
-
35609
- ## User's refinement prompt
35610
-
35611
- {{userPrompt}}
35612
-
35613
- ## Response format
35614
-
35615
- Return ONLY a JSON object: { "roleDocument": "# Brand Layout Role\\n\\n## Enemy\\n..." }
35616
-
35617
- Output ONLY the JSON object. No markdown fences. No explanation.`;
35618
35574
  function buildQaSystemPrompt(questions, layoutPromptSpec) {
35619
35575
  return `You are a chill creative director doing a quick vibe check on someone's layout taste.
35620
35576
 
@@ -37526,9 +37482,35 @@ var Session = class _Session {
37526
37482
  this.emit(message);
37527
37483
  }
37528
37484
  /**
37529
- * Send initial state to client after connection
37485
+ * Push the first page of the agent directory unsolicited right after
37486
+ * `server_info` so the client can paint attention state before its own
37487
+ * paginated `fetch_agents_request` round-trip lands. The regular fetch
37488
+ * still runs in parallel — it establishes the live-update subscription
37489
+ * and paginates beyond the first page. This push exists purely to shave
37490
+ * one relay round-trip from time-to-first-paint.
37491
+ *
37492
+ * Errors are swallowed: a failed push degrades to "wait for the client
37493
+ * to ask," which is still correct.
37530
37494
  */
37531
37495
  async sendInitialState() {
37496
+ try {
37497
+ const synthetic = {
37498
+ type: "fetch_agents_request",
37499
+ requestId: "internal:initial-snapshot",
37500
+ filter: { includeArchived: true },
37501
+ page: { limit: InitialAgentSnapshotPageLimit }
37502
+ };
37503
+ const { entries } = await this.listFetchAgentsEntries(synthetic);
37504
+ this.emit({
37505
+ type: "initial_agent_snapshot",
37506
+ payload: { entries }
37507
+ });
37508
+ } catch (error) {
37509
+ this.sessionLogger.warn(
37510
+ { err: error },
37511
+ "Failed to push initial agent snapshot \u2014 client will fall back to fetch_agents_request"
37512
+ );
37513
+ }
37532
37514
  }
37533
37515
  /**
37534
37516
  * Normalize a user prompt (with optional image metadata) for AgentManager