@rubytech/create-maxy 1.0.3 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Install Maxy — your personal AI assistant",
5
5
  "bin": {
6
6
  "create-maxy": "./dist/index.js"
@@ -131,7 +131,7 @@ function TimelineStep({ icon, isPending, isError, summary, detail, elapsed, isLa
131
131
  <div className="tl-body">
132
132
  <div className="tl-row" onClick={hasDetail ? onToggle : undefined} style={{ cursor: hasDetail ? 'pointer' : 'default' }}>
133
133
  <span className="tl-summary">{summary}</span>
134
- <span className="tl-step-elapsed">{formatElapsed(elapsed)}</span>
134
+ {elapsed > 0 && <span className="tl-step-elapsed">{formatElapsed(elapsed)}</span>}
135
135
  {hasDetail && (
136
136
  <span className="tl-chevron">
137
137
  {expanded ? <ChevronDown size={10} /> : <ChevronRight size={10} />}
@@ -238,7 +238,7 @@ export function ActivityTimeline({ events, isStreaming, elapsedSeconds }: Activi
238
238
  : <span className="tl-summary tl-thinking-label">{e.content.slice(0, 80)}{e.content.length > 80 ? '…' : ''}</span>
239
239
  }
240
240
  </div>
241
- <span className="tl-step-elapsed">{formatElapsed(stepElapsed(i, nextIdx))}</span>
241
+ {stepElapsed(i, nextIdx) > 0 && <span className="tl-step-elapsed">{formatElapsed(stepElapsed(i, nextIdx))}</span>}
242
242
  <span className="tl-chevron">
243
243
  {isExpanded ? <ChevronDown size={10} /> : <ChevronRight size={10} />}
244
244
  </span>
@@ -1594,28 +1594,40 @@ a:hover {
1594
1594
  align-items: center;
1595
1595
  }
1596
1596
 
1597
- .pin-input-row .chat-input {
1597
+ .pin-input-wrapper {
1598
+ position: relative;
1598
1599
  flex: 1;
1599
1600
  }
1600
1601
 
1601
- .pin-toggle {
1602
+ .pin-input-wrapper .chat-input {
1603
+ width: 100%;
1604
+ padding-left: 38px;
1605
+ }
1606
+
1607
+ .pin-toggle-left {
1608
+ position: absolute;
1609
+ left: 10px;
1610
+ top: 50%;
1611
+ transform: translateY(-50%);
1602
1612
  background: none;
1603
- border: 1px solid var(--border-strong);
1604
- border-radius: 50%;
1605
- width: 40px;
1606
- height: 40px;
1613
+ border: none;
1614
+ padding: 0;
1607
1615
  cursor: pointer;
1608
- font-size: 16px;
1609
1616
  color: var(--text-secondary);
1610
- flex-shrink: 0;
1611
1617
  display: flex;
1612
1618
  align-items: center;
1613
1619
  justify-content: center;
1614
- transition: border-color 0.15s;
1620
+ z-index: 1;
1621
+ transition: color 0.15s;
1615
1622
  }
1616
1623
 
1617
- .pin-toggle:hover {
1618
- border-color: var(--sage);
1624
+ .pin-toggle-left:hover {
1625
+ color: var(--sage);
1626
+ }
1627
+
1628
+ .pin-toggle-hidden {
1629
+ visibility: hidden;
1630
+ pointer-events: none;
1619
1631
  }
1620
1632
 
1621
1633
  .btn-primary {
@@ -395,8 +395,11 @@ async function* invokeAdminAgent(
395
395
  continue;
396
396
  }
397
397
 
398
- if ("result" in msg) {
398
+ if (msg.type === "result") {
399
399
  const usage = (msg as { usage?: { input_tokens?: number; output_tokens?: number } }).usage;
400
+ const log = agentLogStream("claude-agent-result");
401
+ log.write(`result msg: ${JSON.stringify({ usage, keys: Object.keys(msg) })}\n`);
402
+ log.end();
400
403
  if (usage?.input_tokens !== undefined) {
401
404
  yield { type: "usage", input_tokens: usage.input_tokens, output_tokens: usage.output_tokens ?? 0 };
402
405
  }
@@ -332,18 +332,20 @@ export default function AdminPage() {
332
332
  <div className="admin-pin-form">
333
333
  <form onSubmit={handleSetPin}>
334
334
  <div className="pin-input-row">
335
- <input
336
- ref={pinInputRef}
337
- type={showPin ? 'text' : 'password'}
338
- value={pin}
339
- onChange={e => setPin(e.target.value)}
340
- placeholder="Choose a PIN"
341
- className="chat-input"
342
- autoFocus
343
- />
344
- <button type="button" className="pin-toggle" onClick={() => setShowPin(!showPin)} aria-label={showPin ? 'Hide' : 'Show'}>
345
- {showPin ? <EyeOff size={18} /> : <Eye size={18} />}
346
- </button>
335
+ <div className="pin-input-wrapper">
336
+ <button type="button" className={`pin-toggle-left${!pin ? ' pin-toggle-hidden' : ''}`} onClick={() => setShowPin(!showPin)} aria-label={showPin ? 'Hide' : 'Show'}>
337
+ {showPin ? <EyeOff size={16} /> : <Eye size={16} />}
338
+ </button>
339
+ <input
340
+ ref={pinInputRef}
341
+ type={showPin ? 'text' : 'password'}
342
+ value={pin}
343
+ onChange={e => setPin(e.target.value)}
344
+ placeholder="Choose a PIN"
345
+ className="chat-input"
346
+ autoFocus
347
+ />
348
+ </div>
347
349
  </div>
348
350
  <div className="pin-input-row">
349
351
  <input
@@ -476,18 +478,20 @@ export default function AdminPage() {
476
478
  <div className="admin-pin-form">
477
479
  <form onSubmit={handleLogin}>
478
480
  <div className="pin-input-row">
479
- <input
480
- ref={pinInputRef}
481
- type={showPin ? 'text' : 'password'}
482
- value={pin}
483
- onChange={e => setPin(e.target.value)}
484
- placeholder="Enter PIN"
485
- className="chat-input"
486
- autoFocus
487
- />
488
- <button type="button" className="pin-toggle" onClick={() => setShowPin(!showPin)} aria-label={showPin ? 'Hide' : 'Show'}>
489
- {showPin ? <EyeOff size={18} /> : <Eye size={18} />}
490
- </button>
481
+ <div className="pin-input-wrapper">
482
+ <button type="button" className={`pin-toggle-left${!pin ? ' pin-toggle-hidden' : ''}`} onClick={() => setShowPin(!showPin)} aria-label={showPin ? 'Hide' : 'Show'}>
483
+ {showPin ? <EyeOff size={16} /> : <Eye size={16} />}
484
+ </button>
485
+ <input
486
+ ref={pinInputRef}
487
+ type={showPin ? 'text' : 'password'}
488
+ value={pin}
489
+ onChange={e => setPin(e.target.value)}
490
+ placeholder="Enter PIN"
491
+ className="chat-input"
492
+ autoFocus
493
+ />
494
+ </div>
491
495
  <button type="submit" className="chat-send" disabled={!pin}>
492
496
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
493
497
  <line x1="5" y1="12" x2="19" y2="12" />
@@ -4,7 +4,7 @@ You are the head of operations. Not an assistant waiting for instructions — a
4
4
 
5
5
  At the start of every session, check the graph for business context. Your goal is to populate the graph efficiently and comprehensively to maximise value from business intelligence.
6
6
 
7
- Your personalisation is in SOUL.md. Read it and apply it.
7
+ Your personalisation is in `agents/admin/SOUL.md` (relative to your working directory). Read it and apply it.
8
8
 
9
9
  ## Boundaries
10
10
 
@@ -18,7 +18,7 @@ Your personalisation is in SOUL.md. Read it and apply it.
18
18
  - Be proactive. Identify what needs doing and do it. Don't wait to be asked.
19
19
  - On session start, assess the state of the business from the graph and report what needs attention.
20
20
  - On first setup (incomplete business data in graph), immediately begin onboarding: learn the business, understand the stage, gather customer details, build a comprehensive picture so you can drive operations forward - one step at a time.
21
- - Write personalisation to your own SOUL.md. Also write the public agent's personalisation to agents/public/SOUL.md.
21
+ - Write personalisation to `agents/admin/SOUL.md`. Also write the public agent's personalisation to `agents/public/SOUL.md`.
22
22
  - Think strategically. Help with planning, not just tasks.
23
23
  - Surface problems before they become urgent. Recommend actions based on what you know.
24
24
  - Store everything you learn about the business in the graph — not in files.